[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / LICM / guards.ll
blob6c25eb167f92ee86ae4c552cd5a4d5e1209ec98f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; REQUIRES: asserts
3 ; RUN: opt -licm -basicaa -ipt-expensive-asserts=true < %s -S | FileCheck %s
4 ; 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 ; Hoist guard and load.
7 define void @test1(i1 %cond, i32* %ptr) {
8 ; CHECK-LABEL: @test1(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
11 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR:%.*]]
12 ; CHECK-NEXT:    br label [[LOOP:%.*]]
13 ; CHECK:       loop:
14 ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
15 ; CHECK-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
16 ; CHECK-NEXT:    br label [[LOOP]]
19 entry:
20   br label %loop
22 loop:
23   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
24   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
25   %val = load i32, i32* %ptr
26   %x.inc = add i32 %x, %val
27   br label %loop
30 ; Can't hoist over a side effect
31 define void @test2(i1 %cond, i32* %ptr) {
32 ; CHECK-LABEL: @test2(
33 ; CHECK-NEXT:  entry:
34 ; CHECK-NEXT:    br label [[LOOP:%.*]]
35 ; CHECK:       loop:
36 ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
37 ; CHECK-NEXT:    store i32 0, i32* [[PTR:%.*]]
38 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
39 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR]]
40 ; CHECK-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
41 ; CHECK-NEXT:    br label [[LOOP]]
44 entry:
45   br label %loop
47 loop:
48   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
49   store i32 0, i32* %ptr
50   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
51   %val = load i32, i32* %ptr
52   %x.inc = add i32 %x, %val
53   br label %loop
56 ; Can't hoist over a side effect
57 define void @test2b(i1 %cond, i32* %ptr) {
58 ; CHECK-LABEL: @test2b(
59 ; CHECK-NEXT:  entry:
60 ; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 1
61 ; CHECK-NEXT:    br label [[LOOP:%.*]]
62 ; CHECK:       loop:
63 ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
64 ; CHECK-NEXT:    store i32 0, i32* [[P2]]
65 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
66 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR]]
67 ; CHECK-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
68 ; CHECK-NEXT:    br label [[LOOP]]
71 entry:
72   br label %loop
74 loop:
75   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
76   %p2 = getelementptr i32, i32* %ptr, i32 1
77   store i32 0, i32* %p2
78   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
79   %val = load i32, i32* %ptr
80   %x.inc = add i32 %x, %val
81   br label %loop
84 ; Hoist guard. Cannot hoist load because of aliasing.
85 define void @test3(i1 %cond, i32* %ptr) {
86 ; CHECK-LABEL: @test3(
87 ; CHECK-NEXT:  entry:
88 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"(i32 0) ]
89 ; CHECK-NEXT:    br label [[LOOP:%.*]]
90 ; CHECK:       loop:
91 ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_INC:%.*]], [[LOOP]] ]
92 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR:%.*]]
93 ; CHECK-NEXT:    store i32 0, i32* [[PTR]]
94 ; CHECK-NEXT:    [[X_INC]] = add i32 [[X]], [[VAL]]
95 ; CHECK-NEXT:    br label [[LOOP]]
98 entry:
99   br label %loop
101 loop:
102   %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
103   call void (i1, ...) @llvm.experimental.guard(i1 %cond) ["deopt" (i32 0)]
104   %val = load i32, i32* %ptr
105   store i32 0, i32* %ptr
106   %x.inc = add i32 %x, %val
107   br label %loop
110 ; Hoist load and guard.
111 define void @test4(i1 %c, i32* %p) {
112 ; CHECK-LABEL: @test4(
113 ; CHECK-NEXT:  entry:
114 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
115 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
116 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
117 ; CHECK-NEXT:    br label [[LOOP:%.*]]
118 ; CHECK:       loop:
119 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
120 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
121 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
122 ; CHECK:       if.true:
123 ; CHECK-NEXT:    br label [[BACKEDGE]]
124 ; CHECK:       if.false:
125 ; CHECK-NEXT:    br label [[BACKEDGE]]
126 ; CHECK:       backedge:
127 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
128 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
129 ; CHECK:       exit:
130 ; CHECK-NEXT:    ret void
133 entry:
134   br label %loop
136 loop:
137   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
138   %iv.next = add i32 %iv, 1
139   br i1 %c, label %if.true, label %if.false
141 if.true:
142   br label %backedge
144 if.false:
145   br label %backedge
147 backedge:
148   %a = load i32, i32* %p
149   %invariant_cond = icmp ne i32 %a, 100
150   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
151   %loop_cond = icmp slt i32 %iv.next, 1000
152   br i1 %loop_cond, label %loop, label %exit
154 exit:
155   ret void
158 ; Do not hoist across a conditionally executed side effect.
159 define void @test4a(i1 %c, i32* %p, i32* %q) {
160 ; CHECK-LABEL: @test4a(
161 ; CHECK-NEXT:  entry:
162 ; CHECK-NEXT:    br label [[LOOP:%.*]]
163 ; CHECK:       loop:
164 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
165 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
166 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
167 ; CHECK:       if.true:
168 ; CHECK-NEXT:    store i32 123, i32* [[Q:%.*]]
169 ; CHECK-NEXT:    br label [[BACKEDGE]]
170 ; CHECK:       if.false:
171 ; CHECK-NEXT:    br label [[BACKEDGE]]
172 ; CHECK:       backedge:
173 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
174 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
175 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
176 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
177 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
178 ; CHECK:       exit:
179 ; CHECK-NEXT:    ret void
182 entry:
183   br label %loop
185 loop:
186   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
187   %iv.next = add i32 %iv, 1
188   br i1 %c, label %if.true, label %if.false
190 if.true:
191   store i32 123, i32* %q
192   br label %backedge
194 if.false:
195   br label %backedge
197 backedge:
198   %a = load i32, i32* %p
199   %invariant_cond = icmp ne i32 %a, 100
200   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
201   %loop_cond = icmp slt i32 %iv.next, 1000
202   br i1 %loop_cond, label %loop, label %exit
204 exit:
205   ret void
208 ; Do not hoist a conditionally executed guard.
209 define void @test4b(i1 %c, i32* %p, i32* %q) {
210 ; CHECK-LABEL: @test4b(
211 ; CHECK-NEXT:  entry:
212 ; CHECK-NEXT:    br label [[LOOP:%.*]]
213 ; CHECK:       loop:
214 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
215 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
216 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
217 ; CHECK:       if.true:
218 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
219 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
220 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
221 ; CHECK-NEXT:    br label [[BACKEDGE]]
222 ; CHECK:       if.false:
223 ; CHECK-NEXT:    br label [[BACKEDGE]]
224 ; CHECK:       backedge:
225 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
226 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
227 ; CHECK:       exit:
228 ; CHECK-NEXT:    ret void
231 entry:
232   br label %loop
234 loop:
235   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
236   %iv.next = add i32 %iv, 1
237   br i1 %c, label %if.true, label %if.false
239 if.true:
240   %a = load i32, i32* %p
241   %invariant_cond = icmp ne i32 %a, 100
242   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
243   br label %backedge
245 if.false:
246   br label %backedge
248 backedge:
249   %loop_cond = icmp slt i32 %iv.next, 1000
250   br i1 %loop_cond, label %loop, label %exit
252 exit:
253   ret void
256 ; Hoist store, load and guard.
257 define void @test4c(i1 %c, i32* %p, i8* noalias %s) {
258 ; CHECK-LABEL: @test4c(
259 ; CHECK-NEXT:  entry:
260 ; CHECK-NEXT:    store i8 0, i8* [[S:%.*]]
261 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
262 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
263 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
264 ; CHECK-NEXT:    br label [[LOOP:%.*]]
265 ; CHECK:       loop:
266 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
267 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
268 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
269 ; CHECK:       if.true:
270 ; CHECK-NEXT:    br label [[BACKEDGE]]
271 ; CHECK:       if.false:
272 ; CHECK-NEXT:    br label [[BACKEDGE]]
273 ; CHECK:       backedge:
274 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
275 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
276 ; CHECK:       exit:
277 ; CHECK-NEXT:    ret void
280 entry:
281   br label %loop
283 loop:
284   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
285   %iv.next = add i32 %iv, 1
286   store i8 0, i8* %s
287   br i1 %c, label %if.true, label %if.false
289 if.true:
290   br label %backedge
292 if.false:
293   br label %backedge
295 backedge:
296   %a = load i32, i32* %p
297   %invariant_cond = icmp ne i32 %a, 100
298   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
299   %loop_cond = icmp slt i32 %iv.next, 1000
300   br i1 %loop_cond, label %loop, label %exit
302 exit:
303   ret void
306 ; Check that we don't hoist across a store in a conditionally executed block.
307 define void @test4d(i1 %c, i32* %p, i8* noalias %s) {
308 ; CHECK-LABEL: @test4d(
309 ; CHECK-NEXT:  entry:
310 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
311 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
312 ; CHECK-NEXT:    br label [[LOOP:%.*]]
313 ; CHECK:       loop:
314 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
315 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
316 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
317 ; CHECK:       if.true:
318 ; CHECK-NEXT:    store i8 0, i8* [[S:%.*]]
319 ; CHECK-NEXT:    br label [[BACKEDGE]]
320 ; CHECK:       if.false:
321 ; CHECK-NEXT:    br label [[BACKEDGE]]
322 ; CHECK:       backedge:
323 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
324 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
325 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
326 ; CHECK:       exit:
327 ; CHECK-NEXT:    ret void
330 entry:
331   br label %loop
333 loop:
334   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
335   %iv.next = add i32 %iv, 1
336   br i1 %c, label %if.true, label %if.false
338 if.true:
339   store i8 0, i8* %s
340   br label %backedge
342 if.false:
343   br label %backedge
345 backedge:
346   %a = load i32, i32* %p
347   %invariant_cond = icmp ne i32 %a, 100
348   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
349   %loop_cond = icmp slt i32 %iv.next, 1000
350   br i1 %loop_cond, label %loop, label %exit
352 exit:
353   ret void
356 ; Check that we don't hoist across a store before the guard in the backedge.
357 define void @test4e(i1 %c, i32* %p, i8* noalias %s) {
358 ; CHECK-LABEL: @test4e(
359 ; CHECK-NEXT:  entry:
360 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
361 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
362 ; CHECK-NEXT:    store i8 0, i8* [[S:%.*]]
363 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
364 ; CHECK-NEXT:    br label [[LOOP:%.*]]
365 ; CHECK:       loop:
366 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
367 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
368 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
369 ; CHECK:       if.true:
370 ; CHECK-NEXT:    br label [[BACKEDGE]]
371 ; CHECK:       if.false:
372 ; CHECK-NEXT:    br label [[BACKEDGE]]
373 ; CHECK:       backedge:
374 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
375 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
376 ; CHECK:       exit:
377 ; CHECK-NEXT:    ret void
380 entry:
381   br label %loop
383 loop:
384   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
385   %iv.next = add i32 %iv, 1
386   br i1 %c, label %if.true, label %if.false
388 if.true:
389   br label %backedge
391 if.false:
392   br label %backedge
394 backedge:
395   %a = load i32, i32* %p
396   %invariant_cond = icmp ne i32 %a, 100
397   store i8 0, i8* %s
398   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
399   %loop_cond = icmp slt i32 %iv.next, 1000
400   br i1 %loop_cond, label %loop, label %exit
402 exit:
403   ret void
406 ; Check that we can hoist the guard in spite of store which happens after.
407 define void @test4f(i1 %c, i32* %p, i8* noalias %s) {
408 ; CHECK-LABEL: @test4f(
409 ; CHECK-NEXT:  entry:
410 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
411 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
412 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
413 ; CHECK-NEXT:    store i8 0, i8* [[S:%.*]]
414 ; CHECK-NEXT:    br label [[LOOP:%.*]]
415 ; CHECK:       loop:
416 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
417 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
418 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
419 ; CHECK:       if.true:
420 ; CHECK-NEXT:    br label [[BACKEDGE]]
421 ; CHECK:       if.false:
422 ; CHECK-NEXT:    br label [[BACKEDGE]]
423 ; CHECK:       backedge:
424 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
425 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
426 ; CHECK:       exit:
427 ; CHECK-NEXT:    ret void
430 entry:
431   br label %loop
433 loop:
434   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
435   %iv.next = add i32 %iv, 1
436   br i1 %c, label %if.true, label %if.false
438 if.true:
439   br label %backedge
441 if.false:
442   br label %backedge
444 backedge:
445   %a = load i32, i32* %p
446   %invariant_cond = icmp ne i32 %a, 100
447   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
448   store i8 0, i8* %s
449   %loop_cond = icmp slt i32 %iv.next, 1000
450   br i1 %loop_cond, label %loop, label %exit
452 exit:
453   ret void
456 ; Do not hoist an invariant guard across a variant guard.
457 define void @test5(i1 %c, i32* %p, i32* %q) {
458 ; CHECK-LABEL: @test5(
459 ; CHECK-NEXT:  entry:
460 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
461 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
462 ; CHECK-NEXT:    br label [[LOOP:%.*]]
463 ; CHECK:       loop:
464 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
465 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
466 ; CHECK-NEXT:    [[VARIANT_COND:%.*]] = icmp ne i32 [[A]], [[IV]]
467 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[VARIANT_COND]]) [ "deopt"() ]
468 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
469 ; CHECK-NEXT:    br label [[BACKEDGE]]
470 ; CHECK:       backedge:
471 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
472 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
473 ; CHECK:       exit:
474 ; CHECK-NEXT:    ret void
477 entry:
478   br label %loop
480 loop:
481   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
482   %iv.next = add i32 %iv, 1
483   %a = load i32, i32* %p
484   %invariant_cond = icmp ne i32 %a, 100
485   %variant_cond = icmp ne i32 %a, %iv
486   call void (i1, ...) @llvm.experimental.guard(i1 %variant_cond) [ "deopt"() ]
487   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
488   br label %backedge
490 backedge:
491   %loop_cond = icmp slt i32 %iv.next, 1000
492   br i1 %loop_cond, label %loop, label %exit
494 exit:
495   ret void
498 ; Hoist an invariant guard, leave the following variant guard in the loop.
499 define void @test5a(i1 %c, i32* %p, i32* %q) {
500 ; CHECK-LABEL: @test5a(
501 ; CHECK-NEXT:  entry:
502 ; CHECK-NEXT:    [[A:%.*]] = load i32, i32* [[P:%.*]]
503 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
504 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
505 ; CHECK-NEXT:    br label [[LOOP:%.*]]
506 ; CHECK:       loop:
507 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
508 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
509 ; CHECK-NEXT:    [[VARIANT_COND:%.*]] = icmp ne i32 [[A]], [[IV]]
510 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[VARIANT_COND]]) [ "deopt"() ]
511 ; CHECK-NEXT:    br label [[BACKEDGE]]
512 ; CHECK:       backedge:
513 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
514 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
515 ; CHECK:       exit:
516 ; CHECK-NEXT:    ret void
519 entry:
520   br label %loop
522 loop:
523   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
524   %iv.next = add i32 %iv, 1
525   %a = load i32, i32* %p
526   %invariant_cond = icmp ne i32 %a, 100
527   %variant_cond = icmp ne i32 %a, %iv
528   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
529   call void (i1, ...) @llvm.experimental.guard(i1 %variant_cond) [ "deopt"() ]
530   br label %backedge
532 backedge:
533   %loop_cond = icmp slt i32 %iv.next, 1000
534   br i1 %loop_cond, label %loop, label %exit
536 exit:
537   ret void
540 declare void @llvm.experimental.guard(i1, ...)