1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 declare void @llvm.assume(i1)
6 declare void @may_unwind()
10 define i1 @assume_dominates(i8 %a, i8 %b, i1 %c) {
11 ; CHECK-LABEL: @assume_dominates(
12 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
13 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
14 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
15 ; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
17 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
18 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
19 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
20 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
21 ; CHECK-NEXT: ret i1 [[RES_2]]
23 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, true
24 ; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
25 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
26 ; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
27 ; CHECK-NEXT: ret i1 [[RES_4]]
29 %add.1 = add nsw nuw i8 %a, 1
30 %cmp.1 = icmp ule i8 %add.1, %b
31 call void @llvm.assume(i1 %cmp.1)
32 br i1 %c, label %then, label %else
35 %t.1 = icmp ule i8 %add.1, %b
36 %t.2 = icmp ule i8 %a, %b
37 %res.1 = xor i1 %t.1, %t.2
38 %add.2 = add nsw nuw i8 %a, 2
39 %c.1 = icmp ule i8 %add.2, %b
40 %res.2 = xor i1 %res.1, %c.1
44 %t.3 = icmp ule i8 %add.1, %b
45 %t.4 = icmp ule i8 %a, %b
46 %res.3 = xor i1 %t.3, %t.4
47 %add.2.1 = add nsw nuw i8 %a, 2
48 %c.2 = icmp ule i8 %add.2.1, %b
49 %res.4 = xor i1 %res.3, %c.2
53 define i1 @assume_dominates_with_may_unwind_call_before_assume(i8 %a, i8 %b, i1 %c) {
54 ; CHECK-LABEL: @assume_dominates_with_may_unwind_call_before_assume(
55 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
56 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
57 ; CHECK-NEXT: call void @may_unwind()
58 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
59 ; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
61 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
62 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
63 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
64 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
65 ; CHECK-NEXT: ret i1 [[RES_2]]
67 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, true
68 ; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
69 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
70 ; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
71 ; CHECK-NEXT: ret i1 [[RES_4]]
73 %add.1 = add nsw nuw i8 %a, 1
74 %cmp.1 = icmp ule i8 %add.1, %b
75 call void @may_unwind()
76 call void @llvm.assume(i1 %cmp.1)
77 br i1 %c, label %then, label %else
80 %t.1 = icmp ule i8 %add.1, %b
81 %t.2 = icmp ule i8 %a, %b
82 %res.1 = xor i1 %t.1, %t.2
83 %add.2 = add nsw nuw i8 %a, 2
84 %c.1 = icmp ule i8 %add.2, %b
85 %res.2 = xor i1 %res.1, %c.1
89 %t.3 = icmp ule i8 %add.1, %b
90 %t.4 = icmp ule i8 %a, %b
91 %res.3 = xor i1 %t.3, %t.4
92 %add.2.1 = add nsw nuw i8 %a, 2
93 %c.2 = icmp ule i8 %add.2.1, %b
94 %res.4 = xor i1 %res.3, %c.2
98 define i1 @assume_dominates_with_may_unwind_call_after_assume(i8 %a, i8 %b, i1 %c) {
99 ; CHECK-LABEL: @assume_dominates_with_may_unwind_call_after_assume(
100 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
101 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
102 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
103 ; CHECK-NEXT: call void @may_unwind()
104 ; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
106 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
107 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
108 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
109 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
110 ; CHECK-NEXT: ret i1 [[RES_2]]
112 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, true
113 ; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
114 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
115 ; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
116 ; CHECK-NEXT: ret i1 [[RES_4]]
118 %add.1 = add nsw nuw i8 %a, 1
119 %cmp.1 = icmp ule i8 %add.1, %b
120 call void @llvm.assume(i1 %cmp.1)
121 call void @may_unwind()
122 br i1 %c, label %then, label %else
125 %t.1 = icmp ule i8 %add.1, %b
126 %t.2 = icmp ule i8 %a, %b
127 %res.1 = xor i1 %t.1, %t.2
128 %add.2 = add nsw nuw i8 %a, 2
129 %c.1 = icmp ule i8 %add.2, %b
130 %res.2 = xor i1 %res.1, %c.1
134 %t.3 = icmp ule i8 %add.1, %b
135 %t.4 = icmp ule i8 %a, %b
136 %res.3 = xor i1 %t.3, %t.4
137 %add.2.1 = add nsw nuw i8 %a, 2
138 %c.2 = icmp ule i8 %add.2.1, %b
139 %res.4 = xor i1 %res.3, %c.2
143 ; Test case from PR54217.
144 define i1 @assume_does_not_dominates_successor_with_may_unwind_call_before_assume(i16 %a, i1 %i.0) {
145 ; CHECK-LABEL: @assume_does_not_dominates_successor_with_may_unwind_call_before_assume(
147 ; CHECK-NEXT: br i1 [[I_0:%.*]], label [[EXIT:%.*]], label [[IF_THEN:%.*]]
149 ; CHECK-NEXT: call void @may_unwind()
150 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[A:%.*]], 0
151 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
152 ; CHECK-NEXT: br label [[EXIT]]
154 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[A]], 0
155 ; CHECK-NEXT: ret i1 [[C_2]]
158 br i1 %i.0, label %exit, label %if.then
161 call void @may_unwind()
162 %c.1 = icmp eq i16 %a, 0
163 call void @llvm.assume(i1 %c.1)
167 %c.2 = icmp eq i16 %a, 0
171 define i1 @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch(i16 %a) {
172 ; CHECK-LABEL: @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch(
174 ; CHECK-NEXT: call void @may_unwind()
175 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[A:%.*]], 0
176 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
177 ; CHECK-NEXT: br label [[EXIT:%.*]]
179 ; CHECK-NEXT: ret i1 true
182 call void @may_unwind()
183 %c.1 = icmp eq i16 %a, 0
184 call void @llvm.assume(i1 %c.1)
188 %c.2 = icmp eq i16 %a, 0
192 define i1 @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch_2(i16 %a, i1 %c) {
193 ; CHECK-LABEL: @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch_2(
195 ; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
197 ; CHECK-NEXT: call void @may_unwind()
198 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[A:%.*]], 0
199 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
200 ; CHECK-NEXT: br label [[EXIT]]
202 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[A]], 0
203 ; CHECK-NEXT: ret i1 [[C_2]]
206 br i1 %c, label %then, label %exit
209 call void @may_unwind()
210 %c.1 = icmp eq i16 %a, 0
211 call void @llvm.assume(i1 %c.1)
215 %c.2 = icmp eq i16 %a, 0
219 define i1 @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch_cycle(i16 %a, i1 %c) {
220 ; CHECK-LABEL: @assume_dominates_successor_with_may_unwind_call_before_assume_uncond_branch_cycle(
222 ; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
224 ; CHECK-NEXT: call void @may_unwind()
225 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i16 [[A:%.*]], 0
226 ; CHECK-NEXT: call void @use(i1 [[C_1]])
227 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
228 ; CHECK-NEXT: br label [[THEN]]
230 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[A]], 0
231 ; CHECK-NEXT: ret i1 [[C_2]]
234 br i1 %c, label %then, label %exit
237 call void @may_unwind()
238 %c.1 = icmp eq i16 %a, 0
239 call void @use(i1 %c.1)
240 call void @llvm.assume(i1 %c.1)
244 %c.2 = icmp eq i16 %a, 0
248 define i1 @assume_single_bb(i8 %a, i8 %b, i1 %c) {
249 ; CHECK-LABEL: @assume_single_bb(
250 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
251 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
252 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
253 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
254 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
255 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
256 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
257 ; CHECK-NEXT: ret i1 [[RES_2]]
259 %add.1 = add nsw nuw i8 %a, 1
260 %cmp.1 = icmp ule i8 %add.1, %b
261 call void @llvm.assume(i1 %cmp.1)
262 %t.1 = icmp ule i8 %add.1, %b
263 %t.2 = icmp ule i8 %a, %b
264 %res.1 = xor i1 %t.1, %t.2
265 %add.2 = add nsw nuw i8 %a, 2
266 %c.1 = icmp ule i8 %add.2, %b
267 %res.2 = xor i1 %res.1, %c.1
271 define i1 @assume_same_bb(i8 %a, i8 %b, i1 %c) {
272 ; CHECK-LABEL: @assume_same_bb(
273 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
274 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
275 ; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
277 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
278 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
279 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
280 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
281 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
282 ; CHECK-NEXT: ret i1 [[RES_2]]
284 ; CHECK-NEXT: [[T_3:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
285 ; CHECK-NEXT: [[T_4:%.*]] = icmp ule i8 [[A]], [[B]]
286 ; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[T_3]], [[T_4]]
287 ; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
288 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
289 ; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
290 ; CHECK-NEXT: ret i1 [[RES_4]]
292 %add.1 = add nsw nuw i8 %a, 1
293 %cmp.1 = icmp ule i8 %add.1, %b
294 br i1 %c, label %then, label %else
297 call void @llvm.assume(i1 %cmp.1)
298 %t.1 = icmp ule i8 %add.1, %b
299 %t.2 = icmp ule i8 %a, %b
300 %res.1 = xor i1 %t.1, %t.2
301 %add.2 = add nsw nuw i8 %a, 2
302 %c.1 = icmp ule i8 %add.2, %b
303 %res.2 = xor i1 %res.1, %c.1
307 %t.3 = icmp ule i8 %add.1, %b
308 %t.4 = icmp ule i8 %a, %b
309 %res.3 = xor i1 %t.3, %t.4
310 %add.2.1 = add nsw nuw i8 %a, 2
311 %c.2 = icmp ule i8 %add.2.1, %b
312 %res.4 = xor i1 %res.3, %c.2
316 define i1 @assume_same_bb2(i8 %a, i8 %b, i1 %c) {
317 ; CHECK-LABEL: @assume_same_bb2(
318 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
319 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
320 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
321 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
322 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
323 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
324 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
325 ; CHECK-NEXT: br label [[EXIT:%.*]]
327 ; CHECK-NEXT: ret i1 [[RES_2]]
329 %add.1 = add nsw nuw i8 %a, 1
330 %cmp.1 = icmp ule i8 %add.1, %b
331 call void @llvm.assume(i1 %cmp.1)
332 %t.1 = icmp ule i8 %add.1, %b
333 %t.2 = icmp ule i8 %a, %b
334 %res.1 = xor i1 %t.1, %t.2
335 %add.2 = add nsw nuw i8 %a, 2
336 %c.1 = icmp ule i8 %add.2, %b
337 %res.2 = xor i1 %res.1, %c.1
345 ; TODO: Keep track of position of assume and may unwinding calls, simplify
346 ; conditions if possible.
347 define i1 @assume_same_bb_after_may_exiting_call(i8 %a, i8 %b, i1 %c) {
348 ; CHECK-LABEL: @assume_same_bb_after_may_exiting_call(
349 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
350 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
351 ; CHECK-NEXT: call void @may_unwind()
352 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
353 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
354 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
355 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
356 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
357 ; CHECK-NEXT: br label [[EXIT:%.*]]
359 ; CHECK-NEXT: ret i1 [[RES_2]]
361 %add.1 = add nsw nuw i8 %a, 1
362 %cmp.1 = icmp ule i8 %add.1, %b
363 call void @may_unwind()
364 call void @llvm.assume(i1 %cmp.1)
365 %t.1 = icmp ule i8 %add.1, %b
366 %t.2 = icmp ule i8 %a, %b
367 %res.1 = xor i1 %t.1, %t.2
368 %add.2 = add nsw nuw i8 %a, 2
369 %c.1 = icmp ule i8 %add.2, %b
370 %res.2 = xor i1 %res.1, %c.1
377 ; TODO: Keep track of position of assume and may unwinding calls, simplify
378 ; conditions if possible.
379 define i1 @assume_same_bb_before_may_exiting_call(i8 %a, i8 %b, i1 %c) {
380 ; CHECK-LABEL: @assume_same_bb_before_may_exiting_call(
381 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
382 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
383 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
384 ; CHECK-NEXT: call void @may_unwind()
385 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
386 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
387 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
388 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
389 ; CHECK-NEXT: br label [[EXIT:%.*]]
391 ; CHECK-NEXT: ret i1 [[RES_2]]
393 %add.1 = add nsw nuw i8 %a, 1
394 %cmp.1 = icmp ule i8 %add.1, %b
395 call void @llvm.assume(i1 %cmp.1)
396 call void @may_unwind()
397 %t.1 = icmp ule i8 %add.1, %b
398 %t.2 = icmp ule i8 %a, %b
399 %res.1 = xor i1 %t.1, %t.2
400 %add.2 = add nsw nuw i8 %a, 2
401 %c.1 = icmp ule i8 %add.2, %b
402 %res.2 = xor i1 %res.1, %c.1
409 define i1 @assume_same_bb_after_condition(i8 %a, i8 %b, i1 %c) {
410 ; CHECK-LABEL: @assume_same_bb_after_condition(
411 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
412 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
413 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
414 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B:%.*]]
415 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
416 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
417 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
418 ; CHECK-NEXT: br label [[EXIT:%.*]]
420 ; CHECK-NEXT: ret i1 [[RES_2]]
422 %add.1 = add nsw nuw i8 %a, 1
423 %t.1 = icmp ule i8 %add.1, %b
424 %t.2 = icmp ule i8 %a, %b
425 %res.1 = xor i1 %t.1, %t.2
426 %add.2 = add nsw nuw i8 %a, 2
427 %c.1 = icmp ule i8 %add.2, %b
428 %res.2 = xor i1 %res.1, %c.1
429 %cmp.1 = icmp ule i8 %add.1, %b
430 call void @llvm.assume(i1 %cmp.1)
437 ; The function may exit before the assume if @may_unwind unwinds. Conditions
438 ; before the call cannot be simplified.
439 define i1 @assume_same_bb_after_condition_may_unwind_between(i8 %a, i8 %b, i1 %c) {
440 ; CHECK-LABEL: @assume_same_bb_after_condition_may_unwind_between(
441 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
442 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
443 ; CHECK-NEXT: call void @use(i1 [[C_1]])
444 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[A]], [[B]]
445 ; CHECK-NEXT: call void @use(i1 [[C_2]])
446 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
447 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
448 ; CHECK-NEXT: [[C_3:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
449 ; CHECK-NEXT: call void @use(i1 [[C_3]])
450 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_3]]
451 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
452 ; CHECK-NEXT: call void @may_unwind()
453 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
454 ; CHECK-NEXT: br label [[EXIT:%.*]]
456 ; CHECK-NEXT: ret i1 [[RES_2]]
458 %add.1 = add nsw nuw i8 %a, 1
459 %c.1 = icmp ule i8 %add.1, %b
460 call void @use(i1 %c.1)
461 %c.2 = icmp ule i8 %a, %b
462 call void @use(i1 %c.2)
463 %res.1 = xor i1 %c.1, %c.2
464 %add.2 = add nsw nuw i8 %a, 2
465 %c.3 = icmp ule i8 %add.2, %b
466 call void @use(i1 %c.3)
467 %res.2 = xor i1 %res.1, %c.3
468 %cmp.1 = icmp ule i8 %add.1, %b
469 call void @may_unwind()
470 call void @llvm.assume(i1 %cmp.1)
477 ; The information of from the assume can be used to simplify %t.2.
478 define i1 @assume_single_bb_conditions_after_assume(i8 %a, i8 %b, i1 %c) {
479 ; CHECK-LABEL: @assume_single_bb_conditions_after_assume(
480 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
481 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
482 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
483 ; CHECK-NEXT: call void @use(i1 [[C_1]])
484 ; CHECK-NEXT: call void @may_unwind()
485 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
486 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
487 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
488 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
489 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
490 ; CHECK-NEXT: ret i1 [[RES_2]]
492 %add.1 = add nsw nuw i8 %a, 1
493 %cmp.1 = icmp ule i8 %add.1, %b
494 %c.1 = icmp ule i8 %add.1, %b
495 call void @use(i1 %c.1)
497 call void @may_unwind()
498 call void @llvm.assume(i1 %cmp.1)
499 %t.2 = icmp ule i8 %a, %b
500 %res.1 = xor i1 %c.1, %t.2
501 %add.2 = add nsw nuw i8 %a, 2
502 %c.2 = icmp ule i8 %add.2, %b
503 %res.2 = xor i1 %res.1, %c.2
507 ; The information of from the assume can be used to simplify %t.2.
509 define i1 @assume_single_bb_assume_at_end_after_may_unwind(i8 %a, i8 %b, i1 %c) {
510 ; CHECK-LABEL: @assume_single_bb_assume_at_end_after_may_unwind(
511 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
512 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
513 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
514 ; CHECK-NEXT: call void @use(i1 [[C_1]])
515 ; CHECK-NEXT: call void @may_unwind()
516 ; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
517 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[T_2]]
518 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
519 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
520 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
521 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
522 ; CHECK-NEXT: ret i1 [[RES_2]]
524 %add.1 = add nsw nuw i8 %a, 1
525 %cmp.1 = icmp ule i8 %add.1, %b
526 %c.1 = icmp ule i8 %add.1, %b
527 call void @use(i1 %c.1)
529 call void @may_unwind()
530 %t.2 = icmp ule i8 %a, %b
531 %res.1 = xor i1 %c.1, %t.2
532 %add.2 = add nsw nuw i8 %a, 2
533 %c.2 = icmp ule i8 %add.2, %b
534 %res.2 = xor i1 %res.1, %c.2
535 call void @llvm.assume(i1 %cmp.1)
539 ; The definition of %t.2 is before the @llvm.assume call, but all uses are
540 ; after the call. %t.2 can be simplified.
542 define i1 @all_uses_after_assume(i8 %a, i8 %b, i1 %c) {
543 ; CHECK-LABEL: @all_uses_after_assume(
544 ; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
545 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
546 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
547 ; CHECK-NEXT: call void @use(i1 [[C_1]])
548 ; CHECK-NEXT: call void @may_unwind()
549 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
550 ; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
551 ; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
552 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
553 ; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
554 ; CHECK-NEXT: ret i1 [[RES_2]]
556 %add.1 = add nsw nuw i8 %a, 1
557 %cmp.1 = icmp ule i8 %add.1, %b
558 %c.1 = icmp ule i8 %add.1, %b
559 %t.2 = icmp ule i8 %a, %b
560 call void @use(i1 %c.1)
562 call void @may_unwind()
563 call void @llvm.assume(i1 %cmp.1)
564 %res.1 = xor i1 %c.1, %t.2
565 %add.2 = add nsw nuw i8 %a, 2
566 %c.2 = icmp ule i8 %add.2, %b
567 %res.2 = xor i1 %res.1, %c.2
571 define i1 @test_order_assume_and_conds_in_different_bb(i16 %a, ptr %dst) {
572 ; CHECK-LABEL: @test_order_assume_and_conds_in_different_bb(
574 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[A:%.*]], 10
575 ; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
577 ; CHECK-NEXT: ret i1 false
579 ; CHECK-NEXT: store volatile float 0.000000e+00, ptr [[DST:%.*]], align 4
580 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i16 [[A]], 20
581 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_2]])
582 ; CHECK-NEXT: ret i1 true
585 %c.1 = icmp ult i16 %a, 10
586 br i1 %c.1, label %then, label %else
592 store volatile float 0.000000e+00, ptr %dst
593 %c.2 = icmp eq i16 %a, 20
594 tail call void @llvm.assume(i1 %c.2)