[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / LICM / guards.ll
blob2343e0917c568c5ce708999526d37743f3c29c52
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; REQUIRES: asserts
3 ; RUN: opt -licm -basicaa -enable-mssa-loop-dependency=false -ipt-expensive-asserts=true < %s -S | FileCheck %s
4 ; RUN: opt -licm -basicaa -enable-mssa-loop-dependency=true -ipt-expensive-asserts=true < %s -S | FileCheck %s --check-prefixes=CHECK,MSSA
5 ; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -ipt-expensive-asserts=true < %s -S | FileCheck %s
6 ; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -ipt-expensive-asserts=true < %s -S | FileCheck %s --check-prefixes=CHECK,MSSA
8 ; Hoist guard and load.
9 define void @test1(i1 %cond, i32* %ptr) {
10 ; CHECK-LABEL: @test1(
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
13 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR:%.*]]
14 ; CHECK-NEXT:    br label [[LOOP:%.*]]
15 ; CHECK:       loop:
16 ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
17 ; CHECK-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
18 ; CHECK-NEXT:    br label [[LOOP]]
21 entry:
22   br label %loop
24 loop:
25   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
26   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
27   %val = load i32, i32* %ptr
28   %x.inc = add i32 %x, %val
29   br label %loop
32 ; Can't hoist over a side effect
33 define void @test2(i1 %cond, i32* %ptr) {
34 ; CHECK-LABEL: @test2(
35 ; CHECK-NEXT:  entry:
36 ; CHECK-NEXT:    br label [[LOOP:%.*]]
37 ; CHECK:       loop:
38 ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
39 ; CHECK-NEXT:    store i32 0, i32* [[PTR:%.*]]
40 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
41 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR]]
42 ; CHECK-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
43 ; CHECK-NEXT:    br label [[LOOP]]
46 entry:
47   br label %loop
49 loop:
50   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
51   store i32 0, i32* %ptr
52   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
53   %val = load i32, i32* %ptr
54   %x.inc = add i32 %x, %val
55   br label %loop
58 ; Can't hoist over a side effect
59 define void @test2b(i1 %cond, i32* %ptr) {
60 ; CHECK-LABEL: @test2b(
61 ; CHECK-NEXT:  entry:
62 ; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 1
63 ; CHECK-NEXT:    br label [[LOOP:%.*]]
64 ; CHECK:       loop:
65 ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
66 ; CHECK-NEXT:    store i32 [[X]], i32* [[P2]]
67 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
68 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR]]
69 ; CHECK-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
70 ; CHECK-NEXT:    br label [[LOOP]]
73 entry:
74   br label %loop
76 loop:
77   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
78   %p2 = getelementptr i32, i32* %ptr, i32 1
79   store i32 %x, i32* %p2
80   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
81   %val = load i32, i32* %ptr
82   %x.inc = add i32 %x, %val
83   br label %loop
86 ; But can hoist if the side effect is hoisted with MSSA
87 define void @test2b_prime(i1 %cond, i32* noalias %ptr) {
88 ; MSSA-LABEL: @test2b_prime(
89 ; MSSA-NEXT:  entry:
90 ; MSSA-NEXT:    [[P2:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 1
91 ; MSSA-NEXT:    store i32 0, i32* [[P2]]
92 ; MSSA-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
93 ; MSSA-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR]]
94 ; MSSA-NEXT:    br label [[LOOP:%.*]]
95 ; MSSA:       loop:
96 ; MSSA-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
97 ; MSSA-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
98 ; MSSA-NEXT:    br label [[LOOP]]
100 entry:
101   br label %loop
103 loop:
104   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
105   %p2 = getelementptr i32, i32* %ptr, i32 1
106   store i32 0, i32* %p2
107   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
108   %val = load i32, i32* %ptr
109   %x.inc = add i32 %x, %val
110   br label %loop
113 ; Hoist guard. Cannot hoist load because of aliasing.
114 define void @test3(i1 %cond, i32* %ptr) {
115 ; CHECK-LABEL: @test3(
116 ; CHECK-NEXT:  entry:
117 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
118 ; CHECK-NEXT:    br label [[LOOP:%.*]]
119 ; CHECK:       loop:
120 ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
121 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR:%.*]]
122 ; CHECK-NEXT:    store i32 0, i32* [[PTR]]
123 ; CHECK-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
124 ; CHECK-NEXT:    br label [[LOOP]]
127 entry:
128   br label %loop
130 loop:
131   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
132   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
133   %val = load i32, i32* %ptr
134   store i32 0, i32* %ptr
135   %x.inc = add i32 %x, %val
136   br label %loop
139 ; Hoist load and guard.
140 define void @test4(i1 %c, i32* %p) {
141 ; CHECK-LABEL: @test4(
142 ; CHECK-NEXT:  entry:
143 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
144 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
145 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
146 ; CHECK-NEXT:    br label [[LOOP:%.*]]
147 ; CHECK:       loop:
148 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
149 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
150 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
151 ; CHECK:       if.true:
152 ; CHECK-NEXT:    br label [[BACKEDGE]]
153 ; CHECK:       if.false:
154 ; CHECK-NEXT:    br label [[BACKEDGE]]
155 ; CHECK:       backedge:
156 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
157 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
158 ; CHECK:       exit:
159 ; CHECK-NEXT:    ret void
162 entry:
163   br label %loop
165 loop:
166   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
167   %iv.next = add i32 %iv, 1
168   br i1 %c, label %if.true, label %if.false
170 if.true:
171   br label %backedge
173 if.false:
174   br label %backedge
176 backedge:
177   %a = load i32, i32* %p
178   %invariant_cond = icmp ne i32 %a, 100
179   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
180   %loop_cond = icmp slt i32 %iv.next, 1000
181   br i1 %loop_cond, label %loop, label %exit
183 exit:
184   ret void
187 ; Do not hoist across a conditionally executed side effect.
188 define void @test4a(i1 %c, i32* %p, i32* %q) {
189 ; CHECK-LABEL: @test4a(
190 ; CHECK-NEXT:  entry:
191 ; CHECK-NEXT:    br label [[LOOP:%.*]]
192 ; CHECK:       loop:
193 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
194 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
195 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
196 ; CHECK:       if.true:
197 ; CHECK-NEXT:    store i32 123, i32* [[Q:%.*]]
198 ; CHECK-NEXT:    br label [[BACKEDGE]]
199 ; CHECK:       if.false:
200 ; CHECK-NEXT:    br label [[BACKEDGE]]
201 ; CHECK:       backedge:
202 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
203 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
204 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
205 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
206 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
207 ; CHECK:       exit:
208 ; CHECK-NEXT:    ret void
211 entry:
212   br label %loop
214 loop:
215   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
216   %iv.next = add i32 %iv, 1
217   br i1 %c, label %if.true, label %if.false
219 if.true:
220   store i32 123, i32* %q
221   br label %backedge
223 if.false:
224   br label %backedge
226 backedge:
227   %a = load i32, i32* %p
228   %invariant_cond = icmp ne i32 %a, 100
229   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
230   %loop_cond = icmp slt i32 %iv.next, 1000
231   br i1 %loop_cond, label %loop, label %exit
233 exit:
234   ret void
237 ; Do not hoist a conditionally executed guard.
238 define void @test4b(i1 %c, i32* %p, i32* %q) {
239 ; CHECK-LABEL: @test4b(
240 ; CHECK-NEXT:  entry:
241 ; CHECK-NEXT:    br label [[LOOP:%.*]]
242 ; CHECK:       loop:
243 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
244 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
245 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
246 ; CHECK:       if.true:
247 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
248 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
249 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
250 ; CHECK-NEXT:    br label [[BACKEDGE]]
251 ; CHECK:       if.false:
252 ; CHECK-NEXT:    br label [[BACKEDGE]]
253 ; CHECK:       backedge:
254 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
255 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
256 ; CHECK:       exit:
257 ; CHECK-NEXT:    ret void
260 entry:
261   br label %loop
263 loop:
264   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
265   %iv.next = add i32 %iv, 1
266   br i1 %c, label %if.true, label %if.false
268 if.true:
269   %a = load i32, i32* %p
270   %invariant_cond = icmp ne i32 %a, 100
271   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
272   br label %backedge
274 if.false:
275   br label %backedge
277 backedge:
278   %loop_cond = icmp slt i32 %iv.next, 1000
279   br i1 %loop_cond, label %loop, label %exit
281 exit:
282   ret void
285 ; Hoist store, load and guard.
286 define void @test4c(i1 %c, i32* %p, i8* noalias %s) {
287 ; CHECK-LABEL: @test4c(
288 ; CHECK-NEXT:  entry:
289 ; CHECK-NEXT:    store i8 0, i8* [[S:%.*]]
290 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
291 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
292 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
293 ; CHECK-NEXT:    br label [[LOOP:%.*]]
294 ; CHECK:       loop:
295 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
296 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
297 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
298 ; CHECK:       if.true:
299 ; CHECK-NEXT:    br label [[BACKEDGE]]
300 ; CHECK:       if.false:
301 ; CHECK-NEXT:    br label [[BACKEDGE]]
302 ; CHECK:       backedge:
303 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
304 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
305 ; CHECK:       exit:
306 ; CHECK-NEXT:    ret void
309 entry:
310   br label %loop
312 loop:
313   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
314   %iv.next = add i32 %iv, 1
315   store i8 0, i8* %s
316   br i1 %c, label %if.true, label %if.false
318 if.true:
319   br label %backedge
321 if.false:
322   br label %backedge
324 backedge:
325   %a = load i32, i32* %p
326   %invariant_cond = icmp ne i32 %a, 100
327   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
328   %loop_cond = icmp slt i32 %iv.next, 1000
329   br i1 %loop_cond, label %loop, label %exit
331 exit:
332   ret void
335 ; Check that we don't hoist across a store in a conditionally executed block.
336 define void @test4d(i1 %c, i32* %p, i8* noalias %s) {
337 ; CHECK-LABEL: @test4d(
338 ; CHECK-NEXT:  entry:
339 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
340 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
341 ; CHECK-NEXT:    br label [[LOOP:%.*]]
342 ; CHECK:       loop:
343 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
344 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
345 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
346 ; CHECK:       if.true:
347 ; CHECK-NEXT:    store i8 0, i8* [[S:%.*]]
348 ; CHECK-NEXT:    br label [[BACKEDGE]]
349 ; CHECK:       if.false:
350 ; CHECK-NEXT:    br label [[BACKEDGE]]
351 ; CHECK:       backedge:
352 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
353 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
354 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
355 ; CHECK:       exit:
356 ; CHECK-NEXT:    ret void
359 entry:
360   br label %loop
362 loop:
363   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
364   %iv.next = add i32 %iv, 1
365   br i1 %c, label %if.true, label %if.false
367 if.true:
368   store i8 0, i8* %s
369   br label %backedge
371 if.false:
372   br label %backedge
374 backedge:
375   %a = load i32, i32* %p
376   %invariant_cond = icmp ne i32 %a, 100
377   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
378   %loop_cond = icmp slt i32 %iv.next, 1000
379   br i1 %loop_cond, label %loop, label %exit
381 exit:
382   ret void
385 ; Check that we don't hoist across a store before the guard in the backedge.
386 define void @test4e(i1 %c, i32* %p, i8* noalias %s) {
387 ; CHECK-LABEL: @test4e(
388 ; CHECK-NEXT:  entry:
389 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
390 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
391 ; CHECK-NEXT:    store i8 0, i8* [[S:%.*]]
392 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
393 ; CHECK-NEXT:    br label [[LOOP:%.*]]
394 ; CHECK:       loop:
395 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
396 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
397 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
398 ; CHECK:       if.true:
399 ; CHECK-NEXT:    br label [[BACKEDGE]]
400 ; CHECK:       if.false:
401 ; CHECK-NEXT:    br label [[BACKEDGE]]
402 ; CHECK:       backedge:
403 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
404 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
405 ; CHECK:       exit:
406 ; CHECK-NEXT:    ret void
409 entry:
410   br label %loop
412 loop:
413   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
414   %iv.next = add i32 %iv, 1
415   br i1 %c, label %if.true, label %if.false
417 if.true:
418   br label %backedge
420 if.false:
421   br label %backedge
423 backedge:
424   %a = load i32, i32* %p
425   %invariant_cond = icmp ne i32 %a, 100
426   store i8 0, i8* %s
427   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
428   %loop_cond = icmp slt i32 %iv.next, 1000
429   br i1 %loop_cond, label %loop, label %exit
431 exit:
432   ret void
435 ; Check that we can hoist the guard in spite of store which happens after.
436 define void @test4f(i1 %c, i32* %p, i8* noalias %s) {
437 ; CHECK-LABEL: @test4f(
438 ; CHECK-NEXT:  entry:
439 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
440 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
441 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
442 ; CHECK-NEXT:    store i8 0, i8* [[S:%.*]]
443 ; CHECK-NEXT:    br label [[LOOP:%.*]]
444 ; CHECK:       loop:
445 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
446 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
447 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
448 ; CHECK:       if.true:
449 ; CHECK-NEXT:    br label [[BACKEDGE]]
450 ; CHECK:       if.false:
451 ; CHECK-NEXT:    br label [[BACKEDGE]]
452 ; CHECK:       backedge:
453 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
454 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
455 ; CHECK:       exit:
456 ; CHECK-NEXT:    ret void
459 entry:
460   br label %loop
462 loop:
463   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
464   %iv.next = add i32 %iv, 1
465   br i1 %c, label %if.true, label %if.false
467 if.true:
468   br label %backedge
470 if.false:
471   br label %backedge
473 backedge:
474   %a = load i32, i32* %p
475   %invariant_cond = icmp ne i32 %a, 100
476   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
477   store i8 0, i8* %s
478   %loop_cond = icmp slt i32 %iv.next, 1000
479   br i1 %loop_cond, label %loop, label %exit
481 exit:
482   ret void
485 ; Do not hoist an invariant guard across a variant guard.
486 define void @test5(i1 %c, i32* %p, i32* %q) {
487 ; CHECK-LABEL: @test5(
488 ; CHECK-NEXT:  entry:
489 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
490 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
491 ; CHECK-NEXT:    br label [[LOOP:%.*]]
492 ; CHECK:       loop:
493 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
494 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
495 ; CHECK-NEXT:    [[VARIANT_COND:%.*]] = icmp ne i32 [[A]], [[IV]]
496 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[VARIANT_COND]]) [ "deopt"() ]
497 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
498 ; CHECK-NEXT:    br label [[BACKEDGE]]
499 ; CHECK:       backedge:
500 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
501 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
502 ; CHECK:       exit:
503 ; CHECK-NEXT:    ret void
506 entry:
507   br label %loop
509 loop:
510   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
511   %iv.next = add i32 %iv, 1
512   %a = load i32, i32* %p
513   %invariant_cond = icmp ne i32 %a, 100
514   %variant_cond = icmp ne i32 %a, %iv
515   call void (i1, ...) @llvm.experimental.guard(i1 %variant_cond) [ "deopt"() ]
516   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
517   br label %backedge
519 backedge:
520   %loop_cond = icmp slt i32 %iv.next, 1000
521   br i1 %loop_cond, label %loop, label %exit
523 exit:
524   ret void
527 ; Hoist an invariant guard, leave the following variant guard in the loop.
528 define void @test5a(i1 %c, i32* %p, i32* %q) {
529 ; CHECK-LABEL: @test5a(
530 ; CHECK-NEXT:  entry:
531 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
532 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
533 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
534 ; CHECK-NEXT:    br label [[LOOP:%.*]]
535 ; CHECK:       loop:
536 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
537 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
538 ; CHECK-NEXT:    [[VARIANT_COND:%.*]] = icmp ne i32 [[A]], [[IV]]
539 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[VARIANT_COND]]) [ "deopt"() ]
540 ; CHECK-NEXT:    br label [[BACKEDGE]]
541 ; CHECK:       backedge:
542 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
543 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
544 ; CHECK:       exit:
545 ; CHECK-NEXT:    ret void
548 entry:
549   br label %loop
551 loop:
552   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
553   %iv.next = add i32 %iv, 1
554   %a = load i32, i32* %p
555   %invariant_cond = icmp ne i32 %a, 100
556   %variant_cond = icmp ne i32 %a, %iv
557   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
558   call void (i1, ...) @llvm.experimental.guard(i1 %variant_cond) [ "deopt"() ]
559   br label %backedge
561 backedge:
562   %loop_cond = icmp slt i32 %iv.next, 1000
563   br i1 %loop_cond, label %loop, label %exit
565 exit:
566   ret void
569 declare void @llvm.experimental.guard(i1, ...)