blob: b3e375fdcddcba3be3d6c27f6f7cd0253a53b211 [file] [log] [blame]
Sanjay Patel964c7352016-12-07 18:56:55 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4; If we have an smin feeding a signed or equality icmp that shares an
5; operand with the smin, the compare should always be folded.
6; Test all 6 foldable predicates (eq,ne,sge,sgt,sle,slt) * 4 commutation
7; possibilities for each predicate. Note that folds to true/false or
8; folds to an existing instruction may be handled by InstSimplify.
9
10; smin(X, Y) == X --> X <= Y
11
12define i1 @eq_smin1(i32 %x, i32 %y) {
13; CHECK-LABEL: @eq_smin1(
Sanjay Pateld6406412016-12-15 19:13:37 +000014; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 %x, %y
Sanjay Patel964c7352016-12-07 18:56:55 +000015; CHECK-NEXT: ret i1 [[CMP2]]
16;
17 %cmp1 = icmp slt i32 %x, %y
18 %sel = select i1 %cmp1, i32 %x, i32 %y
19 %cmp2 = icmp eq i32 %sel, %x
20 ret i1 %cmp2
21}
22
23; Commute min operands.
24
25define i1 @eq_smin2(i32 %x, i32 %y) {
26; CHECK-LABEL: @eq_smin2(
Sanjay Pateld6406412016-12-15 19:13:37 +000027; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 %x, %y
Sanjay Patel964c7352016-12-07 18:56:55 +000028; CHECK-NEXT: ret i1 [[CMP2]]
29;
30 %cmp1 = icmp slt i32 %y, %x
31 %sel = select i1 %cmp1, i32 %y, i32 %x
32 %cmp2 = icmp eq i32 %sel, %x
33 ret i1 %cmp2
34}
35
36; Disguise the icmp predicate by commuting the min op to the RHS.
37
38define i1 @eq_smin3(i32 %a, i32 %y) {
39; CHECK-LABEL: @eq_smin3(
40; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateld6406412016-12-15 19:13:37 +000041; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X]], %y
Sanjay Patel964c7352016-12-07 18:56:55 +000042; CHECK-NEXT: ret i1 [[CMP2]]
43;
44 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
45 %cmp1 = icmp slt i32 %x, %y
46 %sel = select i1 %cmp1, i32 %x, i32 %y
47 %cmp2 = icmp eq i32 %x, %sel
48 ret i1 %cmp2
49}
50
51; Commute min operands.
52
53define i1 @eq_smin4(i32 %a, i32 %y) {
54; CHECK-LABEL: @eq_smin4(
55; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateld6406412016-12-15 19:13:37 +000056; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X]], %y
Sanjay Patel964c7352016-12-07 18:56:55 +000057; CHECK-NEXT: ret i1 [[CMP2]]
58;
59 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
60 %cmp1 = icmp slt i32 %y, %x
61 %sel = select i1 %cmp1, i32 %y, i32 %x
62 %cmp2 = icmp eq i32 %x, %sel
63 ret i1 %cmp2
64}
65
66; smin(X, Y) >= X --> X <= Y
67
68define i1 @sge_smin1(i32 %x, i32 %y) {
69; CHECK-LABEL: @sge_smin1(
Sanjay Pateld6406412016-12-15 19:13:37 +000070; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 %x, %y
Sanjay Patel964c7352016-12-07 18:56:55 +000071; CHECK-NEXT: ret i1 [[CMP2]]
72;
73 %cmp1 = icmp slt i32 %x, %y
74 %sel = select i1 %cmp1, i32 %x, i32 %y
75 %cmp2 = icmp sge i32 %sel, %x
76 ret i1 %cmp2
77}
78
79; Commute min operands.
80
81define i1 @sge_smin2(i32 %x, i32 %y) {
82; CHECK-LABEL: @sge_smin2(
Sanjay Pateld6406412016-12-15 19:13:37 +000083; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 %x, %y
Sanjay Patel964c7352016-12-07 18:56:55 +000084; CHECK-NEXT: ret i1 [[CMP2]]
85;
86 %cmp1 = icmp slt i32 %y, %x
87 %sel = select i1 %cmp1, i32 %y, i32 %x
88 %cmp2 = icmp sge i32 %sel, %x
89 ret i1 %cmp2
90}
91
92; Disguise the icmp predicate by commuting the min op to the RHS.
93
94define i1 @sge_smin3(i32 %a, i32 %y) {
95; CHECK-LABEL: @sge_smin3(
96; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateld6406412016-12-15 19:13:37 +000097; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X]], %y
Sanjay Patel964c7352016-12-07 18:56:55 +000098; CHECK-NEXT: ret i1 [[CMP2]]
99;
100 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
101 %cmp1 = icmp slt i32 %x, %y
102 %sel = select i1 %cmp1, i32 %x, i32 %y
103 %cmp2 = icmp sle i32 %x, %sel
104 ret i1 %cmp2
105}
106
107; Commute min operands.
108
109define i1 @sge_smin4(i32 %a, i32 %y) {
110; CHECK-LABEL: @sge_smin4(
111; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateld6406412016-12-15 19:13:37 +0000112; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X]], %y
Sanjay Patel964c7352016-12-07 18:56:55 +0000113; CHECK-NEXT: ret i1 [[CMP2]]
114;
115 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
116 %cmp1 = icmp slt i32 %y, %x
117 %sel = select i1 %cmp1, i32 %y, i32 %x
118 %cmp2 = icmp sle i32 %x, %sel
119 ret i1 %cmp2
120}
121
122; smin(X, Y) != X --> X > Y
123
124define i1 @ne_smin1(i32 %x, i32 %y) {
125; CHECK-LABEL: @ne_smin1(
Sanjay Pateld6406412016-12-15 19:13:37 +0000126; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 %x, %y
Sanjay Patel964c7352016-12-07 18:56:55 +0000127; CHECK-NEXT: ret i1 [[CMP2]]
128;
129 %cmp1 = icmp slt i32 %x, %y
130 %sel = select i1 %cmp1, i32 %x, i32 %y
131 %cmp2 = icmp ne i32 %sel, %x
132 ret i1 %cmp2
133}
134
135; Commute min operands.
136
137define i1 @ne_smin2(i32 %x, i32 %y) {
138; CHECK-LABEL: @ne_smin2(
139; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 %y, %x
140; CHECK-NEXT: ret i1 [[CMP1]]
141;
142 %cmp1 = icmp slt i32 %y, %x
143 %sel = select i1 %cmp1, i32 %y, i32 %x
144 %cmp2 = icmp ne i32 %sel, %x
145 ret i1 %cmp2
146}
147
148; Disguise the icmp predicate by commuting the min op to the RHS.
149
150define i1 @ne_smin3(i32 %a, i32 %y) {
151; CHECK-LABEL: @ne_smin3(
152; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateld6406412016-12-15 19:13:37 +0000153; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[X]], %y
Sanjay Patel964c7352016-12-07 18:56:55 +0000154; CHECK-NEXT: ret i1 [[CMP2]]
155;
156 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
157 %cmp1 = icmp slt i32 %x, %y
158 %sel = select i1 %cmp1, i32 %x, i32 %y
159 %cmp2 = icmp ne i32 %x, %sel
160 ret i1 %cmp2
161}
162
163; Commute min operands.
164
165define i1 @ne_smin4(i32 %a, i32 %y) {
166; CHECK-LABEL: @ne_smin4(
167; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
168; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[X]], %y
169; CHECK-NEXT: ret i1 [[CMP1]]
170;
171 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
172 %cmp1 = icmp slt i32 %y, %x
173 %sel = select i1 %cmp1, i32 %y, i32 %x
174 %cmp2 = icmp ne i32 %x, %sel
175 ret i1 %cmp2
176}
177
178; smin(X, Y) < X --> X > Y
179
180define i1 @slt_smin1(i32 %x, i32 %y) {
181; CHECK-LABEL: @slt_smin1(
Sanjay Pateld6406412016-12-15 19:13:37 +0000182; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 %x, %y
Sanjay Patel964c7352016-12-07 18:56:55 +0000183; CHECK-NEXT: ret i1 [[CMP2]]
184;
185 %cmp1 = icmp slt i32 %x, %y
186 %sel = select i1 %cmp1, i32 %x, i32 %y
187 %cmp2 = icmp slt i32 %sel, %x
188 ret i1 %cmp2
189}
190
191; Commute min operands.
192
193define i1 @slt_smin2(i32 %x, i32 %y) {
194; CHECK-LABEL: @slt_smin2(
195; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 %y, %x
196; CHECK-NEXT: ret i1 [[CMP1]]
197;
198 %cmp1 = icmp slt i32 %y, %x
199 %sel = select i1 %cmp1, i32 %y, i32 %x
200 %cmp2 = icmp slt i32 %sel, %x
201 ret i1 %cmp2
202}
203
204; Disguise the icmp predicate by commuting the min op to the RHS.
205
206define i1 @slt_smin3(i32 %a, i32 %y) {
207; CHECK-LABEL: @slt_smin3(
208; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateld6406412016-12-15 19:13:37 +0000209; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[X]], %y
Sanjay Patel964c7352016-12-07 18:56:55 +0000210; CHECK-NEXT: ret i1 [[CMP2]]
211;
212 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
213 %cmp1 = icmp slt i32 %x, %y
214 %sel = select i1 %cmp1, i32 %x, i32 %y
215 %cmp2 = icmp sgt i32 %x, %sel
216 ret i1 %cmp2
217}
218
219; Commute min operands.
220
221define i1 @slt_smin4(i32 %a, i32 %y) {
222; CHECK-LABEL: @slt_smin4(
223; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
224; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[X]], %y
225; CHECK-NEXT: ret i1 [[CMP1]]
226;
227 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
228 %cmp1 = icmp slt i32 %y, %x
229 %sel = select i1 %cmp1, i32 %y, i32 %x
230 %cmp2 = icmp sgt i32 %x, %sel
231 ret i1 %cmp2
232}
233
234; smin(X, Y) <= X --> true
235
236define i1 @sle_smin1(i32 %x, i32 %y) {
237; CHECK-LABEL: @sle_smin1(
238; CHECK-NEXT: ret i1 true
239;
240 %cmp1 = icmp slt i32 %x, %y
241 %sel = select i1 %cmp1, i32 %x, i32 %y
242 %cmp2 = icmp sle i32 %sel, %x
243 ret i1 %cmp2
244}
245
246; Commute min operands.
247
248define i1 @sle_smin2(i32 %x, i32 %y) {
249; CHECK-LABEL: @sle_smin2(
250; CHECK-NEXT: ret i1 true
251;
252 %cmp1 = icmp slt i32 %y, %x
253 %sel = select i1 %cmp1, i32 %y, i32 %x
254 %cmp2 = icmp sle i32 %sel, %x
255 ret i1 %cmp2
256}
257
258; Disguise the icmp predicate by commuting the min op to the RHS.
259
260define i1 @sle_smin3(i32 %a, i32 %y) {
261; CHECK-LABEL: @sle_smin3(
262; CHECK-NEXT: ret i1 true
263;
264 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
265 %cmp1 = icmp slt i32 %x, %y
266 %sel = select i1 %cmp1, i32 %x, i32 %y
267 %cmp2 = icmp sge i32 %x, %sel
268 ret i1 %cmp2
269}
270
271; Commute min operands.
272
273define i1 @sle_smin4(i32 %a, i32 %y) {
274; CHECK-LABEL: @sle_smin4(
275; CHECK-NEXT: ret i1 true
276;
277 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
278 %cmp1 = icmp slt i32 %y, %x
279 %sel = select i1 %cmp1, i32 %y, i32 %x
280 %cmp2 = icmp sge i32 %x, %sel
281 ret i1 %cmp2
282}
283
284; smin(X, Y) > X --> false
285
286define i1 @sgt_smin1(i32 %x, i32 %y) {
287; CHECK-LABEL: @sgt_smin1(
288; CHECK-NEXT: ret i1 false
289;
290 %cmp1 = icmp slt i32 %x, %y
291 %sel = select i1 %cmp1, i32 %x, i32 %y
292 %cmp2 = icmp sgt i32 %sel, %x
293 ret i1 %cmp2
294}
295
296; Commute min operands.
297
298define i1 @sgt_smin2(i32 %x, i32 %y) {
299; CHECK-LABEL: @sgt_smin2(
300; CHECK-NEXT: ret i1 false
301;
302 %cmp1 = icmp slt i32 %y, %x
303 %sel = select i1 %cmp1, i32 %y, i32 %x
304 %cmp2 = icmp sgt i32 %sel, %x
305 ret i1 %cmp2
306}
307
308; Disguise the icmp predicate by commuting the min op to the RHS.
309
310define i1 @sgt_smin3(i32 %a, i32 %y) {
311; CHECK-LABEL: @sgt_smin3(
312; CHECK-NEXT: ret i1 false
313;
314 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
315 %cmp1 = icmp slt i32 %x, %y
316 %sel = select i1 %cmp1, i32 %x, i32 %y
317 %cmp2 = icmp slt i32 %x, %sel
318 ret i1 %cmp2
319}
320
321; Commute min operands.
322
323define i1 @sgt_smin4(i32 %a, i32 %y) {
324; CHECK-LABEL: @sgt_smin4(
325; CHECK-NEXT: ret i1 false
326;
327 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
328 %cmp1 = icmp slt i32 %y, %x
329 %sel = select i1 %cmp1, i32 %y, i32 %x
330 %cmp2 = icmp slt i32 %x, %sel
331 ret i1 %cmp2
332}
333