1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=early-cse -earlycse-debug-hash < %s | FileCheck %s --check-prefixes=CHECK,NO_ASSUME
3 ; RUN: opt < %s -S -passes='early-cse<memssa>' | FileCheck %s --check-prefixes=CHECK,NO_ASSUME
4 ; RUN: opt < %s -S -passes='early-cse<memssa>' --enable-knowledge-retention | FileCheck %s --check-prefixes=CHECK,USE_ASSUME
6 declare void @llvm.experimental.guard(i1,...)
8 declare void @llvm.assume(i1)
10 define i32 @test0(ptr %ptr, i1 %cond) {
11 ; We can do store to load forwarding over a guard, since it does not
13 ; NO_ASSUME-LABEL: @test0(
14 ; NO_ASSUME-NEXT: store i32 40, ptr [[PTR:%.*]], align 4
15 ; NO_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"() ]
16 ; NO_ASSUME-NEXT: ret i32 40
18 ; USE_ASSUME-LABEL: @test0(
19 ; USE_ASSUME-NEXT: store i32 40, ptr [[PTR:%.*]], align 4
20 ; USE_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"() ]
21 ; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]
22 ; USE_ASSUME-NEXT: ret i32 40
25 store i32 40, ptr %ptr
26 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
27 %rval = load i32, ptr %ptr
31 define i32 @test1(ptr %val, i1 %cond) {
32 ; We can CSE loads over a guard, since it does not clobber memory
33 ; NO_ASSUME-LABEL: @test1(
34 ; NO_ASSUME-NEXT: [[VAL0:%.*]] = load i32, ptr [[VAL:%.*]], align 4
35 ; NO_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"() ]
36 ; NO_ASSUME-NEXT: ret i32 0
38 ; USE_ASSUME-LABEL: @test1(
39 ; USE_ASSUME-NEXT: [[VAL0:%.*]] = load i32, ptr [[VAL:%.*]], align 4
40 ; USE_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND:%.*]]) [ "deopt"() ]
41 ; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[VAL]], i64 4), "nonnull"(ptr [[VAL]]), "align"(ptr [[VAL]], i64 4) ]
42 ; USE_ASSUME-NEXT: ret i32 0
45 %val0 = load i32, ptr %val
46 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
47 %val1 = load i32, ptr %val
48 %rval = sub i32 %val0, %val1
53 ; Guards on "true" get removed
54 ; CHECK-LABEL: @test2(
55 ; CHECK-NEXT: ret i32 0
57 call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
61 define i32 @test3(i32 %val) {
62 ; After a guard has executed the condition it was guarding is known to
64 ; CHECK-LABEL: @test3(
65 ; CHECK-NEXT: [[COND0:%.*]] = icmp slt i32 [[VAL:%.*]], 40
66 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND0]]) [ "deopt"() ]
67 ; CHECK-NEXT: ret i32 -1
70 %cond0 = icmp slt i32 %val, 40
71 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ]
72 %cond1 = icmp slt i32 %val, 40
73 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
75 %cond2 = icmp slt i32 %val, 40
76 %rval = sext i1 %cond2 to i32
80 define i32 @test3.unhandled(i32 %val) {
81 ; After a guard has executed the condition it was guarding is known to
83 ; CHECK-LABEL: @test3.unhandled(
84 ; CHECK-NEXT: [[COND0:%.*]] = icmp slt i32 [[VAL:%.*]], 40
85 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND0]]) [ "deopt"() ]
86 ; CHECK-NEXT: [[COND1:%.*]] = icmp sge i32 [[VAL]], 40
87 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND1]]) [ "deopt"() ]
88 ; CHECK-NEXT: ret i32 0
91 ; Demonstrates a case we do not yet handle (it is legal to fold %cond2
93 %cond0 = icmp slt i32 %val, 40
94 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ]
95 %cond1 = icmp sge i32 %val, 40
96 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
100 define i32 @test4(i32 %val, i1 %c) {
101 ; Same as test3, but with some control flow involved.
102 ; CHECK-LABEL: @test4(
104 ; CHECK-NEXT: [[COND0:%.*]] = icmp slt i32 [[VAL:%.*]], 40
105 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND0]]) [ "deopt"() ]
106 ; CHECK-NEXT: br label [[BB0:%.*]]
108 ; CHECK-NEXT: [[COND2:%.*]] = icmp ult i32 [[VAL]], 200
109 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND2]]) [ "deopt"() ]
110 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
112 ; CHECK-NEXT: ret i32 0
114 ; CHECK-NEXT: ret i32 20
121 %cond0 = icmp slt i32 %val, 40
122 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ]
123 %cond1 = icmp slt i32 %val, 40
124 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
128 %cond2 = icmp ult i32 %val, 200
129 call void(i1,...) @llvm.experimental.guard(i1 %cond2) [ "deopt"() ]
130 br i1 %c, label %left, label %right
133 %cond3 = icmp ult i32 %val, 200
134 call void(i1,...) @llvm.experimental.guard(i1 %cond3) [ "deopt"() ]
141 define i32 @test5(i32 %val, i1 %c) {
142 ; Same as test4, but the %left block has mutliple predecessors.
143 ; CHECK-LABEL: @test5(
145 ; CHECK-NEXT: [[COND0:%.*]] = icmp slt i32 [[VAL:%.*]], 40
146 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND0]]) [ "deopt"() ]
147 ; CHECK-NEXT: br label [[BB0:%.*]]
149 ; CHECK-NEXT: [[COND2:%.*]] = icmp ult i32 [[VAL]], 200
150 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND2]]) [ "deopt"() ]
151 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
153 ; CHECK-NEXT: br label [[RIGHT]]
155 ; CHECK-NEXT: br label [[LEFT]]
163 %cond0 = icmp slt i32 %val, 40
164 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ]
165 %cond1 = icmp slt i32 %val, 40
166 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
170 %cond2 = icmp ult i32 %val, 200
171 call void(i1,...) @llvm.experimental.guard(i1 %cond2) [ "deopt"() ]
172 br i1 %c, label %left, label %right
175 %cond3 = icmp ult i32 %val, 200
176 call void(i1,...) @llvm.experimental.guard(i1 %cond3) [ "deopt"() ]
183 define void @test6(i1 %c, ptr %ptr) {
184 ; Check that we do not DSE over calls to @llvm.experimental.guard.
185 ; Guard intrinsics do _read_ memory, so th call to guard below needs
186 ; to see the store of 500 to %ptr
187 ; CHECK-LABEL: @test6(
188 ; CHECK-NEXT: store i32 500, ptr [[PTR:%.*]], align 4
189 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[C:%.*]]) [ "deopt"() ]
190 ; CHECK-NEXT: store i32 600, ptr [[PTR]], align 4
191 ; CHECK-NEXT: ret void
195 store i32 500, ptr %ptr
196 call void(i1,...) @llvm.experimental.guard(i1 %c) [ "deopt"() ]
197 store i32 600, ptr %ptr
201 define void @test07(i32 %a, i32 %b) {
202 ; Check that we are able to remove the guards on the same condition even if the
203 ; condition is not being recalculated.
204 ; CHECK-LABEL: @test07(
205 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
206 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]
207 ; CHECK-NEXT: ret void
210 %cmp = icmp eq i32 %a, %b
211 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
212 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
213 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
217 define void @test08(i32 %a, i32 %b, ptr %ptr) {
218 ; Check that we deal correctly with stores when removing guards in the same
219 ; block in case when the condition is not recalculated.
220 ; NO_ASSUME-LABEL: @test08(
221 ; NO_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
222 ; NO_ASSUME-NEXT: store i32 100, ptr [[PTR:%.*]], align 4
223 ; NO_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]
224 ; NO_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4
225 ; NO_ASSUME-NEXT: ret void
227 ; USE_ASSUME-LABEL: @test08(
228 ; USE_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
229 ; USE_ASSUME-NEXT: store i32 100, ptr [[PTR:%.*]], align 4
230 ; USE_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]
231 ; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]
232 ; USE_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4
233 ; USE_ASSUME-NEXT: ret void
236 %cmp = icmp eq i32 %a, %b
237 store i32 100, ptr %ptr
238 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
239 store i32 200, ptr %ptr
240 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
241 store i32 300, ptr %ptr
242 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
243 store i32 400, ptr %ptr
247 define void @test09(i32 %a, i32 %b, i1 %c, ptr %ptr) {
248 ; Similar to test08, but with more control flow.
249 ; TODO: Can we get rid of the store in the end of entry given that it is
250 ; post-dominated by other stores?
251 ; NO_ASSUME-LABEL: @test09(
252 ; NO_ASSUME-NEXT: entry:
253 ; NO_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
254 ; NO_ASSUME-NEXT: store i32 100, ptr [[PTR:%.*]], align 4
255 ; NO_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]
256 ; NO_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4
257 ; NO_ASSUME-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
258 ; NO_ASSUME: if.true:
259 ; NO_ASSUME-NEXT: store i32 500, ptr [[PTR]], align 4
260 ; NO_ASSUME-NEXT: br label [[MERGE:%.*]]
261 ; NO_ASSUME: if.false:
262 ; NO_ASSUME-NEXT: store i32 600, ptr [[PTR]], align 4
263 ; NO_ASSUME-NEXT: br label [[MERGE]]
265 ; NO_ASSUME-NEXT: ret void
267 ; USE_ASSUME-LABEL: @test09(
268 ; USE_ASSUME-NEXT: entry:
269 ; USE_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
270 ; USE_ASSUME-NEXT: store i32 100, ptr [[PTR:%.*]], align 4
271 ; USE_ASSUME-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]
272 ; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]
273 ; USE_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4
274 ; USE_ASSUME-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
275 ; USE_ASSUME: if.true:
276 ; USE_ASSUME-NEXT: store i32 500, ptr [[PTR]], align 4
277 ; USE_ASSUME-NEXT: br label [[MERGE:%.*]]
278 ; USE_ASSUME: if.false:
279 ; USE_ASSUME-NEXT: store i32 600, ptr [[PTR]], align 4
280 ; USE_ASSUME-NEXT: br label [[MERGE]]
282 ; USE_ASSUME-NEXT: ret void
286 %cmp = icmp eq i32 %a, %b
287 store i32 100, ptr %ptr
288 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
289 store i32 200, ptr %ptr
290 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
291 store i32 300, ptr %ptr
292 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
293 store i32 400, ptr %ptr
294 br i1 %c, label %if.true, label %if.false
297 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
298 store i32 500, ptr %ptr
302 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
303 store i32 600, ptr %ptr
310 define void @test10(i32 %a, i32 %b, i1 %c, ptr %ptr) {
311 ; Make sure that non-dominating guards do not cause other guards removal.
312 ; CHECK-LABEL: @test10(
314 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
315 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
317 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]
318 ; CHECK-NEXT: store i32 100, ptr [[PTR:%.*]], align 4
319 ; CHECK-NEXT: br label [[MERGE:%.*]]
321 ; CHECK-NEXT: store i32 200, ptr [[PTR]], align 4
322 ; CHECK-NEXT: br label [[MERGE]]
324 ; CHECK-NEXT: store i32 300, ptr [[PTR]], align 4
325 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]
326 ; CHECK-NEXT: store i32 400, ptr [[PTR]], align 4
327 ; CHECK-NEXT: ret void
331 %cmp = icmp eq i32 %a, %b
332 br i1 %c, label %if.true, label %if.false
335 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
336 store i32 100, ptr %ptr
337 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
341 store i32 200, ptr %ptr
345 store i32 300, ptr %ptr
346 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
347 store i32 400, ptr %ptr
351 define void @test11(i32 %a, i32 %b, ptr %ptr) {
352 ; Make sure that branching condition is applied to guards.
353 ; CHECK-LABEL: @test11(
355 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
356 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
358 ; CHECK-NEXT: br label [[MERGE:%.*]]
360 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
361 ; CHECK-NEXT: br label [[MERGE]]
363 ; CHECK-NEXT: ret void
367 %cmp = icmp eq i32 %a, %b
368 br i1 %cmp, label %if.true, label %if.false
371 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
375 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
382 define void @test12(i32 %a, i32 %b) {
383 ; Check that the assume marks its condition as being true (and thus allows to
384 ; eliminate the dominated guards).
385 ; CHECK-LABEL: @test12(
386 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
387 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
388 ; CHECK-NEXT: ret void
391 %cmp = icmp eq i32 %a, %b
392 call void @llvm.assume(i1 %cmp)
393 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
394 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
395 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
399 define void @test13(i32 %a, i32 %b, ptr %ptr) {
400 ; Check that we deal correctly with stores when removing guards due to assume.
401 ; NO_ASSUME-LABEL: @test13(
402 ; NO_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
403 ; NO_ASSUME-NEXT: call void @llvm.assume(i1 [[CMP]])
404 ; NO_ASSUME-NEXT: store i32 400, ptr [[PTR:%.*]], align 4
405 ; NO_ASSUME-NEXT: ret void
407 ; USE_ASSUME-LABEL: @test13(
408 ; USE_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
409 ; USE_ASSUME-NEXT: call void @llvm.assume(i1 [[CMP]])
410 ; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR:%.*]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]
411 ; USE_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4
412 ; USE_ASSUME-NEXT: ret void
415 %cmp = icmp eq i32 %a, %b
416 call void @llvm.assume(i1 %cmp)
417 store i32 100, ptr %ptr
418 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
419 store i32 200, ptr %ptr
420 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
421 store i32 300, ptr %ptr
422 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
423 store i32 400, ptr %ptr
427 define void @test14(i32 %a, i32 %b, i1 %c, ptr %ptr) {
428 ; Similar to test13, but with more control flow.
429 ; TODO: Can we get rid of the store in the end of entry given that it is
430 ; post-dominated by other stores?
431 ; NO_ASSUME-LABEL: @test14(
432 ; NO_ASSUME-NEXT: entry:
433 ; NO_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
434 ; NO_ASSUME-NEXT: call void @llvm.assume(i1 [[CMP]])
435 ; NO_ASSUME-NEXT: store i32 400, ptr [[PTR:%.*]], align 4
436 ; NO_ASSUME-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
437 ; NO_ASSUME: if.true:
438 ; NO_ASSUME-NEXT: store i32 500, ptr [[PTR]], align 4
439 ; NO_ASSUME-NEXT: br label [[MERGE:%.*]]
440 ; NO_ASSUME: if.false:
441 ; NO_ASSUME-NEXT: store i32 600, ptr [[PTR]], align 4
442 ; NO_ASSUME-NEXT: br label [[MERGE]]
444 ; NO_ASSUME-NEXT: ret void
446 ; USE_ASSUME-LABEL: @test14(
447 ; USE_ASSUME-NEXT: entry:
448 ; USE_ASSUME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
449 ; USE_ASSUME-NEXT: call void @llvm.assume(i1 [[CMP]])
450 ; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR:%.*]], i64 4), "nonnull"(ptr [[PTR]]), "align"(ptr [[PTR]], i64 4) ]
451 ; USE_ASSUME-NEXT: store i32 400, ptr [[PTR]], align 4
452 ; USE_ASSUME-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
453 ; USE_ASSUME: if.true:
454 ; USE_ASSUME-NEXT: store i32 500, ptr [[PTR]], align 4
455 ; USE_ASSUME-NEXT: br label [[MERGE:%.*]]
456 ; USE_ASSUME: if.false:
457 ; USE_ASSUME-NEXT: store i32 600, ptr [[PTR]], align 4
458 ; USE_ASSUME-NEXT: br label [[MERGE]]
460 ; USE_ASSUME-NEXT: ret void
464 %cmp = icmp eq i32 %a, %b
465 call void @llvm.assume(i1 %cmp)
466 store i32 100, ptr %ptr
467 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
468 store i32 200, ptr %ptr
469 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
470 store i32 300, ptr %ptr
471 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
472 store i32 400, ptr %ptr
473 br i1 %c, label %if.true, label %if.false
476 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
477 store i32 500, ptr %ptr
481 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
482 store i32 600, ptr %ptr
489 define void @test15(i32 %a, i32 %b, i1 %c, ptr %ptr) {
490 ; Make sure that non-dominating assumes do not cause guards removal.
491 ; CHECK-LABEL: @test15(
493 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
494 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
496 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
497 ; CHECK-NEXT: store i32 100, ptr [[PTR:%.*]], align 4
498 ; CHECK-NEXT: br label [[MERGE:%.*]]
500 ; CHECK-NEXT: store i32 200, ptr [[PTR]], align 4
501 ; CHECK-NEXT: br label [[MERGE]]
503 ; CHECK-NEXT: store i32 300, ptr [[PTR]], align 4
504 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"() ]
505 ; CHECK-NEXT: store i32 400, ptr [[PTR]], align 4
506 ; CHECK-NEXT: ret void
510 %cmp = icmp eq i32 %a, %b
511 br i1 %c, label %if.true, label %if.false
514 call void @llvm.assume(i1 %cmp)
515 store i32 100, ptr %ptr
516 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
520 store i32 200, ptr %ptr
524 store i32 300, ptr %ptr
525 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
526 store i32 400, ptr %ptr
530 define void @test16(i32 %a, i32 %b) {
531 ; Check that we don't bother to do anything with assumes even if we know the
532 ; condition being true.
533 ; CHECK-LABEL: @test16(
534 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
535 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
536 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
537 ; CHECK-NEXT: ret void
540 %cmp = icmp eq i32 %a, %b
541 call void @llvm.assume(i1 %cmp)
542 call void @llvm.assume(i1 %cmp)
546 define void @test17(i32 %a, i32 %b, i1 %c, ptr %ptr) {
547 ; Check that we don't bother to do anything with assumes even if we know the
548 ; condition being true or false (includes come control flow).
549 ; CHECK-LABEL: @test17(
551 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
552 ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
554 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
555 ; CHECK-NEXT: br label [[MERGE:%.*]]
557 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
558 ; CHECK-NEXT: br label [[MERGE]]
560 ; CHECK-NEXT: ret void
564 %cmp = icmp eq i32 %a, %b
565 br i1 %c, label %if.true, label %if.false
568 call void @llvm.assume(i1 %cmp)
572 call void @llvm.assume(i1 %cmp)
579 define void @test18(i1 %c) {
580 ; Check that we don't bother to do anything with assumes even if we know the
581 ; condition being true and not being an instruction.
582 ; CHECK-LABEL: @test18(
583 ; CHECK-NEXT: call void @llvm.assume(i1 [[C:%.*]])
584 ; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
585 ; CHECK-NEXT: ret void
588 call void @llvm.assume(i1 %c)
589 call void @llvm.assume(i1 %c)