Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / assumes.ll
blob5ec231fab15d6f7eb0f5bc782a5b305136d86799
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()
8 declare void @use(i1)
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:%.*]]
16 ; CHECK:       then:
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]]
22 ; CHECK:       else:
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
34 then:
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
41   ret i1 %res.2
43 else:
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
50   ret i1 %res.4
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:%.*]]
60 ; CHECK:       then:
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]]
66 ; CHECK:       else:
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
79 then:
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
86   ret i1 %res.2
88 else:
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
95   ret i1 %res.4
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:%.*]]
105 ; CHECK:       then:
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]]
111 ; CHECK:       else:
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
124 then:
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
131   ret i1 %res.2
133 else:
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
140   ret i1 %res.4
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(
146 ; CHECK-NEXT:  entry:
147 ; CHECK-NEXT:    br i1 [[I_0:%.*]], label [[EXIT:%.*]], label [[IF_THEN:%.*]]
148 ; CHECK:       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]]
153 ; CHECK:       exit:
154 ; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i16 [[A]], 0
155 ; CHECK-NEXT:    ret i1 [[C_2]]
157 entry:
158   br i1 %i.0, label %exit, label %if.then
160 if.then:
161   call void @may_unwind()
162   %c.1 = icmp eq i16 %a, 0
163   call void @llvm.assume(i1 %c.1)
164   br label %exit
166 exit:
167   %c.2 = icmp eq i16 %a, 0
168   ret i1 %c.2
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(
173 ; CHECK-NEXT:  entry:
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:%.*]]
178 ; CHECK:       exit:
179 ; CHECK-NEXT:    ret i1 true
181 entry:
182   call void @may_unwind()
183   %c.1 = icmp eq i16 %a, 0
184   call void @llvm.assume(i1 %c.1)
185   br label %exit
187 exit:
188   %c.2 = icmp eq i16 %a, 0
189   ret i1 %c.2
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(
194 ; CHECK-NEXT:  entry:
195 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
196 ; CHECK:       then:
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]]
201 ; CHECK:       exit:
202 ; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i16 [[A]], 0
203 ; CHECK-NEXT:    ret i1 [[C_2]]
205 entry:
206   br i1 %c, label %then, label %exit
208 then:
209   call void @may_unwind()
210   %c.1 = icmp eq i16 %a, 0
211   call void @llvm.assume(i1 %c.1)
212   br label %exit
214 exit:
215   %c.2 = icmp eq i16 %a, 0
216   ret i1 %c.2
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(
221 ; CHECK-NEXT:  entry:
222 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
223 ; CHECK:       then:
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]]
229 ; CHECK:       exit:
230 ; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i16 [[A]], 0
231 ; CHECK-NEXT:    ret i1 [[C_2]]
233 entry:
234   br i1 %c, label %then, label %exit
236 then:
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)
241   br label %then
243 exit:
244   %c.2 = icmp eq i16 %a, 0
245   ret i1 %c.2
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
268   ret i1 %res.2
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:%.*]]
276 ; CHECK:       then:
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]]
283 ; CHECK:       else:
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
296 then:
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
304   ret i1 %res.2
306 else:
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
313   ret i1 %res.4
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:%.*]]
326 ; CHECK:       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
338   br label %exit
340 exit:
341   ret i1 %res.2
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:%.*]]
358 ; CHECK:       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
371   br label %exit
373 exit:
374   ret i1 %res.2
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:%.*]]
390 ; CHECK:       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
403   br label %exit
405 exit:
406   ret i1 %res.2
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:%.*]]
419 ; CHECK:       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)
431   br label %exit
433 exit:
434   ret i1 %res.2
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:%.*]]
455 ; CHECK:       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)
471   br label %exit
473 exit:
474   ret i1 %res.2
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
504   ret i1 %res.2
507 ; The information of from the assume can be used to simplify %t.2.
508 ; TODO
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)
536   ret i1 %res.2
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.
541 ; TODO
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
568   ret i1 %res.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(
573 ; CHECK-NEXT:  entry:
574 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[A:%.*]], 10
575 ; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
576 ; CHECK:       then:
577 ; CHECK-NEXT:    ret i1 false
578 ; CHECK:       else:
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
584 entry:
585   %c.1 = icmp ult i16 %a, 10
586   br i1 %c.1, label %then, label %else
588 then:
589   ret i1 0
591 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)
595   ret i1 %c.2