• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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(
14; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 %x, %y
15; 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(
27; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 %x, %y
28; 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
41; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[X]], %y
42; 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
56; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[X]], %y
57; 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(
70; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 %x, %y
71; 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(
83; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 %x, %y
84; 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
97; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[X]], %y
98; 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
112; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[X]], %y
113; 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(
126; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 %x, %y
127; 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
153; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X]], %y
154; 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(
182; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 %x, %y
183; 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
209; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X]], %y
210; 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
334