[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / umin-icmp.ll
blobef53d1635b227d4c9307a3691f949d43f8d248cb
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
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.
11 ; umin(X, Y) == X --> X <= Y
13 define 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]]
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
24 ; Commute min operands.
26 define 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]]
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
37 ; Disguise the icmp predicate by commuting the min op to the RHS.
39 define 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]]
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
52 ; Commute min operands.
54 define 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]]
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
67 ; umin(X, Y) >= X --> X <= Y
69 define 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]]
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
80 ; Commute min operands.
82 define 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]]
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
93 ; Disguise the icmp predicate by commuting the min op to the RHS.
95 define 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]]
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
108 ; Commute min operands.
110 define 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]]
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
123 ; umin(X, Y) != X --> X > Y
125 define 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]]
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
136 ; Commute min operands.
138 define 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]]
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
149 ; Disguise the icmp predicate by commuting the min op to the RHS.
151 define 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]]
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
164 ; Commute min operands.
166 define 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]]
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
179 ; umin(X, Y) < X --> X > Y
181 define 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]]
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
192 ; Commute min operands.
194 define 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]]
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
205 ; Disguise the icmp predicate by commuting the min op to the RHS.
207 define 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]]
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
220 ; Commute min operands.
222 define 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]]
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