[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopUnswitch / basictest.ll
blob61647c8f644420a1143a9772aafeeddac38ad2a1
1 ; RUN: opt < %s -loop-unswitch -enable-new-pm=0 -verify-loop-info -verify-memoryssa -S < %s 2>&1 | FileCheck %s
3 define i32 @test(i32* %A, i1 %C) {
4 entry:
5         br label %no_exit
6 no_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
14 then:           ; 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
21 no_exit.backedge:               ; preds = %endif, %then
22         %i.0.0.be = phi i32 [ %inc9, %then ], [ %inc, %endif ]          ; <i32> [#uses=1]
23         br label %no_exit
24 endif:          ; 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
28 return:         ; preds = %endif, %then
29         ret i32 %tmp.13
32 ; This simple test would normally unswitch, but should be inhibited by the presence of
33 ; the noduplicate call.
35 ; CHECK-LABEL: @test2(
36 define i32 @test2(i32* %var) {
37   %mem = alloca i32
38   store i32 2, i32* %mem
39   %c = load i32, i32* %mem
41   br label %loop_begin
43 loop_begin:
45   %var_val = load i32, i32* %var
47   switch i32 %c, label %default [
48       i32 1, label %inc
49       i32 2, label %dec
50   ]
52 inc:
53   call void @incf() noreturn nounwind
54   br label %loop_begin
55 dec:
56 ; CHECK: call void @decf()
57 ; CHECK-NOT: call void @decf()
58   call void @decf() noreturn nounwind noduplicate
59   br label %loop_begin
60 default:
61   br label %loop_exit
62 loop_exit:
63   ret i32 0
64 ; CHECK: }
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.
70 ; CHECK-LABEL: @test3(
71 define i32 @test3(i32* %var) {
72   %mem = alloca i32
73   store i32 2, i32* %mem
74   %c = load i32, i32* %mem
76   br label %loop_begin
78 loop_begin:
80   %var_val = load i32, i32* %var
82 ; CHECK: call void @conv()
83 ; CHECK-NOT: call void @conv()
84   call void @conv() convergent
86   switch i32 %c, label %default [
87       i32 1, label %inc
88       i32 2, label %dec
89   ]
91 inc:
92   call void @incf() noreturn nounwind
93   br label %loop_begin
94 dec:
95   call void @decf() noreturn nounwind
96   br label %loop_begin
97 default:
98   br label %loop_exit
99 loop_exit:
100   ret i32 0
101 ; CHECK: }
104 ; Make sure we unswitch %a == 0 out of the loop.
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
114 define void @and_i2_as_switch_input(i2 %a) {
115 entry:
116   br label %for.body
118 for.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   ]
127 sw.bb:
128   br label %sw.epilog
130 sw.bb1:
131   br label %sw.epilog
133 sw.default:
134   br label %sw.epilog
136 sw.epilog:
137   br label %for.inc
139 for.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
144 for.end:
145   ret void
148 ; Make sure we unswitch %a == !0 out of the loop.
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
158 define void @or_i2_as_switch_input(i2 %a) {
159 entry:
160   br label %for.body
162 for.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   ]
171 sw.bb:
172   br label %sw.epilog
174 sw.bb1:
175   br label %sw.epilog
177 sw.default:
178   br label %sw.epilog
180 sw.epilog:
181   br label %for.inc
183 for.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
188 for.end:
189   ret void
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.
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
204 define void @or_i2_as_switch_input_unswitch_default(i2 %a) {
205 entry:
206   br label %for.body
208 for.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   ]
217 sw.bb:
218   br label %sw.epilog
220 sw.bb1:
221   br label %sw.epilog
223 sw.default:
224   br label %sw.epilog
226 sw.epilog:
227   br label %for.inc
229 for.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
234 for.end:
235   ret void
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.
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
246 define void @and_or_i2_as_switch_input(i2 %a) {
247 entry:
248   br label %for.body
250 for.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   ]
259 sw.bb:
260   br label %sw.epilog
262 sw.bb1:
263   br label %sw.epilog
265 sw.default:
266   br label %sw.epilog
268 sw.epilog:
269   br label %for.inc
271 for.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
276 for.end:
277   ret void
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.
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
288 define void @and_or_i1_as_branch_input(i1 %a) {
289 entry:
290   br label %for.body
292 for.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
298 sw.bb:
299   br label %sw.epilog
301 sw.bb1:
302   br label %sw.epilog
304 sw.epilog:
305   br label %for.inc
307 for.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
312 for.end:
313   ret void
316 declare void @incf() noreturn
317 declare void @decf() noreturn
318 declare void @conv() convergent