1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
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.
10 ; smin(X, Y) == X --> X <= Y
12 define 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]]
17 %cmp1 = icmp slt i32 %x, %y
18 %sel = select i1 %cmp1, i32 %x, i32 %y
19 %cmp2 = icmp eq i32 %sel, %x
23 ; Commute min operands.
25 define 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]]
30 %cmp1 = icmp slt i32 %y, %x
31 %sel = select i1 %cmp1, i32 %y, i32 %x
32 %cmp2 = icmp eq i32 %sel, %x
36 ; Disguise the icmp predicate by commuting the min op to the RHS.
38 define 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]]
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
51 ; Commute min operands.
53 define 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]]
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
66 ; smin(X, Y) >= X --> X <= Y
68 define 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]]
73 %cmp1 = icmp slt i32 %x, %y
74 %sel = select i1 %cmp1, i32 %x, i32 %y
75 %cmp2 = icmp sge i32 %sel, %x
79 ; Commute min operands.
81 define 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]]
86 %cmp1 = icmp slt i32 %y, %x
87 %sel = select i1 %cmp1, i32 %y, i32 %x
88 %cmp2 = icmp sge i32 %sel, %x
92 ; Disguise the icmp predicate by commuting the min op to the RHS.
94 define 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]]
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
107 ; Commute min operands.
109 define 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]]
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
122 ; smin(X, Y) != X --> X > Y
124 define 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]]
129 %cmp1 = icmp slt i32 %x, %y
130 %sel = select i1 %cmp1, i32 %x, i32 %y
131 %cmp2 = icmp ne i32 %sel, %x
135 ; Commute min operands.
137 define 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]]
142 %cmp1 = icmp slt i32 %y, %x
143 %sel = select i1 %cmp1, i32 %y, i32 %x
144 %cmp2 = icmp ne i32 %sel, %x
148 ; Disguise the icmp predicate by commuting the min op to the RHS.
150 define 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]]
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
163 ; Commute min operands.
165 define 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]]
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
178 ; smin(X, Y) < X --> X > Y
180 define 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]]
185 %cmp1 = icmp slt i32 %x, %y
186 %sel = select i1 %cmp1, i32 %x, i32 %y
187 %cmp2 = icmp slt i32 %sel, %x
191 ; Commute min operands.
193 define 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]]
198 %cmp1 = icmp slt i32 %y, %x
199 %sel = select i1 %cmp1, i32 %y, i32 %x
200 %cmp2 = icmp slt i32 %sel, %x
204 ; Disguise the icmp predicate by commuting the min op to the RHS.
206 define 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]]
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
219 ; Commute min operands.
221 define 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]]
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
234 ; smin(X, Y) <= X --> true
236 define i1 @sle_smin1(i32 %x, i32 %y) {
237 ; CHECK-LABEL: @sle_smin1(
238 ; CHECK-NEXT: ret i1 true
240 %cmp1 = icmp slt i32 %x, %y
241 %sel = select i1 %cmp1, i32 %x, i32 %y
242 %cmp2 = icmp sle i32 %sel, %x
246 ; Commute min operands.
248 define i1 @sle_smin2(i32 %x, i32 %y) {
249 ; CHECK-LABEL: @sle_smin2(
250 ; CHECK-NEXT: ret i1 true
252 %cmp1 = icmp slt i32 %y, %x
253 %sel = select i1 %cmp1, i32 %y, i32 %x
254 %cmp2 = icmp sle i32 %sel, %x
258 ; Disguise the icmp predicate by commuting the min op to the RHS.
260 define i1 @sle_smin3(i32 %a, i32 %y) {
261 ; CHECK-LABEL: @sle_smin3(
262 ; CHECK-NEXT: ret i1 true
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
271 ; Commute min operands.
273 define i1 @sle_smin4(i32 %a, i32 %y) {
274 ; CHECK-LABEL: @sle_smin4(
275 ; CHECK-NEXT: ret i1 true
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
284 ; smin(X, Y) > X --> false
286 define i1 @sgt_smin1(i32 %x, i32 %y) {
287 ; CHECK-LABEL: @sgt_smin1(
288 ; CHECK-NEXT: ret i1 false
290 %cmp1 = icmp slt i32 %x, %y
291 %sel = select i1 %cmp1, i32 %x, i32 %y
292 %cmp2 = icmp sgt i32 %sel, %x
296 ; Commute min operands.
298 define i1 @sgt_smin2(i32 %x, i32 %y) {
299 ; CHECK-LABEL: @sgt_smin2(
300 ; CHECK-NEXT: ret i1 false
302 %cmp1 = icmp slt i32 %y, %x
303 %sel = select i1 %cmp1, i32 %y, i32 %x
304 %cmp2 = icmp sgt i32 %sel, %x
308 ; Disguise the icmp predicate by commuting the min op to the RHS.
310 define i1 @sgt_smin3(i32 %a, i32 %y) {
311 ; CHECK-LABEL: @sgt_smin3(
312 ; CHECK-NEXT: ret i1 false
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
321 ; Commute min operands.
323 define i1 @sgt_smin4(i32 %a, i32 %y) {
324 ; CHECK-LABEL: @sgt_smin4(
325 ; CHECK-NEXT: ret i1 false
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