1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4; If we have a umin feeding an unsigned or equality icmp that shares an
5; operand with the umin, the compare should always be folded.
6; Test all 4 foldable predicates (eq,ne,uge,ult) * 4 commutation
7; possibilities for each predicate. Note that folds to true/false
8; (predicate is ule/ugt) or folds to an existing instruction should be
9; handled by InstSimplify.
10
11; umin(X, Y) == X --> X <= Y
12
13define i1 @eq_umin1(i32 %x, i32 %y) {
14; CHECK-LABEL: @eq_umin1(
15; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 %x, %y
16; CHECK-NEXT:    ret i1 [[CMP2]]
17;
18  %cmp1 = icmp ult 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 min operands.
25
26define i1 @eq_umin2(i32 %x, i32 %y) {
27; CHECK-LABEL: @eq_umin2(
28; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 %x, %y
29; CHECK-NEXT:    ret i1 [[CMP2]]
30;
31  %cmp1 = icmp ult 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 min op to the RHS.
38
39define i1 @eq_umin3(i32 %a, i32 %y) {
40; CHECK-LABEL: @eq_umin3(
41; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
42; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X]], %y
43; CHECK-NEXT:    ret i1 [[CMP2]]
44;
45  %x = add i32 %a, 3 ; thwart complexity-based canonicalization
46  %cmp1 = icmp ult 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 min operands.
53
54define i1 @eq_umin4(i32 %a, i32 %y) {
55; CHECK-LABEL: @eq_umin4(
56; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
57; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X]], %y
58; CHECK-NEXT:    ret i1 [[CMP2]]
59;
60  %x = add i32 %a, 3 ; thwart complexity-based canonicalization
61  %cmp1 = icmp ult 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; umin(X, Y) >= X --> X <= Y
68
69define i1 @uge_umin1(i32 %x, i32 %y) {
70; CHECK-LABEL: @uge_umin1(
71; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 %x, %y
72; CHECK-NEXT:    ret i1 [[CMP2]]
73;
74  %cmp1 = icmp ult i32 %x, %y
75  %sel = select i1 %cmp1, i32 %x, i32 %y
76  %cmp2 = icmp uge i32 %sel, %x
77  ret i1 %cmp2
78}
79
80; Commute min operands.
81
82define i1 @uge_umin2(i32 %x, i32 %y) {
83; CHECK-LABEL: @uge_umin2(
84; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 %x, %y
85; CHECK-NEXT:    ret i1 [[CMP2]]
86;
87  %cmp1 = icmp ult i32 %y, %x
88  %sel = select i1 %cmp1, i32 %y, i32 %x
89  %cmp2 = icmp uge i32 %sel, %x
90  ret i1 %cmp2
91}
92
93; Disguise the icmp predicate by commuting the min op to the RHS.
94
95define i1 @uge_umin3(i32 %a, i32 %y) {
96; CHECK-LABEL: @uge_umin3(
97; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
98; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X]], %y
99; CHECK-NEXT:    ret i1 [[CMP2]]
100;
101  %x = add i32 %a, 3 ; thwart complexity-based canonicalization
102  %cmp1 = icmp ult i32 %x, %y
103  %sel = select i1 %cmp1, i32 %x, i32 %y
104  %cmp2 = icmp ule i32 %x, %sel
105  ret i1 %cmp2
106}
107
108; Commute min operands.
109
110define i1 @uge_umin4(i32 %a, i32 %y) {
111; CHECK-LABEL: @uge_umin4(
112; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
113; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X]], %y
114; CHECK-NEXT:    ret i1 [[CMP2]]
115;
116  %x = add i32 %a, 3 ; thwart complexity-based canonicalization
117  %cmp1 = icmp ult i32 %y, %x
118  %sel = select i1 %cmp1, i32 %y, i32 %x
119  %cmp2 = icmp ule i32 %x, %sel
120  ret i1 %cmp2
121}
122
123; umin(X, Y) != X --> X > Y
124
125define i1 @ne_umin1(i32 %x, i32 %y) {
126; CHECK-LABEL: @ne_umin1(
127; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 %x, %y
128; CHECK-NEXT:    ret i1 [[CMP2]]
129;
130  %cmp1 = icmp ult 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 min operands.
137
138define i1 @ne_umin2(i32 %x, i32 %y) {
139; CHECK-LABEL: @ne_umin2(
140; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 %y, %x
141; CHECK-NEXT:    ret i1 [[CMP1]]
142;
143  %cmp1 = icmp ult 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 min op to the RHS.
150
151define i1 @ne_umin3(i32 %a, i32 %y) {
152; CHECK-LABEL: @ne_umin3(
153; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
154; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[X]], %y
155; CHECK-NEXT:    ret i1 [[CMP2]]
156;
157  %x = add i32 %a, 3 ; thwart complexity-based canonicalization
158  %cmp1 = icmp ult 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 min operands.
165
166define i1 @ne_umin4(i32 %a, i32 %y) {
167; CHECK-LABEL: @ne_umin4(
168; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
169; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
170; CHECK-NEXT:    ret i1 [[CMP1]]
171;
172  %x = add i32 %a, 3 ; thwart complexity-based canonicalization
173  %cmp1 = icmp ult 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; umin(X, Y) < X --> X > Y
180
181define i1 @ult_umin1(i32 %x, i32 %y) {
182; CHECK-LABEL: @ult_umin1(
183; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 %x, %y
184; CHECK-NEXT:    ret i1 [[CMP2]]
185;
186  %cmp1 = icmp ult i32 %x, %y
187  %sel = select i1 %cmp1, i32 %x, i32 %y
188  %cmp2 = icmp ult i32 %sel, %x
189  ret i1 %cmp2
190}
191
192; Commute min operands.
193
194define i1 @ult_umin2(i32 %x, i32 %y) {
195; CHECK-LABEL: @ult_umin2(
196; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 %y, %x
197; CHECK-NEXT:    ret i1 [[CMP1]]
198;
199  %cmp1 = icmp ult i32 %y, %x
200  %sel = select i1 %cmp1, i32 %y, i32 %x
201  %cmp2 = icmp ult i32 %sel, %x
202  ret i1 %cmp2
203}
204
205; Disguise the icmp predicate by commuting the min op to the RHS.
206
207define i1 @ult_umin3(i32 %a, i32 %y) {
208; CHECK-LABEL: @ult_umin3(
209; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
210; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[X]], %y
211; CHECK-NEXT:    ret i1 [[CMP2]]
212;
213  %x = add i32 %a, 3 ; thwart complexity-based canonicalization
214  %cmp1 = icmp ult i32 %x, %y
215  %sel = select i1 %cmp1, i32 %x, i32 %y
216  %cmp2 = icmp ugt i32 %x, %sel
217  ret i1 %cmp2
218}
219
220; Commute min operands.
221
222define i1 @ult_umin4(i32 %a, i32 %y) {
223; CHECK-LABEL: @ult_umin4(
224; CHECK-NEXT:    [[X:%.*]] = add i32 %a, 3
225; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
226; CHECK-NEXT:    ret i1 [[CMP1]]
227;
228  %x = add i32 %a, 3 ; thwart complexity-based canonicalization
229  %cmp1 = icmp ult i32 %y, %x
230  %sel = select i1 %cmp1, i32 %y, i32 %x
231  %cmp2 = icmp ugt i32 %x, %sel
232  ret i1 %cmp2
233}
234
235