xref: /llvm-project/llvm/test/Transforms/InstCombine/umax-icmp.ll (revision a105877646d68e48cdeeeadd9d1e075dc3c5d68d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
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.
10
11; umax(X, Y) == X --> X >= Y
12
13define 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]]
17;
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
22}
23
24; Commute max operands.
25
26define 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]]
30;
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
35}
36
37; Disguise the icmp predicate by commuting the max op to the RHS.
38
39define 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]]
44;
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
50}
51
52; Commute max operands.
53
54define 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]]
59;
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
65}
66
67; umax(X, Y) <= X --> Y <= X
68
69define 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]]
73;
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
78}
79
80; Commute max operands.
81
82define 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]]
86;
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
91}
92
93; Disguise the icmp predicate by commuting the max op to the RHS.
94
95define 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]]
100;
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
106}
107
108; Commute max operands.
109
110define 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]]
115;
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
121}
122
123; umax(X, Y) != X --> X < Y
124
125define 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]]
129;
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
134}
135
136; Commute max operands.
137
138define 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]]
142;
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
147}
148
149; Disguise the icmp predicate by commuting the max op to the RHS.
150
151define 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]]
156;
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
162}
163
164; Commute max operands.
165
166define 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]]
171;
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
177}
178
179; umax(X, Y) > X --> Y > X
180
181define 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]]
185;
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
190}
191
192; Commute max operands.
193
194define 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]]
198;
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
203}
204
205; Disguise the icmp predicate by commuting the max op to the RHS.
206
207define 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]]
212;
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
218}
219
220; Commute max operands.
221
222define 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]]
227;
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
233}
234
235declare void @use(i1 %c)
236
237define 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
264;
265  %cmp = icmp eq i32 %x, %z
266  br i1 %cmp, label %if, label %end
267if:
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
290end:
291  ret void
292}
293
294define 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
321;
322  %cmp = icmp eq i32 %x, %z
323  br i1 %cmp, label %if, label %end
324if:
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
347end:
348  ret void
349}
350
351define 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
380;
381  %cmp = icmp ult i32 %x, %z
382  br i1 %cmp, label %if, label %end
383if:
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
406end:
407  ret void
408}
409
410define 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
439;
440  %cmp = icmp ult i32 %x, %z
441  br i1 %cmp, label %if, label %end
442if:
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
465end:
466  ret void
467}
468
469define 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
498;
499  %cmp = icmp ule i32 %x, %z
500  br i1 %cmp, label %if, label %end
501if:
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
524end:
525  ret void
526}
527
528define 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
557;
558  %cmp = icmp ule i32 %x, %z
559  br i1 %cmp, label %if, label %end
560if:
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
583end:
584  ret void
585}
586
587define 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
610;
611  %cmp = icmp ugt i32 %x, %z
612  br i1 %cmp, label %if, label %end
613if:
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
636end:
637  ret void
638}
639
640define 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
663;
664  %cmp = icmp ugt i32 %x, %z
665  br i1 %cmp, label %if, label %end
666if:
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
689end:
690  ret void
691}
692
693define 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
720;
721  %cmp = icmp uge i32 %x, %z
722  br i1 %cmp, label %if, label %end
723if:
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
746end:
747  ret void
748}
749
750define 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
777;
778  %cmp = icmp uge i32 %x, %z
779  br i1 %cmp, label %if, label %end
780if:
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
803end:
804  ret void
805}
806
807declare i32 @llvm.umax.i32(i32, i32)
808