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: [[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]]
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
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
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
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:%.*]]
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]]
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
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
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
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:%.*]]
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]]
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
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
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
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
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:%.*]]
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]]
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
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
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
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:%.*]]
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
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:%.*]]
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
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:%.*]]
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
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:%.*]]
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)
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:%.*]]
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)
396 ; The information of from the assume can be used to simplify %t.2.
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
428 ; The information of from the assume can be used to simplify %t.2.
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)
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.
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