[VectorCombine] foldInsExtVectorToShuffle - canonicalize new shuffle(undef,x) ->...
[llvm-project.git] / llvm / test / Transforms / InstCombine / umax-icmp.ll
blobb4eea30bfc6af5686d3b0193e66086b65cf5c979
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
21   ret i1 %cmp2
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
34   ret i1 %cmp2
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
49   ret i1 %cmp2
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
64   ret i1 %cmp2
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
77   ret i1 %cmp2
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
90   ret i1 %cmp2
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 ule i32 [[Y:%.*]], [[X]]
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
105   ret i1 %cmp2
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 ule i32 [[Y:%.*]], [[X]]
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
120   ret i1 %cmp2
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
133   ret i1 %cmp2
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
146   ret i1 %cmp2
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
161   ret i1 %cmp2
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
176   ret i1 %cmp2
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
189   ret i1 %cmp2
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
202   ret i1 %cmp2
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 ugt i32 [[Y:%.*]], [[X]]
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
217   ret i1 %cmp2
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 ugt i32 [[Y:%.*]], [[X]]
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
232   ret i1 %cmp2
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:%.*]]
241 ; CHECK:       if:
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
262 ; CHECK:       end:
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)
289   ret void
290 end:
291   ret void
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:%.*]]
298 ; CHECK:       if:
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
319 ; CHECK:       end:
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)
346   ret void
347 end:
348   ret void
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:%.*]]
355 ; CHECK:       if:
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
378 ; CHECK:       end:
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)
405   ret void
406 end:
407   ret void
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:%.*]]
414 ; CHECK:       if:
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
437 ; CHECK:       end:
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)
464   ret void
465 end:
466   ret void
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:%.*]]
473 ; CHECK:       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
496 ; CHECK:       end:
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)
523   ret void
524 end:
525   ret void
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:%.*]]
532 ; CHECK:       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
555 ; CHECK:       end:
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)
582   ret void
583 end:
584   ret void
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:%.*]]
591 ; CHECK:       if:
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
608 ; CHECK:       end:
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)
635   ret void
636 end:
637   ret void
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:%.*]]
644 ; CHECK:       if:
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
661 ; CHECK:       end:
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)
688   ret void
689 end:
690   ret void
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:%.*]]
697 ; CHECK:       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
718 ; CHECK:       end:
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)
745   ret void
746 end:
747   ret void
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:%.*]]
754 ; CHECK:       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
775 ; CHECK:       end:
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)
802   ret void
803 end:
804   ret void
807 declare i32 @llvm.umax.i32(i32, i32)