1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
5 define i1 @umax_ugt(i32 %x, i32 %y) {
6 ; CHECK-LABEL: define i1 @umax_ugt
7 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
8 ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)
9 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y]], [[MAX]]
10 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
12 ; CHECK-NEXT: [[RET:%.*]] = xor i1 true, true
13 ; CHECK-NEXT: ret i1 [[RET]]
15 ; CHECK-NEXT: ret i1 false
17 %max = call i32 @llvm.umax.i32(i32 %x, i32 1)
18 %cmp = icmp ugt i32 %y, %max
19 br i1 %cmp, label %if, label %end
22 %cmp2 = icmp ugt i32 %y, %x
23 %cmp3 = icmp uge i32 %y, %x
24 %ret = xor i1 %cmp2, %cmp3
31 define i1 @umax_uge(i32 %x, i32 %y) {
32 ; CHECK-LABEL: define i1 @umax_uge
33 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
34 ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)
35 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[Y]], [[MAX]]
36 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
38 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y]], [[X]]
39 ; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP2]], true
40 ; CHECK-NEXT: ret i1 [[RET]]
42 ; CHECK-NEXT: ret i1 false
44 %max = call i32 @llvm.umax.i32(i32 %x, i32 1)
45 %cmp = icmp uge i32 %y, %max
46 br i1 %cmp, label %if, label %end
49 %cmp2 = icmp ugt i32 %y, %x
50 %cmp3 = icmp uge i32 %y, %x
51 %ret = xor i1 %cmp2, %cmp3
58 define i1 @umin_ult(i32 %x, i32 %y) {
59 ; CHECK-LABEL: define i1 @umin_ult
60 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
61 ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 1)
62 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[Y]], [[MIN]]
63 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
65 ; CHECK-NEXT: [[RET:%.*]] = xor i1 true, true
66 ; CHECK-NEXT: ret i1 [[RET]]
68 ; CHECK-NEXT: ret i1 false
70 %min = call i32 @llvm.umin.i32(i32 %x, i32 1)
71 %cmp = icmp ult i32 %y, %min
72 br i1 %cmp, label %if, label %end
75 %cmp2 = icmp ult i32 %y, %x
76 %cmp3 = icmp ule i32 %y, %x
77 %ret = xor i1 %cmp2, %cmp3
84 define i1 @umin_ule(i32 %x, i32 %y) {
85 ; CHECK-LABEL: define i1 @umin_ule
86 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
87 ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 1)
88 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[Y]], [[MIN]]
89 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
91 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y]], [[X]]
92 ; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP2]], true
93 ; CHECK-NEXT: ret i1 [[RET]]
95 ; CHECK-NEXT: ret i1 false
97 %min = call i32 @llvm.umin.i32(i32 %x, i32 1)
98 %cmp = icmp ule i32 %y, %min
99 br i1 %cmp, label %if, label %end
102 %cmp2 = icmp ult i32 %y, %x
103 %cmp3 = icmp ule i32 %y, %x
104 %ret = xor i1 %cmp2, %cmp3
111 define i1 @smax_sgt(i32 %x, i32 %y) {
112 ; CHECK-LABEL: define i1 @smax_sgt
113 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
114 ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 1)
115 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[Y]], [[MAX]]
116 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
118 ; CHECK-NEXT: [[RET:%.*]] = xor i1 true, true
119 ; CHECK-NEXT: ret i1 [[RET]]
121 ; CHECK-NEXT: ret i1 false
123 %max = call i32 @llvm.smax.i32(i32 %x, i32 1)
124 %cmp = icmp sgt i32 %y, %max
125 br i1 %cmp, label %if, label %end
128 %cmp2 = icmp sgt i32 %y, %x
129 %cmp3 = icmp sge i32 %y, %x
130 %ret = xor i1 %cmp2, %cmp3
137 define i1 @smax_sge(i32 %x, i32 %y) {
138 ; CHECK-LABEL: define i1 @smax_sge
139 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
140 ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 1)
141 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[Y]], [[MAX]]
142 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
144 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[Y]], [[X]]
145 ; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP2]], true
146 ; CHECK-NEXT: ret i1 [[RET]]
148 ; CHECK-NEXT: ret i1 false
150 %max = call i32 @llvm.smax.i32(i32 %x, i32 1)
151 %cmp = icmp sge i32 %y, %max
152 br i1 %cmp, label %if, label %end
155 %cmp2 = icmp sgt i32 %y, %x
156 %cmp3 = icmp sge i32 %y, %x
157 %ret = xor i1 %cmp2, %cmp3
164 define i1 @smin_slt(i32 %x, i32 %y) {
165 ; CHECK-LABEL: define i1 @smin_slt
166 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
167 ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 1)
168 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], [[MIN]]
169 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
171 ; CHECK-NEXT: [[RET:%.*]] = xor i1 true, true
172 ; CHECK-NEXT: ret i1 [[RET]]
174 ; CHECK-NEXT: ret i1 false
176 %min = call i32 @llvm.smin.i32(i32 %x, i32 1)
177 %cmp = icmp slt i32 %y, %min
178 br i1 %cmp, label %if, label %end
181 %cmp2 = icmp slt i32 %y, %x
182 %cmp3 = icmp sle i32 %y, %x
183 %ret = xor i1 %cmp2, %cmp3
190 define i1 @smin_sle(i32 %x, i32 %y) {
191 ; CHECK-LABEL: define i1 @smin_sle
192 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
193 ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 1)
194 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[Y]], [[MIN]]
195 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
197 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[Y]], [[X]]
198 ; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP2]], true
199 ; CHECK-NEXT: ret i1 [[RET]]
201 ; CHECK-NEXT: ret i1 false
203 %min = call i32 @llvm.smin.i32(i32 %x, i32 1)
204 %cmp = icmp sle i32 %y, %min
205 br i1 %cmp, label %if, label %end
208 %cmp2 = icmp slt i32 %y, %x
209 %cmp3 = icmp sle i32 %y, %x
210 %ret = xor i1 %cmp2, %cmp3
217 define i1 @umax_uge_ugt_with_add_nuw(i32 %x, i32 %y) {
218 ; CHECK-LABEL: define i1 @umax_uge_ugt_with_add_nuw
219 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
220 ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)
221 ; CHECK-NEXT: [[SUM:%.*]] = add nuw i32 [[MAX]], 1
222 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[Y]], [[SUM]]
223 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
225 ; CHECK-NEXT: ret i1 true
227 ; CHECK-NEXT: ret i1 false
229 %max = call i32 @llvm.umax.i32(i32 %x, i32 1)
230 %sum = add nuw i32 %max, 1
231 %cmp = icmp uge i32 %y, %sum
232 br i1 %cmp, label %if, label %end
235 %cmp2 = icmp ugt i32 %y, %x
242 define i1 @smin_ule_mixed(i32 %x, i32 %y) {
243 ; CHECK-LABEL: define i1 @smin_ule_mixed
244 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
245 ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 1)
246 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[Y]], [[MIN]]
247 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
249 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[Y]], [[X]]
250 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sle i32 [[Y]], [[X]]
251 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[Y]], [[X]]
252 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ule i32 [[Y]], [[X]]
253 ; CHECK-NEXT: [[XOR1:%.*]] = xor i1 [[CMP2]], [[CMP3]]
254 ; CHECK-NEXT: [[XOR2:%.*]] = xor i1 [[CMP4]], [[CMP5]]
255 ; CHECK-NEXT: [[RET:%.*]] = xor i1 [[XOR1]], [[XOR2]]
256 ; CHECK-NEXT: ret i1 [[RET]]
258 ; CHECK-NEXT: ret i1 false
260 %min = call i32 @llvm.smin.i32(i32 %x, i32 1)
261 %cmp = icmp ule i32 %y, %min
262 br i1 %cmp, label %if, label %end
265 %cmp2 = icmp slt i32 %y, %x
266 %cmp3 = icmp sle i32 %y, %x
267 %cmp4 = icmp ult i32 %y, %x
268 %cmp5 = icmp ule i32 %y, %x
269 %xor1 = xor i1 %cmp2, %cmp3
270 %xor2 = xor i1 %cmp4, %cmp5
271 %ret = xor i1 %xor1, %xor2
278 define i1 @umax_ugt_ugt_both(i32 %x, i32 %y, i32 %z) {
279 ; CHECK-LABEL: define i1 @umax_ugt_ugt_both
280 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
281 ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]])
282 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Z]], [[MAX]]
283 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
285 ; CHECK-NEXT: [[AND:%.*]] = xor i1 true, true
286 ; CHECK-NEXT: ret i1 [[AND]]
288 ; CHECK-NEXT: ret i1 false
290 %max = call i32 @llvm.umax.i32(i32 %x, i32 %y)
291 %cmp = icmp ugt i32 %z, %max
292 br i1 %cmp, label %if, label %end
295 %cmp2 = icmp ugt i32 %z, %x
296 %cmp3 = icmp ugt i32 %z, %y
297 %and = xor i1 %cmp2, %cmp3
304 define i1 @smin_branchless(i32 %x, i32 %y) {
305 ; CHECK-LABEL: define i1 @smin_branchless
306 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
308 ; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 [[Y]])
309 ; CHECK-NEXT: [[RET:%.*]] = xor i1 true, false
310 ; CHECK-NEXT: ret i1 [[RET]]
313 %min = call i32 @llvm.smin.i32(i32 %x, i32 %y)
314 %cmp1 = icmp sle i32 %min, %x
315 %cmp2 = icmp sgt i32 %min, %x
316 %ret = xor i1 %cmp1, %cmp2
320 define i32 @simplify_smax(i32 %x, i32 %y, i32 %z) {
321 ; CHECK-LABEL: define i32 @simplify_smax
322 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
324 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], [[Y]]
325 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
327 ; CHECK-NEXT: [[MAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 [[Z]])
328 ; CHECK-NEXT: [[MAX2:%.*]] = call i32 @llvm.smax.i32(i32 [[Y]], i32 [[MAX1]])
329 ; CHECK-NEXT: ret i32 [[MAX2]]
331 ; CHECK-NEXT: ret i32 0
334 %cmp = icmp slt i32 %x, %y
335 br i1 %cmp, label %if, label %end
337 %max1 = call i32 @llvm.smax.i32(i32 %x, i32 %z)
338 %max2 = call i32 @llvm.smax.i32(i32 %y, i32 %max1)
344 declare i32 @llvm.smin.i32(i32, i32)
345 declare i32 @llvm.smax.i32(i32, i32)
346 declare i32 @llvm.umin.i32(i32, i32)
347 declare i32 @llvm.umax.i32(i32, i32)