xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/assumes.ll (revision 13ffde316a8541d77116bd18f73efada236617f3)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4declare void @llvm.assume(i1)
5
6declare void @may_unwind()
7
8declare void @use(i1)
9
10define 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]]
28;
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
33
34then:
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
42
43else:
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
51}
52
53define 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]]
72;
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
78
79then:
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
87
88else:
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
96}
97
98define 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]]
117;
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
123
124then:
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
132
133else:
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
141}
142
143; Test case from PR54217.
144define 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]]
156;
157entry:
158  br i1 %i.0, label %exit, label %if.then
159
160if.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
165
166exit:
167  %c.2 = icmp eq i16 %a, 0
168  ret i1 %c.2
169}
170
171define 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
180;
181entry:
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
186
187exit:
188  %c.2 = icmp eq i16 %a, 0
189  ret i1 %c.2
190}
191
192define 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]]
204;
205entry:
206  br i1 %c, label %then, label %exit
207
208then:
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
213
214exit:
215  %c.2 = icmp eq i16 %a, 0
216  ret i1 %c.2
217}
218
219define 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]]
232;
233entry:
234  br i1 %c, label %then, label %exit
235
236then:
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
242
243exit:
244  %c.2 = icmp eq i16 %a, 0
245  ret i1 %c.2
246}
247
248define 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]]
258;
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
269}
270
271define 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]]
291;
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
295
296then:
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
305
306else:
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
314}
315
316define 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]]
328;
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
339
340exit:
341  ret i1 %res.2
342}
343
344
345; TODO: Keep track of position of assume and may unwinding calls, simplify
346; conditions if possible.
347define 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]]
360;
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
372
373exit:
374  ret i1 %res.2
375}
376
377; TODO: Keep track of position of assume and may unwinding calls, simplify
378; conditions if possible.
379define 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]]
392;
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
404
405exit:
406  ret i1 %res.2
407}
408
409define 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]]
421;
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
432
433exit:
434  ret i1 %res.2
435}
436
437; The function may exit before the assume if @may_unwind unwinds. Conditions
438; before the call cannot be simplified.
439define 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]]
457;
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
472
473exit:
474  ret i1 %res.2
475}
476
477; The information of from the assume can be used to simplify %t.2.
478define 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]]
491;
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)
496
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
505}
506
507; The information of from the assume can be used to simplify %t.2.
508; TODO
509define 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]]
523;
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)
528
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
537}
538
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
542define 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]]
555;
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)
561
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
569}
570
571define 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
583;
584entry:
585  %c.1 = icmp ult i16 %a, 10
586  br i1 %c.1, label %then, label %else
587
588then:
589  ret i1 0
590
591else:
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
596}
597