1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
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(
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:%.*]]
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]]
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
32 ; Can't hoist over a side effect
33 define void @test2(i1 %cond, i32* %ptr) {
34 ; CHECK-LABEL: @test2(
36 ; CHECK-NEXT: br label [[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]]
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
58 ; Can't hoist over a side effect
59 define void @test2b(i1 %cond, i32* %ptr) {
60 ; CHECK-LABEL: @test2b(
62 ; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 1
63 ; CHECK-NEXT: br label [[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]]
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
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(
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:%.*]]
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]]
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
113 ; Hoist guard. Cannot hoist load because of aliasing.
114 define void @test3(i1 %cond, i32* %ptr) {
115 ; CHECK-LABEL: @test3(
117 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
118 ; CHECK-NEXT: br label [[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]]
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
139 ; Hoist load and guard.
140 define void @test4(i1 %c, i32* %p) {
141 ; CHECK-LABEL: @test4(
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:%.*]]
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:%.*]]
152 ; CHECK-NEXT: br label [[BACKEDGE]]
154 ; CHECK-NEXT: br label [[BACKEDGE]]
156 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
157 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
159 ; CHECK-NEXT: ret void
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
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
187 ; Do not hoist across a conditionally executed side effect.
188 define void @test4a(i1 %c, i32* %p, i32* %q) {
189 ; CHECK-LABEL: @test4a(
191 ; CHECK-NEXT: br label [[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:%.*]]
197 ; CHECK-NEXT: store i32 123, i32* [[Q:%.*]]
198 ; CHECK-NEXT: br label [[BACKEDGE]]
200 ; CHECK-NEXT: br label [[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:%.*]]
208 ; CHECK-NEXT: ret void
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
220 store i32 123, i32* %q
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
237 ; Do not hoist a conditionally executed guard.
238 define void @test4b(i1 %c, i32* %p, i32* %q) {
239 ; CHECK-LABEL: @test4b(
241 ; CHECK-NEXT: br label [[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:%.*]]
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]]
252 ; CHECK-NEXT: br label [[BACKEDGE]]
254 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
255 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
257 ; CHECK-NEXT: ret void
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
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"() ]
278 %loop_cond = icmp slt i32 %iv.next, 1000
279 br i1 %loop_cond, label %loop, label %exit
285 ; Hoist store, load and guard.
286 define void @test4c(i1 %c, i32* %p, i8* noalias %s) {
287 ; CHECK-LABEL: @test4c(
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:%.*]]
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:%.*]]
299 ; CHECK-NEXT: br label [[BACKEDGE]]
301 ; CHECK-NEXT: br label [[BACKEDGE]]
303 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
304 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
306 ; CHECK-NEXT: ret void
313 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
314 %iv.next = add i32 %iv, 1
316 br i1 %c, label %if.true, label %if.false
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
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(
339 ; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[P:%.*]]
340 ; CHECK-NEXT: [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
341 ; CHECK-NEXT: br label [[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:%.*]]
347 ; CHECK-NEXT: store i8 0, i8* [[S:%.*]]
348 ; CHECK-NEXT: br label [[BACKEDGE]]
350 ; CHECK-NEXT: br label [[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:%.*]]
356 ; CHECK-NEXT: ret void
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
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
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(
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:%.*]]
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:%.*]]
399 ; CHECK-NEXT: br label [[BACKEDGE]]
401 ; CHECK-NEXT: br label [[BACKEDGE]]
403 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
404 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
406 ; CHECK-NEXT: ret void
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
424 %a = load i32, i32* %p
425 %invariant_cond = icmp ne i32 %a, 100
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
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(
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:%.*]]
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:%.*]]
449 ; CHECK-NEXT: br label [[BACKEDGE]]
451 ; CHECK-NEXT: br label [[BACKEDGE]]
453 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
454 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
456 ; CHECK-NEXT: ret void
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
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"() ]
478 %loop_cond = icmp slt i32 %iv.next, 1000
479 br i1 %loop_cond, label %loop, label %exit
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(
489 ; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[P:%.*]]
490 ; CHECK-NEXT: [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
491 ; CHECK-NEXT: br label [[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]]
500 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
501 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
503 ; CHECK-NEXT: ret void
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"() ]
520 %loop_cond = icmp slt i32 %iv.next, 1000
521 br i1 %loop_cond, label %loop, label %exit
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(
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:%.*]]
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]]
542 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
543 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
545 ; CHECK-NEXT: ret void
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"() ]
562 %loop_cond = icmp slt i32 %iv.next, 1000
563 br i1 %loop_cond, label %loop, label %exit
569 declare void @llvm.experimental.guard(i1, ...)