• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -loop-unswitch -enable-new-pm=0 -verify-loop-info -S < %s 2>&1 | FileCheck %s
2; RUN: opt < %s -loop-unswitch -enable-new-pm=0 -verify-loop-info -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s 2>&1 | FileCheck %s
3
4define i32 @test(i32* %A, i1 %C) {
5entry:
6	br label %no_exit
7no_exit:		; preds = %no_exit.backedge, %entry
8	%i.0.0 = phi i32 [ 0, %entry ], [ %i.0.0.be, %no_exit.backedge ]		; <i32> [#uses=3]
9	%gep.upgrd.1 = zext i32 %i.0.0 to i64		; <i64> [#uses=1]
10	%tmp.7 = getelementptr i32, i32* %A, i64 %gep.upgrd.1		; <i32*> [#uses=4]
11	%tmp.13 = load i32, i32* %tmp.7		; <i32> [#uses=2]
12	%tmp.14 = add i32 %tmp.13, 1		; <i32> [#uses=1]
13	store i32 %tmp.14, i32* %tmp.7
14	br i1 %C, label %then, label %endif
15then:		; preds = %no_exit
16	%tmp.29 = load i32, i32* %tmp.7		; <i32> [#uses=1]
17	%tmp.30 = add i32 %tmp.29, 2		; <i32> [#uses=1]
18	store i32 %tmp.30, i32* %tmp.7
19	%inc9 = add i32 %i.0.0, 1		; <i32> [#uses=2]
20	%tmp.112 = icmp ult i32 %inc9, 100000		; <i1> [#uses=1]
21	br i1 %tmp.112, label %no_exit.backedge, label %return
22no_exit.backedge:		; preds = %endif, %then
23	%i.0.0.be = phi i32 [ %inc9, %then ], [ %inc, %endif ]		; <i32> [#uses=1]
24	br label %no_exit
25endif:		; preds = %no_exit
26	%inc = add i32 %i.0.0, 1		; <i32> [#uses=2]
27	%tmp.1 = icmp ult i32 %inc, 100000		; <i1> [#uses=1]
28	br i1 %tmp.1, label %no_exit.backedge, label %return
29return:		; preds = %endif, %then
30	ret i32 %tmp.13
31}
32
33; This simple test would normally unswitch, but should be inhibited by the presence of
34; the noduplicate call.
35
36; CHECK-LABEL: @test2(
37define i32 @test2(i32* %var) {
38  %mem = alloca i32
39  store i32 2, i32* %mem
40  %c = load i32, i32* %mem
41
42  br label %loop_begin
43
44loop_begin:
45
46  %var_val = load i32, i32* %var
47
48  switch i32 %c, label %default [
49      i32 1, label %inc
50      i32 2, label %dec
51  ]
52
53inc:
54  call void @incf() noreturn nounwind
55  br label %loop_begin
56dec:
57; CHECK: call void @decf()
58; CHECK-NOT: call void @decf()
59  call void @decf() noreturn nounwind noduplicate
60  br label %loop_begin
61default:
62  br label %loop_exit
63loop_exit:
64  ret i32 0
65; CHECK: }
66}
67
68; This simple test would normally unswitch, but should be inhibited by the presence of
69; the convergent call that is not control-dependent on the unswitch condition.
70
71; CHECK-LABEL: @test3(
72define i32 @test3(i32* %var) {
73  %mem = alloca i32
74  store i32 2, i32* %mem
75  %c = load i32, i32* %mem
76
77  br label %loop_begin
78
79loop_begin:
80
81  %var_val = load i32, i32* %var
82
83; CHECK: call void @conv()
84; CHECK-NOT: call void @conv()
85  call void @conv() convergent
86
87  switch i32 %c, label %default [
88      i32 1, label %inc
89      i32 2, label %dec
90  ]
91
92inc:
93  call void @incf() noreturn nounwind
94  br label %loop_begin
95dec:
96  call void @decf() noreturn nounwind
97  br label %loop_begin
98default:
99  br label %loop_exit
100loop_exit:
101  ret i32 0
102; CHECK: }
103}
104
105; Make sure we unswitch %a == 0 out of the loop.
106;
107; CHECK: define void @and_i2_as_switch_input(i2
108; CHECK: entry:
109; This is an indication that the loop has been unswitched.
110; CHECK: icmp eq i2 %a, 0
111; CHECK: br
112; There should be no more unswitching after the 1st unswitch.
113; CHECK-NOT: icmp eq
114; CHECK: ret
115define void @and_i2_as_switch_input(i2 %a) {
116entry:
117  br label %for.body
118
119for.body:
120  %i = phi i2 [ 0, %entry ], [ %inc, %for.inc ]
121  %and = and i2 %a, %i
122  %and1 = and i2 %and, %i
123  switch i2 %and1, label %sw.default [
124    i2 0, label %sw.bb
125    i2 1, label %sw.bb1
126  ]
127
128sw.bb:
129  br label %sw.epilog
130
131sw.bb1:
132  br label %sw.epilog
133
134sw.default:
135  br label %sw.epilog
136
137sw.epilog:
138  br label %for.inc
139
140for.inc:
141  %inc = add nsw i2 %i, 1
142  %cmp = icmp slt i2 %inc, 3
143  br i1 %cmp, label %for.body, label %for.end
144
145for.end:
146  ret void
147}
148
149; Make sure we unswitch %a == !0 out of the loop.
150;
151; CHECK: define void @or_i2_as_switch_input(i2
152; CHECK: entry:
153; This is an indication that the loop has been unswitched.
154; CHECK: icmp eq i2 %a, -1
155; CHECK: br
156; There should be no more unswitching after the 1st unswitch.
157; CHECK-NOT: icmp eq
158; CHECK: ret
159define void @or_i2_as_switch_input(i2 %a) {
160entry:
161  br label %for.body
162
163for.body:
164  %i = phi i2 [ 0, %entry ], [ %inc, %for.inc ]
165  %or = or i2 %a, %i
166  %or1 = or i2 %or, %i
167  switch i2 %or1, label %sw.default [
168    i2 2, label %sw.bb
169    i2 3, label %sw.bb1
170  ]
171
172sw.bb:
173  br label %sw.epilog
174
175sw.bb1:
176  br label %sw.epilog
177
178sw.default:
179  br label %sw.epilog
180
181sw.epilog:
182  br label %for.inc
183
184for.inc:
185  %inc = add nsw i2 %i, 1
186  %cmp = icmp slt i2 %inc, 3
187  br i1 %cmp, label %for.body, label %for.end
188
189for.end:
190  ret void
191}
192
193; Make sure we unswitch %a == !0 out of the loop. Even we do not
194; have it as a case value. Unswitching it out allows us to simplify
195; the or operator chain.
196;
197; CHECK: define void @or_i2_as_switch_input_unswitch_default(i2
198; CHECK: entry:
199; This is an indication that the loop has been unswitched.
200; CHECK: icmp eq i2 %a, -1
201; CHECK: br
202; There should be no more unswitching after the 1st unswitch.
203; CHECK-NOT: icmp eq
204; CHECK: ret
205define void @or_i2_as_switch_input_unswitch_default(i2 %a) {
206entry:
207  br label %for.body
208
209for.body:
210  %i = phi i2 [ 0, %entry ], [ %inc, %for.inc ]
211  %or = or i2 %a, %i
212  %or1 = or i2 %or, %i
213  switch i2 %or1, label %sw.default [
214    i2 1, label %sw.bb
215    i2 2, label %sw.bb1
216  ]
217
218sw.bb:
219  br label %sw.epilog
220
221sw.bb1:
222  br label %sw.epilog
223
224sw.default:
225  br label %sw.epilog
226
227sw.epilog:
228  br label %for.inc
229
230for.inc:
231  %inc = add nsw i2 %i, 1
232  %cmp = icmp slt i2 %inc, 3
233  br i1 %cmp, label %for.body, label %for.end
234
235for.end:
236  ret void
237}
238
239; Make sure we don't unswitch, as we can not find an input value %a
240; that will effectively unswitch 0 or 3 out of the loop.
241;
242; CHECK: define void @and_or_i2_as_switch_input(i2
243; CHECK: entry:
244; This is an indication that the loop has NOT been unswitched.
245; CHECK-NOT: icmp
246; CHECK: br
247define void @and_or_i2_as_switch_input(i2 %a) {
248entry:
249  br label %for.body
250
251for.body:
252  %i = phi i2 [ 0, %entry ], [ %inc, %for.inc ]
253  %and = and i2 %a, %i
254  %or = or i2 %and, %i
255  switch i2 %or, label %sw.default [
256    i2 0, label %sw.bb
257    i2 3, label %sw.bb1
258  ]
259
260sw.bb:
261  br label %sw.epilog
262
263sw.bb1:
264  br label %sw.epilog
265
266sw.default:
267  br label %sw.epilog
268
269sw.epilog:
270  br label %for.inc
271
272for.inc:
273  %inc = add nsw i2 %i, 1
274  %cmp = icmp slt i2 %inc, 3
275  br i1 %cmp, label %for.body, label %for.end
276
277for.end:
278  ret void
279}
280
281; Make sure we don't unswitch, as we can not find an input value %a
282; that will effectively unswitch true/false out of the loop.
283;
284; CHECK: define void @and_or_i1_as_branch_input(i1
285; CHECK: entry:
286; This is an indication that the loop has NOT been unswitched.
287; CHECK-NOT: icmp
288; CHECK: br
289define void @and_or_i1_as_branch_input(i1 %a) {
290entry:
291  br label %for.body
292
293for.body:
294  %i = phi i1 [ 0, %entry ], [ %inc, %for.inc ]
295  %and = and i1 %a, %i
296  %or = or i1 %and, %i
297  br i1 %or, label %sw.bb, label %sw.bb1
298
299sw.bb:
300  br label %sw.epilog
301
302sw.bb1:
303  br label %sw.epilog
304
305sw.epilog:
306  br label %for.inc
307
308for.inc:
309  %inc = add nsw i1 %i, 1
310  %cmp = icmp slt i1 %inc, 1
311  br i1 %cmp, label %for.body, label %for.end
312
313for.end:
314  ret void
315}
316
317declare void @incf() noreturn
318declare void @decf() noreturn
319declare void @conv() convergent
320