[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / smin-icmp.ll
blob19519ee24f40770984fc6032ca4f92f29eadbee8
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
20   ret i1 %cmp2
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
33   ret i1 %cmp2
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
48   ret i1 %cmp2
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
63   ret i1 %cmp2
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
76   ret i1 %cmp2
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
89   ret i1 %cmp2
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
104   ret i1 %cmp2
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
119   ret i1 %cmp2
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
132   ret i1 %cmp2
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
145   ret i1 %cmp2
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
160   ret i1 %cmp2
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
175   ret i1 %cmp2
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
188   ret i1 %cmp2
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
201   ret i1 %cmp2
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
216   ret i1 %cmp2
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
231   ret i1 %cmp2
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
243   ret i1 %cmp2
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
255   ret i1 %cmp2
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
268   ret i1 %cmp2
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
281   ret i1 %cmp2
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
293   ret i1 %cmp2
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
305   ret i1 %cmp2
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
318   ret i1 %cmp2
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
331   ret i1 %cmp2