[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / minmax-of-minmax.ll
blob58f2099e43672a148ad014289f2947e9598148f1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 define i32 @smax_of_smax_smin_commute0(i32 %x, i32 %y) {
5 ; CHECK-LABEL: @smax_of_smax_smin_commute0(
6 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
7 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
8 ; CHECK-NEXT:    ret i32 [[MAX]]
10   %cmp1 = icmp slt i32 %x, %y
11   %min = select i1 %cmp1, i32 %x, i32 %y
12   %cmp2 = icmp slt i32 %y, %x
13   %max = select i1 %cmp2, i32 %x, i32 %y
14   %cmp3 = icmp sgt i32 %max, %min
15   %r = select i1 %cmp3, i32 %max, i32 %min
16   ret i32 %r
19 define i32 @smax_of_smax_smin_commute1(i32 %x, i32 %y) {
20 ; CHECK-LABEL: @smax_of_smax_smin_commute1(
21 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
22 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
23 ; CHECK-NEXT:    ret i32 [[MAX]]
25   %cmp1 = icmp sgt i32 %x, %y
26   %min = select i1 %cmp1, i32 %y, i32 %x
27   %cmp2 = icmp sgt i32 %x, %y
28   %max = select i1 %cmp2, i32 %x, i32 %y
29   %cmp3 = icmp sgt i32 %max, %min
30   %r = select i1 %cmp3, i32 %max, i32 %min
31   ret i32 %r
34 define i32 @smax_of_smax_smin_commute2(i32 %x, i32 %y) {
35 ; CHECK-LABEL: @smax_of_smax_smin_commute2(
36 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
37 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
38 ; CHECK-NEXT:    ret i32 [[MAX]]
40   %cmp1 = icmp slt i32 %x, %y
41   %min = select i1 %cmp1, i32 %x, i32 %y
42   %cmp2 = icmp slt i32 %y, %x
43   %max = select i1 %cmp2, i32 %x, i32 %y
44   %cmp3 = icmp slt i32 %min, %max
45   %r = select i1 %cmp3, i32 %max, i32 %min
46   ret i32 %r
49 define <2 x i32> @smax_of_smax_smin_commute3(<2 x i32> %x, <2 x i32> %y) {
50 ; CHECK-LABEL: @smax_of_smax_smin_commute3(
51 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt <2 x i32> [[X:%.*]], [[Y:%.*]]
52 ; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Y]]
53 ; CHECK-NEXT:    ret <2 x i32> [[MAX]]
55   %cmp1 = icmp sgt <2 x i32> %x, %y
56   %min = select <2 x i1> %cmp1, <2 x i32> %y, <2 x i32> %x
57   %cmp2 = icmp sgt <2 x i32> %x, %y
58   %max = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %y
59   %cmp3 = icmp slt <2 x i32> %min, %max
60   %r = select <2 x i1> %cmp3, <2 x i32> %max, <2 x i32> %min
61   ret <2 x i32> %r
64 define i32 @smin_of_smin_smax_commute0(i32 %x, i32 %y) {
65 ; CHECK-LABEL: @smin_of_smin_smax_commute0(
66 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[Y:%.*]], [[X:%.*]]
67 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
68 ; CHECK-NEXT:    ret i32 [[MIN]]
70   %cmp1 = icmp sgt i32 %x, %y
71   %max = select i1 %cmp1, i32 %x, i32 %y
72   %cmp2 = icmp sgt i32 %y, %x
73   %min = select i1 %cmp2, i32 %x, i32 %y
74   %cmp3 = icmp sgt i32 %max, %min
75   %r = select i1 %cmp3, i32 %min, i32 %max
76   ret i32 %r
79 define i32 @smin_of_smin_smax_commute1(i32 %x, i32 %y) {
80 ; CHECK-LABEL: @smin_of_smin_smax_commute1(
81 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
82 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
83 ; CHECK-NEXT:    ret i32 [[MIN]]
85   %cmp1 = icmp slt i32 %x, %y
86   %max = select i1 %cmp1, i32 %y, i32 %x
87   %cmp2 = icmp slt i32 %x, %y
88   %min = select i1 %cmp2, i32 %x, i32 %y
89   %cmp3 = icmp sgt i32 %max, %min
90   %r = select i1 %cmp3, i32 %min, i32 %max
91   ret i32 %r
94 define <2 x i32> @smin_of_smin_smax_commute2(<2 x i32> %x, <2 x i32> %y) {
95 ; CHECK-LABEL: @smin_of_smin_smax_commute2(
96 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt <2 x i32> [[X:%.*]], [[Y:%.*]]
97 ; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Y]]
98 ; CHECK-NEXT:    ret <2 x i32> [[MIN]]
100   %cmp1 = icmp sgt <2 x i32> %x, %y
101   %max = select <2 x i1> %cmp1, <2 x i32> %x, <2 x i32> %y
102   %cmp2 = icmp slt <2 x i32> %x, %y
103   %min = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %y
104   %cmp3 = icmp slt <2 x i32> %min, %max
105   %r = select <2 x i1> %cmp3, <2 x i32> %min, <2 x i32> %max
106   ret <2 x i32> %r
109 define i32 @smin_of_smin_smax_commute3(i32 %x, i32 %y) {
110 ; CHECK-LABEL: @smin_of_smin_smax_commute3(
111 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[Y:%.*]], [[X:%.*]]
112 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
113 ; CHECK-NEXT:    ret i32 [[MIN]]
115   %cmp1 = icmp slt i32 %x, %y
116   %max = select i1 %cmp1, i32 %y, i32 %x
117   %cmp2 = icmp sgt i32 %y, %x
118   %min = select i1 %cmp2, i32 %x, i32 %y
119   %cmp3 = icmp slt i32 %min, %max
120   %r = select i1 %cmp3, i32 %min, i32 %max
121   ret i32 %r
124 define i32 @umax_of_umax_umin_commute0(i32 %x, i32 %y) {
125 ; CHECK-LABEL: @umax_of_umax_umin_commute0(
126 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], [[X:%.*]]
127 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
128 ; CHECK-NEXT:    ret i32 [[MAX]]
130   %cmp1 = icmp ult i32 %x, %y
131   %min = select i1 %cmp1, i32 %x, i32 %y
132   %cmp2 = icmp ult i32 %y, %x
133   %max = select i1 %cmp2, i32 %x, i32 %y
134   %cmp3 = icmp ugt i32 %max, %min
135   %r = select i1 %cmp3, i32 %max, i32 %min
136   ret i32 %r
139 define i32 @umax_of_umax_umin_commute1(i32 %x, i32 %y) {
140 ; CHECK-LABEL: @umax_of_umax_umin_commute1(
141 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
142 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
143 ; CHECK-NEXT:    ret i32 [[MAX]]
145   %cmp1 = icmp ugt i32 %x, %y
146   %min = select i1 %cmp1, i32 %y, i32 %x
147   %cmp2 = icmp ugt i32 %x, %y
148   %max = select i1 %cmp2, i32 %x, i32 %y
149   %cmp3 = icmp ugt i32 %max, %min
150   %r = select i1 %cmp3, i32 %max, i32 %min
151   ret i32 %r
154 define i32 @umax_of_umax_umin_commute2(i32 %x, i32 %y) {
155 ; CHECK-LABEL: @umax_of_umax_umin_commute2(
156 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], [[X:%.*]]
157 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
158 ; CHECK-NEXT:    ret i32 [[MAX]]
160   %cmp1 = icmp ult i32 %x, %y
161   %min = select i1 %cmp1, i32 %x, i32 %y
162   %cmp2 = icmp ult i32 %y, %x
163   %max = select i1 %cmp2, i32 %x, i32 %y
164   %cmp3 = icmp ult i32 %min, %max
165   %r = select i1 %cmp3, i32 %max, i32 %min
166   ret i32 %r
169 define <2 x i32> @umax_of_umax_umin_commute3(<2 x i32> %x, <2 x i32> %y) {
170 ; CHECK-LABEL: @umax_of_umax_umin_commute3(
171 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt <2 x i32> [[X:%.*]], [[Y:%.*]]
172 ; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Y]]
173 ; CHECK-NEXT:    ret <2 x i32> [[MAX]]
175   %cmp1 = icmp ugt <2 x i32> %x, %y
176   %min = select <2 x i1> %cmp1, <2 x i32> %y, <2 x i32> %x
177   %cmp2 = icmp ugt <2 x i32> %x, %y
178   %max = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %y
179   %cmp3 = icmp ult <2 x i32> %min, %max
180   %r = select <2 x i1> %cmp3, <2 x i32> %max, <2 x i32> %min
181   ret <2 x i32> %r
184 define i32 @umin_of_umin_umax_commute0(i32 %x, i32 %y) {
185 ; CHECK-LABEL: @umin_of_umin_umax_commute0(
186 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
187 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
188 ; CHECK-NEXT:    ret i32 [[MIN]]
190   %cmp1 = icmp ugt i32 %x, %y
191   %max = select i1 %cmp1, i32 %x, i32 %y
192   %cmp2 = icmp ugt i32 %y, %x
193   %min = select i1 %cmp2, i32 %x, i32 %y
194   %cmp3 = icmp ugt i32 %max, %min
195   %r = select i1 %cmp3, i32 %min, i32 %max
196   ret i32 %r
199 define i32 @umin_of_umin_umax_commute1(i32 %x, i32 %y) {
200 ; CHECK-LABEL: @umin_of_umin_umax_commute1(
201 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
202 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
203 ; CHECK-NEXT:    ret i32 [[MIN]]
205   %cmp1 = icmp ult i32 %x, %y
206   %max = select i1 %cmp1, i32 %y, i32 %x
207   %cmp2 = icmp ult i32 %x, %y
208   %min = select i1 %cmp2, i32 %x, i32 %y
209   %cmp3 = icmp ugt i32 %max, %min
210   %r = select i1 %cmp3, i32 %min, i32 %max
211   ret i32 %r
214 define <2 x i32> @umin_of_umin_umax_commute2(<2 x i32> %x, <2 x i32> %y) {
215 ; CHECK-LABEL: @umin_of_umin_umax_commute2(
216 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]]
217 ; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Y]]
218 ; CHECK-NEXT:    ret <2 x i32> [[MIN]]
220   %cmp1 = icmp ugt <2 x i32> %x, %y
221   %max = select <2 x i1> %cmp1, <2 x i32> %x, <2 x i32> %y
222   %cmp2 = icmp ult <2 x i32> %x, %y
223   %min = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %y
224   %cmp3 = icmp ult <2 x i32> %min, %max
225   %r = select <2 x i1> %cmp3, <2 x i32> %min, <2 x i32> %max
226   ret <2 x i32> %r
229 define i32 @umin_of_umin_umax_commute3(i32 %x, i32 %y) {
230 ; CHECK-LABEL: @umin_of_umin_umax_commute3(
231 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
232 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
233 ; CHECK-NEXT:    ret i32 [[MIN]]
235   %cmp1 = icmp ult i32 %x, %y
236   %max = select i1 %cmp1, i32 %y, i32 %x
237   %cmp2 = icmp ugt i32 %y, %x
238   %min = select i1 %cmp2, i32 %x, i32 %y
239   %cmp3 = icmp ult i32 %min, %max
240   %r = select i1 %cmp3, i32 %min, i32 %max
241   ret i32 %r
244 ; Negative test - mismatch of min/max flavor
246 define i32 @umin_of_smin_umax_wrong_pattern(i32 %x, i32 %y) {
247 ; CHECK-LABEL: @umin_of_smin_umax_wrong_pattern(
248 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
249 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 [[Y]]
250 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[Y]], [[X]]
251 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
252 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[MAX]], [[MIN]]
253 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP3]], i32 [[MIN]], i32 [[MAX]]
254 ; CHECK-NEXT:    ret i32 [[R]]
256   %cmp1 = icmp ugt i32 %x, %y
257   %max = select i1 %cmp1, i32 %x, i32 %y
258   %cmp2 = icmp sgt i32 %y, %x
259   %min = select i1 %cmp2, i32 %x, i32 %y
260   %cmp3 = icmp ugt i32 %max, %min
261   %r = select i1 %cmp3, i32 %min, i32 %max
262   ret i32 %r
265 ; Negative test - mismatch of min/max flavor
267 define i32 @smin_of_umin_umax_wrong_pattern2(i32 %x, i32 %y) {
268 ; CHECK-LABEL: @smin_of_umin_umax_wrong_pattern2(
269 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
270 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP1]], i32 [[Y]], i32 [[X]]
271 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
272 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
273 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[MAX]], [[MIN]]
274 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP3]], i32 [[MIN]], i32 [[MAX]]
275 ; CHECK-NEXT:    ret i32 [[R]]
277   %cmp1 = icmp ult i32 %x, %y
278   %max = select i1 %cmp1, i32 %y, i32 %x
279   %cmp2 = icmp ult i32 %x, %y
280   %min = select i1 %cmp2, i32 %x, i32 %y
281   %cmp3 = icmp sgt i32 %max, %min
282   %r = select i1 %cmp3, i32 %min, i32 %max
283   ret i32 %r
286 ; Negative test - operands must match
288 define <2 x i32> @umin_of_umin_umax_wrong_operand(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
289 ; CHECK-LABEL: @umin_of_umin_umax_wrong_operand(
290 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt <2 x i32> [[X:%.*]], [[Y:%.*]]
291 ; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> [[X]], <2 x i32> [[Y]]
292 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i32> [[X]], [[Z:%.*]]
293 ; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Z]]
294 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult <2 x i32> [[MIN]], [[MAX]]
295 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[CMP3]], <2 x i32> [[MIN]], <2 x i32> [[MAX]]
296 ; CHECK-NEXT:    ret <2 x i32> [[R]]
298   %cmp1 = icmp ugt <2 x i32> %x, %y
299   %max = select <2 x i1> %cmp1, <2 x i32> %x, <2 x i32> %y
300   %cmp2 = icmp ult <2 x i32> %x, %z
301   %min = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %z
302   %cmp3 = icmp ult <2 x i32> %min, %max
303   %r = select <2 x i1> %cmp3, <2 x i32> %min, <2 x i32> %max
304   ret <2 x i32> %r
307 ; Negative test - operands must match
309 define i32 @umin_of_umin_umax_wrong_operand2(i32 %x, i32 %y, i32 %z) {
310 ; CHECK-LABEL: @umin_of_umin_umax_wrong_operand2(
311 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]
312 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP1]], i32 [[Z]], i32 [[X]]
313 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X]]
314 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
315 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[MIN]], [[MAX]]
316 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP3]], i32 [[MIN]], i32 [[MAX]]
317 ; CHECK-NEXT:    ret i32 [[R]]
319   %cmp1 = icmp ult i32 %x, %z
320   %max = select i1 %cmp1, i32 %z, i32 %x
321   %cmp2 = icmp ugt i32 %y, %x
322   %min = select i1 %cmp2, i32 %x, i32 %y
323   %cmp3 = icmp ult i32 %min, %max
324   %r = select i1 %cmp3, i32 %min, i32 %max
325   ret i32 %r