[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / assumes.ll
blobf916798188ff8c8af02f45f600beb90a1aec0267
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:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
18 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
19 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
20 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
21 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
22 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
23 ; CHECK-NEXT:    ret i1 [[RES_2]]
24 ; CHECK:       else:
25 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
26 ; CHECK-NEXT:    [[T_4:%.*]] = icmp ule i8 [[A]], [[B]]
27 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 true, true
28 ; CHECK-NEXT:    [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
29 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
30 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
31 ; CHECK-NEXT:    ret i1 [[RES_4]]
33   %add.1 = add nsw nuw i8 %a, 1
34   %cmp.1 = icmp ule i8 %add.1, %b
35   call void @llvm.assume(i1 %cmp.1)
36   br i1 %c, label %then, label %else
38 then:
39   %t.1 = icmp ule i8 %add.1, %b
40   %t.2 = icmp ule i8 %a, %b
41   %res.1 = xor i1 %t.1, %t.2
42   %add.2 = add nsw nuw i8 %a, 2
43   %c.1 = icmp ule i8 %add.2, %b
44   %res.2 = xor i1 %res.1, %c.1
45   ret i1 %res.2
47 else:
48   %t.3 = icmp ule i8 %add.1, %b
49   %t.4 = icmp ule i8 %a, %b
50   %res.3 = xor i1 %t.3, %t.4
51   %add.2.1 = add nsw nuw i8 %a, 2
52   %c.2 = icmp ule i8 %add.2.1, %b
53   %res.4 = xor i1 %res.3, %c.2
54   ret i1 %res.4
57 define i1 @assume_dominates_with_may_unwind_call_before_assume(i8 %a, i8 %b, i1 %c) {
58 ; CHECK-LABEL: @assume_dominates_with_may_unwind_call_before_assume(
59 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
60 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
61 ; CHECK-NEXT:    call void @may_unwind()
62 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
63 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
64 ; CHECK:       then:
65 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
66 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
67 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
68 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
69 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
70 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
71 ; CHECK-NEXT:    ret i1 [[RES_2]]
72 ; CHECK:       else:
73 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
74 ; CHECK-NEXT:    [[T_4:%.*]] = icmp ule i8 [[A]], [[B]]
75 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 true, true
76 ; CHECK-NEXT:    [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
77 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
78 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
79 ; CHECK-NEXT:    ret i1 [[RES_4]]
81   %add.1 = add nsw nuw i8 %a, 1
82   %cmp.1 = icmp ule i8 %add.1, %b
83   call void @may_unwind()
84   call void @llvm.assume(i1 %cmp.1)
85   br i1 %c, label %then, label %else
87 then:
88   %t.1 = icmp ule i8 %add.1, %b
89   %t.2 = icmp ule i8 %a, %b
90   %res.1 = xor i1 %t.1, %t.2
91   %add.2 = add nsw nuw i8 %a, 2
92   %c.1 = icmp ule i8 %add.2, %b
93   %res.2 = xor i1 %res.1, %c.1
94   ret i1 %res.2
96 else:
97   %t.3 = icmp ule i8 %add.1, %b
98   %t.4 = icmp ule i8 %a, %b
99   %res.3 = xor i1 %t.3, %t.4
100   %add.2.1 = add nsw nuw i8 %a, 2
101   %c.2 = icmp ule i8 %add.2.1, %b
102   %res.4 = xor i1 %res.3, %c.2
103   ret i1 %res.4
106 define i1 @assume_dominates_with_may_unwind_call_after_assume(i8 %a, i8 %b, i1 %c) {
107 ; CHECK-LABEL: @assume_dominates_with_may_unwind_call_after_assume(
108 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
109 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
110 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
111 ; CHECK-NEXT:    call void @may_unwind()
112 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
113 ; CHECK:       then:
114 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
115 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
116 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
117 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
118 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
119 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
120 ; CHECK-NEXT:    ret i1 [[RES_2]]
121 ; CHECK:       else:
122 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
123 ; CHECK-NEXT:    [[T_4:%.*]] = icmp ule i8 [[A]], [[B]]
124 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 true, true
125 ; CHECK-NEXT:    [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
126 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
127 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
128 ; CHECK-NEXT:    ret i1 [[RES_4]]
130   %add.1 = add nsw nuw i8 %a, 1
131   %cmp.1 = icmp ule i8 %add.1, %b
132   call void @llvm.assume(i1 %cmp.1)
133   call void @may_unwind()
134   br i1 %c, label %then, label %else
136 then:
137   %t.1 = icmp ule i8 %add.1, %b
138   %t.2 = icmp ule i8 %a, %b
139   %res.1 = xor i1 %t.1, %t.2
140   %add.2 = add nsw nuw i8 %a, 2
141   %c.1 = icmp ule i8 %add.2, %b
142   %res.2 = xor i1 %res.1, %c.1
143   ret i1 %res.2
145 else:
146   %t.3 = icmp ule i8 %add.1, %b
147   %t.4 = icmp ule i8 %a, %b
148   %res.3 = xor i1 %t.3, %t.4
149   %add.2.1 = add nsw nuw i8 %a, 2
150   %c.2 = icmp ule i8 %add.2.1, %b
151   %res.4 = xor i1 %res.3, %c.2
152   ret i1 %res.4
155 define i1 @assume_single_bb(i8 %a, i8 %b, i1 %c) {
156 ; CHECK-LABEL: @assume_single_bb(
157 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
158 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
159 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
160 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
161 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
162 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
163 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
164 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
165 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
166 ; CHECK-NEXT:    ret i1 [[RES_2]]
168   %add.1 = add nsw nuw i8 %a, 1
169   %cmp.1 = icmp ule i8 %add.1, %b
170   call void @llvm.assume(i1 %cmp.1)
171   %t.1 = icmp ule i8 %add.1, %b
172   %t.2 = icmp ule i8 %a, %b
173   %res.1 = xor i1 %t.1, %t.2
174   %add.2 = add nsw nuw i8 %a, 2
175   %c.1 = icmp ule i8 %add.2, %b
176   %res.2 = xor i1 %res.1, %c.1
177   ret i1 %res.2
180 define i1 @assume_same_bb(i8 %a, i8 %b, i1 %c) {
181 ; CHECK-LABEL: @assume_same_bb(
182 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
183 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
184 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
185 ; CHECK:       then:
186 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
187 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
188 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
189 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
190 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
191 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
192 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
193 ; CHECK-NEXT:    ret i1 [[RES_2]]
194 ; CHECK:       else:
195 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
196 ; CHECK-NEXT:    [[T_4:%.*]] = icmp ule i8 [[A]], [[B]]
197 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[T_3]], [[T_4]]
198 ; CHECK-NEXT:    [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
199 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
200 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
201 ; CHECK-NEXT:    ret i1 [[RES_4]]
203   %add.1 = add nsw nuw i8 %a, 1
204   %cmp.1 = icmp ule i8 %add.1, %b
205   br i1 %c, label %then, label %else
207 then:
208   call void @llvm.assume(i1 %cmp.1)
209   %t.1 = icmp ule i8 %add.1, %b
210   %t.2 = icmp ule i8 %a, %b
211   %res.1 = xor i1 %t.1, %t.2
212   %add.2 = add nsw nuw i8 %a, 2
213   %c.1 = icmp ule i8 %add.2, %b
214   %res.2 = xor i1 %res.1, %c.1
215   ret i1 %res.2
217 else:
218   %t.3 = icmp ule i8 %add.1, %b
219   %t.4 = icmp ule i8 %a, %b
220   %res.3 = xor i1 %t.3, %t.4
221   %add.2.1 = add nsw nuw i8 %a, 2
222   %c.2 = icmp ule i8 %add.2.1, %b
223   %res.4 = xor i1 %res.3, %c.2
224   ret i1 %res.4
227 define i1 @assume_same_bb2(i8 %a, i8 %b, i1 %c) {
228 ; CHECK-LABEL: @assume_same_bb2(
229 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
230 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
231 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
232 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
233 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
234 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
235 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
236 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
237 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
238 ; CHECK-NEXT:    br label [[EXIT:%.*]]
239 ; CHECK:       exit:
240 ; CHECK-NEXT:    ret i1 [[RES_2]]
242   %add.1 = add nsw nuw i8 %a, 1
243   %cmp.1 = icmp ule i8 %add.1, %b
244   call void @llvm.assume(i1 %cmp.1)
245   %t.1 = icmp ule i8 %add.1, %b
246   %t.2 = icmp ule i8 %a, %b
247   %res.1 = xor i1 %t.1, %t.2
248   %add.2 = add nsw nuw i8 %a, 2
249   %c.1 = icmp ule i8 %add.2, %b
250   %res.2 = xor i1 %res.1, %c.1
251   br label %exit
253 exit:
254   ret i1 %res.2
258 ; TODO: Keep track of position of assume and may unwinding calls, simplify
259 ; conditions if possible.
260 define i1 @assume_same_bb_after_may_exiting_call(i8 %a, i8 %b, i1 %c) {
261 ; CHECK-LABEL: @assume_same_bb_after_may_exiting_call(
262 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
263 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
264 ; CHECK-NEXT:    call void @may_unwind()
265 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
266 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
267 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
268 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[T_1]], [[T_2]]
269 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
270 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
271 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
272 ; CHECK-NEXT:    br label [[EXIT:%.*]]
273 ; CHECK:       exit:
274 ; CHECK-NEXT:    ret i1 [[RES_2]]
276   %add.1 = add nsw nuw i8 %a, 1
277   %cmp.1 = icmp ule i8 %add.1, %b
278   call void @may_unwind()
279   call void @llvm.assume(i1 %cmp.1)
280   %t.1 = icmp ule i8 %add.1, %b
281   %t.2 = icmp ule i8 %a, %b
282   %res.1 = xor i1 %t.1, %t.2
283   %add.2 = add nsw nuw i8 %a, 2
284   %c.1 = icmp ule i8 %add.2, %b
285   %res.2 = xor i1 %res.1, %c.1
286   br label %exit
288 exit:
289   ret i1 %res.2
292 ; TODO: Keep track of position of assume and may unwinding calls, simplify
293 ; conditions if possible.
294 define i1 @assume_same_bb_before_may_exiting_call(i8 %a, i8 %b, i1 %c) {
295 ; CHECK-LABEL: @assume_same_bb_before_may_exiting_call(
296 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
297 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
298 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
299 ; CHECK-NEXT:    call void @may_unwind()
300 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
301 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
302 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
303 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
304 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
305 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
306 ; CHECK-NEXT:    br label [[EXIT:%.*]]
307 ; CHECK:       exit:
308 ; CHECK-NEXT:    ret i1 [[RES_2]]
310   %add.1 = add nsw nuw i8 %a, 1
311   %cmp.1 = icmp ule i8 %add.1, %b
312   call void @llvm.assume(i1 %cmp.1)
313   call void @may_unwind()
314   %t.1 = icmp ule i8 %add.1, %b
315   %t.2 = icmp ule i8 %a, %b
316   %res.1 = xor i1 %t.1, %t.2
317   %add.2 = add nsw nuw i8 %a, 2
318   %c.1 = icmp ule i8 %add.2, %b
319   %res.2 = xor i1 %res.1, %c.1
320   br label %exit
322 exit:
323   ret i1 %res.2
326 define i1 @assume_same_bb_after_condition(i8 %a, i8 %b, i1 %c) {
327 ; CHECK-LABEL: @assume_same_bb_after_condition(
328 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
329 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
330 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
331 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
332 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
333 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
334 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
335 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
336 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
337 ; CHECK-NEXT:    br label [[EXIT:%.*]]
338 ; CHECK:       exit:
339 ; CHECK-NEXT:    ret i1 [[RES_2]]
341   %add.1 = add nsw nuw i8 %a, 1
342   %t.1 = icmp ule i8 %add.1, %b
343   %t.2 = icmp ule i8 %a, %b
344   %res.1 = xor i1 %t.1, %t.2
345   %add.2 = add nsw nuw i8 %a, 2
346   %c.1 = icmp ule i8 %add.2, %b
347   %res.2 = xor i1 %res.1, %c.1
348   %cmp.1 = icmp ule i8 %add.1, %b
349   call void @llvm.assume(i1 %cmp.1)
350   br label %exit
352 exit:
353   ret i1 %res.2
356 ; The function may exit before the assume if @may_unwind unwinds. Conditions
357 ; before the call cannot be simplified.
358 define i1 @assume_same_bb_after_condition_may_unwind_between(i8 %a, i8 %b, i1 %c) {
359 ; CHECK-LABEL: @assume_same_bb_after_condition_may_unwind_between(
360 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
361 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
362 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
363 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[A]], [[B]]
364 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
365 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
366 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
367 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
368 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
369 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_3]]
370 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
371 ; CHECK-NEXT:    call void @may_unwind()
372 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
373 ; CHECK-NEXT:    br label [[EXIT:%.*]]
374 ; CHECK:       exit:
375 ; CHECK-NEXT:    ret i1 [[RES_2]]
377   %add.1 = add nsw nuw i8 %a, 1
378   %c.1 = icmp ule i8 %add.1, %b
379   call void @use(i1 %c.1)
380   %c.2 = icmp ule i8 %a, %b
381   call void @use(i1 %c.2)
382   %res.1 = xor i1 %c.1, %c.2
383   %add.2 = add nsw nuw i8 %a, 2
384   %c.3 = icmp ule i8 %add.2, %b
385   call void @use(i1 %c.3)
386   %res.2 = xor i1 %res.1, %c.3
387   %cmp.1 = icmp ule i8 %add.1, %b
388   call void @may_unwind()
389   call void @llvm.assume(i1 %cmp.1)
390   br label %exit
392 exit:
393   ret i1 %res.2
396 ; The information of from the assume can be used to simplify %t.2.
397 ; TODO
398 define i1 @assume_single_bb_conditions_after_assume(i8 %a, i8 %b, i1 %c) {
399 ; CHECK-LABEL: @assume_single_bb_conditions_after_assume(
400 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
401 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
402 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
403 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
404 ; CHECK-NEXT:    call void @may_unwind()
405 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
406 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
407 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[T_2]]
408 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
409 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
410 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
411 ; CHECK-NEXT:    ret i1 [[RES_2]]
413   %add.1 = add nsw nuw i8 %a, 1
414   %cmp.1 = icmp ule i8 %add.1, %b
415   %c.1 = icmp ule i8 %add.1, %b
416   call void @use(i1 %c.1)
418   call void @may_unwind()
419   call void @llvm.assume(i1 %cmp.1)
420   %t.2 = icmp ule i8 %a, %b
421   %res.1 = xor i1 %c.1, %t.2
422   %add.2 = add nsw nuw i8 %a, 2
423   %c.2 = icmp ule i8 %add.2, %b
424   %res.2 = xor i1 %res.1, %c.2
425   ret i1 %res.2
428 ; The information of from the assume can be used to simplify %t.2.
429 ; TODO
430 define i1 @assume_single_bb_assume_at_end_after_may_unwind(i8 %a, i8 %b, i1 %c) {
431 ; CHECK-LABEL: @assume_single_bb_assume_at_end_after_may_unwind(
432 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
433 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
434 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
435 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
436 ; CHECK-NEXT:    call void @may_unwind()
437 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
438 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[T_2]]
439 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
440 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
441 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
442 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
443 ; CHECK-NEXT:    ret i1 [[RES_2]]
445   %add.1 = add nsw nuw i8 %a, 1
446   %cmp.1 = icmp ule i8 %add.1, %b
447   %c.1 = icmp ule i8 %add.1, %b
448   call void @use(i1 %c.1)
450   call void @may_unwind()
451   %t.2 = icmp ule i8 %a, %b
452   %res.1 = xor i1 %c.1, %t.2
453   %add.2 = add nsw nuw i8 %a, 2
454   %c.2 = icmp ule i8 %add.2, %b
455   %res.2 = xor i1 %res.1, %c.2
456   call void @llvm.assume(i1 %cmp.1)
457   ret i1 %res.2
460 ; The definition of %t.2 is before the @llvm.assume call, but all uses are
461 ; after the call. %t.2 can be simplified.
462 ; TODO
463 define i1 @all_uses_after_assume(i8 %a, i8 %b, i1 %c) {
464 ; CHECK-LABEL: @all_uses_after_assume(
465 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
466 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
467 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
468 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
469 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
470 ; CHECK-NEXT:    call void @may_unwind()
471 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_1]])
472 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[T_2]]
473 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
474 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
475 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
476 ; CHECK-NEXT:    ret i1 [[RES_2]]
478   %add.1 = add nsw nuw i8 %a, 1
479   %cmp.1 = icmp ule i8 %add.1, %b
480   %c.1 = icmp ule i8 %add.1, %b
481   %t.2 = icmp ule i8 %a, %b
482   call void @use(i1 %c.1)
484   call void @may_unwind()
485   call void @llvm.assume(i1 %cmp.1)
486   %res.1 = xor i1 %c.1, %t.2
487   %add.2 = add nsw nuw i8 %a, 2
488   %c.2 = icmp ule i8 %add.2, %b
489   %res.2 = xor i1 %res.1, %c.2
490   ret i1 %res.2