1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 ; If we have a umax feeding an unsigned or equality icmp that shares an
5 ; operand with the umax, the compare should always be folded.
6 ; Test all 4 foldable predicates (eq,ne,ugt,ule) * 4 commutation
7 ; possibilities for each predicate. Note that folds to true/false
8 ; (predicate = uge/ult) or folds to an existing instruction should be
9 ; handled by InstSimplify.
11 ; umax(X, Y) == X --> X >= Y
13 define i1 @eq_umax1(i32 %x, i32 %y) {
14 ; CHECK-LABEL: @eq_umax1(
15 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
16 ; CHECK-NEXT: ret i1 [[CMP2]]
18 %cmp1 = icmp ugt i32 %x, %y
19 %sel = select i1 %cmp1, i32 %x, i32 %y
20 %cmp2 = icmp eq i32 %sel, %x
24 ; Commute max operands.
26 define i1 @eq_umax2(i32 %x, i32 %y) {
27 ; CHECK-LABEL: @eq_umax2(
28 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
29 ; CHECK-NEXT: ret i1 [[CMP2]]
31 %cmp1 = icmp ugt i32 %y, %x
32 %sel = select i1 %cmp1, i32 %y, i32 %x
33 %cmp2 = icmp eq i32 %sel, %x
37 ; Disguise the icmp predicate by commuting the max op to the RHS.
39 define i1 @eq_umax3(i32 %a, i32 %y) {
40 ; CHECK-LABEL: @eq_umax3(
41 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
42 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], [[Y:%.*]]
43 ; CHECK-NEXT: ret i1 [[CMP2]]
45 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
46 %cmp1 = icmp ugt i32 %x, %y
47 %sel = select i1 %cmp1, i32 %x, i32 %y
48 %cmp2 = icmp eq i32 %x, %sel
52 ; Commute max operands.
54 define i1 @eq_umax4(i32 %a, i32 %y) {
55 ; CHECK-LABEL: @eq_umax4(
56 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
57 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], [[Y:%.*]]
58 ; CHECK-NEXT: ret i1 [[CMP2]]
60 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
61 %cmp1 = icmp ugt i32 %y, %x
62 %sel = select i1 %cmp1, i32 %y, i32 %x
63 %cmp2 = icmp eq i32 %x, %sel
67 ; umax(X, Y) <= X --> Y <= X
69 define i1 @ule_umax1(i32 %x, i32 %y) {
70 ; CHECK-LABEL: @ule_umax1(
71 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[Y:%.*]], [[X:%.*]]
72 ; CHECK-NEXT: ret i1 [[CMP2]]
74 %cmp1 = icmp ugt i32 %x, %y
75 %sel = select i1 %cmp1, i32 %x, i32 %y
76 %cmp2 = icmp ule i32 %sel, %x
80 ; Commute max operands.
82 define i1 @ule_umax2(i32 %x, i32 %y) {
83 ; CHECK-LABEL: @ule_umax2(
84 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[Y:%.*]], [[X:%.*]]
85 ; CHECK-NEXT: ret i1 [[CMP2]]
87 %cmp1 = icmp ugt i32 %y, %x
88 %sel = select i1 %cmp1, i32 %y, i32 %x
89 %cmp2 = icmp ule i32 %sel, %x
93 ; Disguise the icmp predicate by commuting the max op to the RHS.
95 define i1 @ule_umax3(i32 %a, i32 %y) {
96 ; CHECK-LABEL: @ule_umax3(
97 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
98 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], [[Y:%.*]]
99 ; CHECK-NEXT: ret i1 [[CMP2]]
101 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
102 %cmp1 = icmp ugt i32 %x, %y
103 %sel = select i1 %cmp1, i32 %x, i32 %y
104 %cmp2 = icmp uge i32 %x, %sel
108 ; Commute max operands.
110 define i1 @ule_umax4(i32 %a, i32 %y) {
111 ; CHECK-LABEL: @ule_umax4(
112 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
113 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], [[Y:%.*]]
114 ; CHECK-NEXT: ret i1 [[CMP2]]
116 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
117 %cmp1 = icmp ugt i32 %y, %x
118 %sel = select i1 %cmp1, i32 %y, i32 %x
119 %cmp2 = icmp uge i32 %x, %sel
123 ; umax(X, Y) != X --> X < Y
125 define i1 @ne_umax1(i32 %x, i32 %y) {
126 ; CHECK-LABEL: @ne_umax1(
127 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
128 ; CHECK-NEXT: ret i1 [[CMP2]]
130 %cmp1 = icmp ugt i32 %x, %y
131 %sel = select i1 %cmp1, i32 %x, i32 %y
132 %cmp2 = icmp ne i32 %sel, %x
136 ; Commute max operands.
138 define i1 @ne_umax2(i32 %x, i32 %y) {
139 ; CHECK-LABEL: @ne_umax2(
140 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
141 ; CHECK-NEXT: ret i1 [[CMP2]]
143 %cmp1 = icmp ugt i32 %y, %x
144 %sel = select i1 %cmp1, i32 %y, i32 %x
145 %cmp2 = icmp ne i32 %sel, %x
149 ; Disguise the icmp predicate by commuting the max op to the RHS.
151 define i1 @ne_umax3(i32 %a, i32 %y) {
152 ; CHECK-LABEL: @ne_umax3(
153 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
154 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
155 ; CHECK-NEXT: ret i1 [[CMP2]]
157 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
158 %cmp1 = icmp ugt i32 %x, %y
159 %sel = select i1 %cmp1, i32 %x, i32 %y
160 %cmp2 = icmp ne i32 %x, %sel
164 ; Commute max operands.
166 define i1 @ne_umax4(i32 %a, i32 %y) {
167 ; CHECK-LABEL: @ne_umax4(
168 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
169 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
170 ; CHECK-NEXT: ret i1 [[CMP2]]
172 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
173 %cmp1 = icmp ugt i32 %y, %x
174 %sel = select i1 %cmp1, i32 %y, i32 %x
175 %cmp2 = icmp ne i32 %x, %sel
179 ; umax(X, Y) > X --> Y > X
181 define i1 @ugt_umax1(i32 %x, i32 %y) {
182 ; CHECK-LABEL: @ugt_umax1(
183 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
184 ; CHECK-NEXT: ret i1 [[CMP2]]
186 %cmp1 = icmp ugt i32 %x, %y
187 %sel = select i1 %cmp1, i32 %x, i32 %y
188 %cmp2 = icmp ugt i32 %sel, %x
192 ; Commute max operands.
194 define i1 @ugt_umax2(i32 %x, i32 %y) {
195 ; CHECK-LABEL: @ugt_umax2(
196 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
197 ; CHECK-NEXT: ret i1 [[CMP2]]
199 %cmp1 = icmp ugt i32 %y, %x
200 %sel = select i1 %cmp1, i32 %y, i32 %x
201 %cmp2 = icmp ugt i32 %sel, %x
205 ; Disguise the icmp predicate by commuting the max op to the RHS.
207 define i1 @ugt_umax3(i32 %a, i32 %y) {
208 ; CHECK-LABEL: @ugt_umax3(
209 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
210 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
211 ; CHECK-NEXT: ret i1 [[CMP2]]
213 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
214 %cmp1 = icmp ugt i32 %x, %y
215 %sel = select i1 %cmp1, i32 %x, i32 %y
216 %cmp2 = icmp ult i32 %x, %sel
220 ; Commute max operands.
222 define i1 @ugt_umax4(i32 %a, i32 %y) {
223 ; CHECK-LABEL: @ugt_umax4(
224 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
225 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
226 ; CHECK-NEXT: ret i1 [[CMP2]]
228 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
229 %cmp1 = icmp ugt i32 %y, %x
230 %sel = select i1 %cmp1, i32 %y, i32 %x
231 %cmp2 = icmp ult i32 %x, %sel
235 declare void @use(i1 %c)
237 define void @eq_umax_contextual(i32 %x, i32 %y, i32 %z) {
238 ; CHECK-LABEL: @eq_umax_contextual(
239 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Z:%.*]]
240 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
242 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]])
243 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
244 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
245 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
246 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
247 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
248 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
249 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
250 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
251 ; CHECK-NEXT: call void @use(i1 false)
252 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]]
253 ; CHECK-NEXT: call void @use(i1 [[CMP6]])
254 ; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]]
255 ; CHECK-NEXT: call void @use(i1 [[CMP7]])
256 ; CHECK-NEXT: call void @use(i1 true)
257 ; CHECK-NEXT: [[CMP9:%.*]] = icmp uge i32 [[X]], [[Y]]
258 ; CHECK-NEXT: call void @use(i1 [[CMP9]])
259 ; CHECK-NEXT: [[CMP10:%.*]] = icmp ult i32 [[X]], [[Y]]
260 ; CHECK-NEXT: call void @use(i1 [[CMP10]])
261 ; CHECK-NEXT: ret void
263 ; CHECK-NEXT: ret void
265 %cmp = icmp eq i32 %x, %z
266 br i1 %cmp, label %if, label %end
268 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y)
269 %cmp1 = icmp slt i32 %cond, %z
270 call void @use(i1 %cmp1)
271 %cmp2 = icmp sle i32 %cond, %z
272 call void @use(i1 %cmp2)
273 %cmp3 = icmp sgt i32 %cond, %z
274 call void @use(i1 %cmp3)
275 %cmp4 = icmp sge i32 %cond, %z
276 call void @use(i1 %cmp4)
277 %cmp5 = icmp ult i32 %cond, %z
278 call void @use(i1 %cmp5)
279 %cmp6 = icmp ule i32 %cond, %z
280 call void @use(i1 %cmp6)
281 %cmp7 = icmp ugt i32 %cond, %z
282 call void @use(i1 %cmp7)
283 %cmp8 = icmp uge i32 %cond, %z
284 call void @use(i1 %cmp8)
285 %cmp9 = icmp eq i32 %cond, %z
286 call void @use(i1 %cmp9)
287 %cmp10 = icmp ne i32 %cond, %z
288 call void @use(i1 %cmp10)
294 define void @eq_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
295 ; CHECK-LABEL: @eq_umax_contextual_commuted(
296 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Z:%.*]]
297 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
299 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]])
300 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
301 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
302 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
303 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
304 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
305 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
306 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
307 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
308 ; CHECK-NEXT: call void @use(i1 false)
309 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]]
310 ; CHECK-NEXT: call void @use(i1 [[CMP6]])
311 ; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]]
312 ; CHECK-NEXT: call void @use(i1 [[CMP7]])
313 ; CHECK-NEXT: call void @use(i1 true)
314 ; CHECK-NEXT: [[CMP9:%.*]] = icmp uge i32 [[X]], [[Y]]
315 ; CHECK-NEXT: call void @use(i1 [[CMP9]])
316 ; CHECK-NEXT: [[CMP10:%.*]] = icmp ult i32 [[X]], [[Y]]
317 ; CHECK-NEXT: call void @use(i1 [[CMP10]])
318 ; CHECK-NEXT: ret void
320 ; CHECK-NEXT: ret void
322 %cmp = icmp eq i32 %x, %z
323 br i1 %cmp, label %if, label %end
325 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x)
326 %cmp1 = icmp slt i32 %cond, %z
327 call void @use(i1 %cmp1)
328 %cmp2 = icmp sle i32 %cond, %z
329 call void @use(i1 %cmp2)
330 %cmp3 = icmp sgt i32 %cond, %z
331 call void @use(i1 %cmp3)
332 %cmp4 = icmp sge i32 %cond, %z
333 call void @use(i1 %cmp4)
334 %cmp5 = icmp ult i32 %cond, %z
335 call void @use(i1 %cmp5)
336 %cmp6 = icmp ule i32 %cond, %z
337 call void @use(i1 %cmp6)
338 %cmp7 = icmp ugt i32 %cond, %z
339 call void @use(i1 %cmp7)
340 %cmp8 = icmp uge i32 %cond, %z
341 call void @use(i1 %cmp8)
342 %cmp9 = icmp eq i32 %cond, %z
343 call void @use(i1 %cmp9)
344 %cmp10 = icmp ne i32 %cond, %z
345 call void @use(i1 %cmp10)
351 define void @ult_umax_contextual(i32 %x, i32 %y, i32 %z) {
352 ; CHECK-LABEL: @ult_umax_contextual(
353 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]
354 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
356 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]])
357 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
358 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
359 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
360 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
361 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
362 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
363 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
364 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
365 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]]
366 ; CHECK-NEXT: call void @use(i1 [[CMP5]])
367 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]]
368 ; CHECK-NEXT: call void @use(i1 [[CMP6]])
369 ; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]]
370 ; CHECK-NEXT: call void @use(i1 [[CMP7]])
371 ; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]
372 ; CHECK-NEXT: call void @use(i1 [[CMP8]])
373 ; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
374 ; CHECK-NEXT: call void @use(i1 [[CMP9]])
375 ; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
376 ; CHECK-NEXT: call void @use(i1 [[CMP10]])
377 ; CHECK-NEXT: ret void
379 ; CHECK-NEXT: ret void
381 %cmp = icmp ult i32 %x, %z
382 br i1 %cmp, label %if, label %end
384 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y)
385 %cmp1 = icmp slt i32 %cond, %z
386 call void @use(i1 %cmp1)
387 %cmp2 = icmp sle i32 %cond, %z
388 call void @use(i1 %cmp2)
389 %cmp3 = icmp sgt i32 %cond, %z
390 call void @use(i1 %cmp3)
391 %cmp4 = icmp sge i32 %cond, %z
392 call void @use(i1 %cmp4)
393 %cmp5 = icmp ult i32 %cond, %z
394 call void @use(i1 %cmp5)
395 %cmp6 = icmp ule i32 %cond, %z
396 call void @use(i1 %cmp6)
397 %cmp7 = icmp ugt i32 %cond, %z
398 call void @use(i1 %cmp7)
399 %cmp8 = icmp uge i32 %cond, %z
400 call void @use(i1 %cmp8)
401 %cmp9 = icmp eq i32 %cond, %z
402 call void @use(i1 %cmp9)
403 %cmp10 = icmp ne i32 %cond, %z
404 call void @use(i1 %cmp10)
410 define void @ult_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
411 ; CHECK-LABEL: @ult_umax_contextual_commuted(
412 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]
413 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
415 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]])
416 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
417 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
418 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
419 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
420 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
421 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
422 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
423 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
424 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]]
425 ; CHECK-NEXT: call void @use(i1 [[CMP5]])
426 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]]
427 ; CHECK-NEXT: call void @use(i1 [[CMP6]])
428 ; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]]
429 ; CHECK-NEXT: call void @use(i1 [[CMP7]])
430 ; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]
431 ; CHECK-NEXT: call void @use(i1 [[CMP8]])
432 ; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
433 ; CHECK-NEXT: call void @use(i1 [[CMP9]])
434 ; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
435 ; CHECK-NEXT: call void @use(i1 [[CMP10]])
436 ; CHECK-NEXT: ret void
438 ; CHECK-NEXT: ret void
440 %cmp = icmp ult i32 %x, %z
441 br i1 %cmp, label %if, label %end
443 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x)
444 %cmp1 = icmp slt i32 %cond, %z
445 call void @use(i1 %cmp1)
446 %cmp2 = icmp sle i32 %cond, %z
447 call void @use(i1 %cmp2)
448 %cmp3 = icmp sgt i32 %cond, %z
449 call void @use(i1 %cmp3)
450 %cmp4 = icmp sge i32 %cond, %z
451 call void @use(i1 %cmp4)
452 %cmp5 = icmp ult i32 %cond, %z
453 call void @use(i1 %cmp5)
454 %cmp6 = icmp ule i32 %cond, %z
455 call void @use(i1 %cmp6)
456 %cmp7 = icmp ugt i32 %cond, %z
457 call void @use(i1 %cmp7)
458 %cmp8 = icmp uge i32 %cond, %z
459 call void @use(i1 %cmp8)
460 %cmp9 = icmp eq i32 %cond, %z
461 call void @use(i1 %cmp9)
462 %cmp10 = icmp ne i32 %cond, %z
463 call void @use(i1 %cmp10)
469 define void @ule_umax_contextual(i32 %x, i32 %y, i32 %z) {
470 ; CHECK-LABEL: @ule_umax_contextual(
471 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]]
472 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]
474 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]])
475 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
476 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
477 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
478 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
479 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
480 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
481 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
482 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
483 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]
484 ; CHECK-NEXT: call void @use(i1 [[CMP5]])
485 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]]
486 ; CHECK-NEXT: call void @use(i1 [[CMP6]])
487 ; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]]
488 ; CHECK-NEXT: call void @use(i1 [[CMP7]])
489 ; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
490 ; CHECK-NEXT: call void @use(i1 [[CMP8]])
491 ; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
492 ; CHECK-NEXT: call void @use(i1 [[CMP9]])
493 ; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
494 ; CHECK-NEXT: call void @use(i1 [[CMP10]])
495 ; CHECK-NEXT: ret void
497 ; CHECK-NEXT: ret void
499 %cmp = icmp ule i32 %x, %z
500 br i1 %cmp, label %if, label %end
502 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y)
503 %cmp1 = icmp slt i32 %cond, %z
504 call void @use(i1 %cmp1)
505 %cmp2 = icmp sle i32 %cond, %z
506 call void @use(i1 %cmp2)
507 %cmp3 = icmp sgt i32 %cond, %z
508 call void @use(i1 %cmp3)
509 %cmp4 = icmp sge i32 %cond, %z
510 call void @use(i1 %cmp4)
511 %cmp5 = icmp ult i32 %cond, %z
512 call void @use(i1 %cmp5)
513 %cmp6 = icmp ule i32 %cond, %z
514 call void @use(i1 %cmp6)
515 %cmp7 = icmp ugt i32 %cond, %z
516 call void @use(i1 %cmp7)
517 %cmp8 = icmp uge i32 %cond, %z
518 call void @use(i1 %cmp8)
519 %cmp9 = icmp eq i32 %cond, %z
520 call void @use(i1 %cmp9)
521 %cmp10 = icmp ne i32 %cond, %z
522 call void @use(i1 %cmp10)
528 define void @ule_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
529 ; CHECK-LABEL: @ule_umax_contextual_commuted(
530 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]]
531 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]
533 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]])
534 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
535 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
536 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
537 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
538 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
539 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
540 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
541 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
542 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]
543 ; CHECK-NEXT: call void @use(i1 [[CMP5]])
544 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]]
545 ; CHECK-NEXT: call void @use(i1 [[CMP6]])
546 ; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]]
547 ; CHECK-NEXT: call void @use(i1 [[CMP7]])
548 ; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
549 ; CHECK-NEXT: call void @use(i1 [[CMP8]])
550 ; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
551 ; CHECK-NEXT: call void @use(i1 [[CMP9]])
552 ; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
553 ; CHECK-NEXT: call void @use(i1 [[CMP10]])
554 ; CHECK-NEXT: ret void
556 ; CHECK-NEXT: ret void
558 %cmp = icmp ule i32 %x, %z
559 br i1 %cmp, label %if, label %end
561 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x)
562 %cmp1 = icmp slt i32 %cond, %z
563 call void @use(i1 %cmp1)
564 %cmp2 = icmp sle i32 %cond, %z
565 call void @use(i1 %cmp2)
566 %cmp3 = icmp sgt i32 %cond, %z
567 call void @use(i1 %cmp3)
568 %cmp4 = icmp sge i32 %cond, %z
569 call void @use(i1 %cmp4)
570 %cmp5 = icmp ult i32 %cond, %z
571 call void @use(i1 %cmp5)
572 %cmp6 = icmp ule i32 %cond, %z
573 call void @use(i1 %cmp6)
574 %cmp7 = icmp ugt i32 %cond, %z
575 call void @use(i1 %cmp7)
576 %cmp8 = icmp uge i32 %cond, %z
577 call void @use(i1 %cmp8)
578 %cmp9 = icmp eq i32 %cond, %z
579 call void @use(i1 %cmp9)
580 %cmp10 = icmp ne i32 %cond, %z
581 call void @use(i1 %cmp10)
587 define void @ugt_umax_contextual(i32 %x, i32 %y, i32 %z) {
588 ; CHECK-LABEL: @ugt_umax_contextual(
589 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]]
590 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
592 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]])
593 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
594 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
595 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
596 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
597 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
598 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
599 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
600 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
601 ; CHECK-NEXT: call void @use(i1 false)
602 ; CHECK-NEXT: call void @use(i1 false)
603 ; CHECK-NEXT: call void @use(i1 true)
604 ; CHECK-NEXT: call void @use(i1 true)
605 ; CHECK-NEXT: call void @use(i1 false)
606 ; CHECK-NEXT: call void @use(i1 true)
607 ; CHECK-NEXT: ret void
609 ; CHECK-NEXT: ret void
611 %cmp = icmp ugt i32 %x, %z
612 br i1 %cmp, label %if, label %end
614 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y)
615 %cmp1 = icmp slt i32 %cond, %z
616 call void @use(i1 %cmp1)
617 %cmp2 = icmp sle i32 %cond, %z
618 call void @use(i1 %cmp2)
619 %cmp3 = icmp sgt i32 %cond, %z
620 call void @use(i1 %cmp3)
621 %cmp4 = icmp sge i32 %cond, %z
622 call void @use(i1 %cmp4)
623 %cmp5 = icmp ult i32 %cond, %z
624 call void @use(i1 %cmp5)
625 %cmp6 = icmp ule i32 %cond, %z
626 call void @use(i1 %cmp6)
627 %cmp7 = icmp ugt i32 %cond, %z
628 call void @use(i1 %cmp7)
629 %cmp8 = icmp uge i32 %cond, %z
630 call void @use(i1 %cmp8)
631 %cmp9 = icmp eq i32 %cond, %z
632 call void @use(i1 %cmp9)
633 %cmp10 = icmp ne i32 %cond, %z
634 call void @use(i1 %cmp10)
640 define void @ugt_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
641 ; CHECK-LABEL: @ugt_umax_contextual_commuted(
642 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]]
643 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]
645 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]])
646 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
647 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
648 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
649 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
650 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
651 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
652 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
653 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
654 ; CHECK-NEXT: call void @use(i1 false)
655 ; CHECK-NEXT: call void @use(i1 false)
656 ; CHECK-NEXT: call void @use(i1 true)
657 ; CHECK-NEXT: call void @use(i1 true)
658 ; CHECK-NEXT: call void @use(i1 false)
659 ; CHECK-NEXT: call void @use(i1 true)
660 ; CHECK-NEXT: ret void
662 ; CHECK-NEXT: ret void
664 %cmp = icmp ugt i32 %x, %z
665 br i1 %cmp, label %if, label %end
667 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x)
668 %cmp1 = icmp slt i32 %cond, %z
669 call void @use(i1 %cmp1)
670 %cmp2 = icmp sle i32 %cond, %z
671 call void @use(i1 %cmp2)
672 %cmp3 = icmp sgt i32 %cond, %z
673 call void @use(i1 %cmp3)
674 %cmp4 = icmp sge i32 %cond, %z
675 call void @use(i1 %cmp4)
676 %cmp5 = icmp ult i32 %cond, %z
677 call void @use(i1 %cmp5)
678 %cmp6 = icmp ule i32 %cond, %z
679 call void @use(i1 %cmp6)
680 %cmp7 = icmp ugt i32 %cond, %z
681 call void @use(i1 %cmp7)
682 %cmp8 = icmp uge i32 %cond, %z
683 call void @use(i1 %cmp8)
684 %cmp9 = icmp eq i32 %cond, %z
685 call void @use(i1 %cmp9)
686 %cmp10 = icmp ne i32 %cond, %z
687 call void @use(i1 %cmp10)
693 define void @uge_umax_contextual(i32 %x, i32 %y, i32 %z) {
694 ; CHECK-LABEL: @uge_umax_contextual(
695 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]
696 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]
698 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]])
699 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
700 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
701 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
702 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
703 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
704 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
705 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
706 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
707 ; CHECK-NEXT: call void @use(i1 false)
708 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]
709 ; CHECK-NEXT: call void @use(i1 [[CMP6]])
710 ; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]
711 ; CHECK-NEXT: call void @use(i1 [[CMP7]])
712 ; CHECK-NEXT: call void @use(i1 true)
713 ; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
714 ; CHECK-NEXT: call void @use(i1 [[CMP9]])
715 ; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
716 ; CHECK-NEXT: call void @use(i1 [[CMP10]])
717 ; CHECK-NEXT: ret void
719 ; CHECK-NEXT: ret void
721 %cmp = icmp uge i32 %x, %z
722 br i1 %cmp, label %if, label %end
724 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y)
725 %cmp1 = icmp slt i32 %cond, %z
726 call void @use(i1 %cmp1)
727 %cmp2 = icmp sle i32 %cond, %z
728 call void @use(i1 %cmp2)
729 %cmp3 = icmp sgt i32 %cond, %z
730 call void @use(i1 %cmp3)
731 %cmp4 = icmp sge i32 %cond, %z
732 call void @use(i1 %cmp4)
733 %cmp5 = icmp ult i32 %cond, %z
734 call void @use(i1 %cmp5)
735 %cmp6 = icmp ule i32 %cond, %z
736 call void @use(i1 %cmp6)
737 %cmp7 = icmp ugt i32 %cond, %z
738 call void @use(i1 %cmp7)
739 %cmp8 = icmp uge i32 %cond, %z
740 call void @use(i1 %cmp8)
741 %cmp9 = icmp eq i32 %cond, %z
742 call void @use(i1 %cmp9)
743 %cmp10 = icmp ne i32 %cond, %z
744 call void @use(i1 %cmp10)
750 define void @uge_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
751 ; CHECK-LABEL: @uge_umax_contextual_commuted(
752 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]
753 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]
755 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]])
756 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]
757 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
758 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]
759 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
760 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]
761 ; CHECK-NEXT: call void @use(i1 [[CMP3]])
762 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]
763 ; CHECK-NEXT: call void @use(i1 [[CMP4]])
764 ; CHECK-NEXT: call void @use(i1 false)
765 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]
766 ; CHECK-NEXT: call void @use(i1 [[CMP6]])
767 ; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]
768 ; CHECK-NEXT: call void @use(i1 [[CMP7]])
769 ; CHECK-NEXT: call void @use(i1 true)
770 ; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
771 ; CHECK-NEXT: call void @use(i1 [[CMP9]])
772 ; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
773 ; CHECK-NEXT: call void @use(i1 [[CMP10]])
774 ; CHECK-NEXT: ret void
776 ; CHECK-NEXT: ret void
778 %cmp = icmp uge i32 %x, %z
779 br i1 %cmp, label %if, label %end
781 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x)
782 %cmp1 = icmp slt i32 %cond, %z
783 call void @use(i1 %cmp1)
784 %cmp2 = icmp sle i32 %cond, %z
785 call void @use(i1 %cmp2)
786 %cmp3 = icmp sgt i32 %cond, %z
787 call void @use(i1 %cmp3)
788 %cmp4 = icmp sge i32 %cond, %z
789 call void @use(i1 %cmp4)
790 %cmp5 = icmp ult i32 %cond, %z
791 call void @use(i1 %cmp5)
792 %cmp6 = icmp ule i32 %cond, %z
793 call void @use(i1 %cmp6)
794 %cmp7 = icmp ugt i32 %cond, %z
795 call void @use(i1 %cmp7)
796 %cmp8 = icmp uge i32 %cond, %z
797 call void @use(i1 %cmp8)
798 %cmp9 = icmp eq i32 %cond, %z
799 call void @use(i1 %cmp9)
800 %cmp10 = icmp ne i32 %cond, %z
801 call void @use(i1 %cmp10)
807 declare i32 @llvm.umax.i32(i32, i32)