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