[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / adjust-for-minmax.ll
blob0b4720c1a209fb168fe5dbad953972f36ad490e7
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; Instcombine should recognize that this code can be adjusted to fit the canonical max/min pattern.
6 ; No change
8 define i32 @smax1(i32 %n) {
9 ; CHECK-LABEL: @smax1(
10 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
11 ; CHECK-NEXT:    ret i32 [[M]]
13   %t = icmp sgt i32 %n, 0
14   %m = select i1 %t, i32 %n, i32 0
15   ret i32 %m
18 ; No change
20 define i32 @smin1(i32 %n) {
21 ; CHECK-LABEL: @smin1(
22 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smin.i32(i32 [[N:%.*]], i32 0)
23 ; CHECK-NEXT:    ret i32 [[M]]
25   %t = icmp slt i32 %n, 0
26   %m = select i1 %t, i32 %n, i32 0
27   ret i32 %m
30 ; Canonicalize min/max.
32 define i32 @smax2(i32 %n) {
33 ; CHECK-LABEL: @smax2(
34 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
35 ; CHECK-NEXT:    ret i32 [[M]]
37   %t = icmp sge i32 %n, 1
38   %m = select i1 %t, i32 %n, i32 0
39   ret i32 %m
42 ; Canonicalize min/max.
44 define i32 @smin2(i32 %n) {
45 ; CHECK-LABEL: @smin2(
46 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smin.i32(i32 [[N:%.*]], i32 0)
47 ; CHECK-NEXT:    ret i32 [[M]]
49   %t = icmp sle i32 %n, -1
50   %m = select i1 %t, i32 %n, i32 0
51   ret i32 %m
54 ; Canonicalize min/max.
56 define i32 @smax3(i32 %n) {
57 ; CHECK-LABEL: @smax3(
58 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
59 ; CHECK-NEXT:    ret i32 [[M]]
61   %t = icmp sgt i32 %n, -1
62   %m = select i1 %t, i32 %n, i32 0
63   ret i32 %m
66 ; Canonicalize min/max.
68 define <2 x i32> @smax3_vec(<2 x i32> %n) {
69 ; CHECK-LABEL: @smax3_vec(
70 ; CHECK-NEXT:    [[M:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[N:%.*]], <2 x i32> zeroinitializer)
71 ; CHECK-NEXT:    ret <2 x i32> [[M]]
73   %t = icmp sgt <2 x i32> %n, <i32 -1, i32 -1>
74   %m = select <2 x i1> %t, <2 x i32> %n, <2 x i32> zeroinitializer
75   ret <2 x i32> %m
78 ; Canonicalize min/max.
80 define i32 @smin3(i32 %n) {
81 ; CHECK-LABEL: @smin3(
82 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smin.i32(i32 [[N:%.*]], i32 0)
83 ; CHECK-NEXT:    ret i32 [[M]]
85   %t = icmp slt i32 %n, 1
86   %m = select i1 %t, i32 %n, i32 0
87   ret i32 %m
90 ; Canonicalize min/max.
92 define <2 x i32> @smin3_vec(<2 x i32> %n) {
93 ; CHECK-LABEL: @smin3_vec(
94 ; CHECK-NEXT:    [[M:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[N:%.*]], <2 x i32> zeroinitializer)
95 ; CHECK-NEXT:    ret <2 x i32> [[M]]
97   %t = icmp slt <2 x i32> %n, <i32 1, i32 1>
98   %m = select <2 x i1> %t, <2 x i32> %n, <2 x i32> zeroinitializer
99   ret <2 x i32> %m
102 ; Canonicalize min/max.
104 define i32 @umax3(i32 %n) {
105 ; CHECK-LABEL: @umax3(
106 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 5)
107 ; CHECK-NEXT:    ret i32 [[M]]
109   %t = icmp ugt i32 %n, 4
110   %m = select i1 %t, i32 %n, i32 5
111   ret i32 %m
114 ; Canonicalize min/max.
116 define <2 x i32> @umax3_vec(<2 x i32> %n) {
117 ; CHECK-LABEL: @umax3_vec(
118 ; CHECK-NEXT:    [[M:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[N:%.*]], <2 x i32> splat (i32 5))
119 ; CHECK-NEXT:    ret <2 x i32> [[M]]
121   %t = icmp ugt <2 x i32> %n, <i32 4, i32 4>
122   %m = select <2 x i1> %t, <2 x i32> %n, <2 x i32> <i32 5, i32 5>
123   ret <2 x i32> %m
126 ; Canonicalize min/max.
128 define i32 @umin3(i32 %n) {
129 ; CHECK-LABEL: @umin3(
130 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.umin.i32(i32 [[N:%.*]], i32 6)
131 ; CHECK-NEXT:    ret i32 [[M]]
133   %t = icmp ult i32 %n, 7
134   %m = select i1 %t, i32 %n, i32 6
135   ret i32 %m
138 ; Canonicalize min/max.
140 define <2 x i32> @umin3_vec(<2 x i32> %n) {
141 ; CHECK-LABEL: @umin3_vec(
142 ; CHECK-NEXT:    [[M:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[N:%.*]], <2 x i32> splat (i32 6))
143 ; CHECK-NEXT:    ret <2 x i32> [[M]]
145   %t = icmp ult <2 x i32> %n, <i32 7, i32 7>
146   %m = select <2 x i1> %t, <2 x i32> %n, <2 x i32> <i32 6, i32 6>
147   ret <2 x i32> %m
150 ; Canonicalize min/max.
152 define i32 @smax4(i32 %n) {
153 ; CHECK-LABEL: @smax4(
154 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
155 ; CHECK-NEXT:    ret i32 [[M]]
157   %t = icmp sge i32 %n, 0
158   %m = select i1 %t, i32 %n, i32 0
159   ret i32 %m
162 ; Canonicalize min/max.
164 define <2 x i32> @smax4_vec(<2 x i32> %n) {
165 ; CHECK-LABEL: @smax4_vec(
166 ; CHECK-NEXT:    [[M:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[N:%.*]], <2 x i32> zeroinitializer)
167 ; CHECK-NEXT:    ret <2 x i32> [[M]]
169   %t = icmp sge <2 x i32> %n, zeroinitializer
170   %m = select <2 x i1> %t, <2 x i32> %n, <2 x i32> zeroinitializer
171   ret <2 x i32> %m
174 ; Canonicalize min/max.
176 define i32 @smin4(i32 %n) {
177 ; CHECK-LABEL: @smin4(
178 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smin.i32(i32 [[N:%.*]], i32 0)
179 ; CHECK-NEXT:    ret i32 [[M]]
181   %t = icmp sle i32 %n, 0
182   %m = select i1 %t, i32 %n, i32 0
183   ret i32 %m
186 ; Canonicalize min/max.
188 define <2 x i32> @smin4_vec(<2 x i32> %n) {
189 ; CHECK-LABEL: @smin4_vec(
190 ; CHECK-NEXT:    [[M:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[N:%.*]], <2 x i32> zeroinitializer)
191 ; CHECK-NEXT:    ret <2 x i32> [[M]]
193   %t = icmp sle <2 x i32> %n, zeroinitializer
194   %m = select <2 x i1> %t, <2 x i32> %n, <2 x i32> zeroinitializer
195   ret <2 x i32> %m
198 ; Canonicalize min/max.
200 define i32 @umax4(i32 %n) {
201 ; CHECK-LABEL: @umax4(
202 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 8)
203 ; CHECK-NEXT:    ret i32 [[M]]
205   %t = icmp uge i32 %n, 8
206   %m = select i1 %t, i32 %n, i32 8
207   ret i32 %m
210 ; Canonicalize min/max.
212 define <2 x i32> @umax4_vec(<2 x i32> %n) {
213 ; CHECK-LABEL: @umax4_vec(
214 ; CHECK-NEXT:    [[M:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[N:%.*]], <2 x i32> splat (i32 8))
215 ; CHECK-NEXT:    ret <2 x i32> [[M]]
217   %t = icmp uge <2 x i32> %n, <i32 8, i32 8>
218   %m = select <2 x i1> %t, <2 x i32> %n, <2 x i32> <i32 8, i32 8>
219   ret <2 x i32> %m
222 ; Canonicalize min/max.
224 define i32 @umin4(i32 %n) {
225 ; CHECK-LABEL: @umin4(
226 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.umin.i32(i32 [[N:%.*]], i32 9)
227 ; CHECK-NEXT:    ret i32 [[M]]
229   %t = icmp ule i32 %n, 9
230   %m = select i1 %t, i32 %n, i32 9
231   ret i32 %m
234 ; Canonicalize min/max.
236 define <2 x i32> @umin4_vec(<2 x i32> %n) {
237 ; CHECK-LABEL: @umin4_vec(
238 ; CHECK-NEXT:    [[M:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[N:%.*]], <2 x i32> splat (i32 9))
239 ; CHECK-NEXT:    ret <2 x i32> [[M]]
241   %t = icmp ule <2 x i32> %n, <i32 9, i32 9>
242   %m = select <2 x i1> %t, <2 x i32> %n, <2 x i32> <i32 9, i32 9>
243   ret <2 x i32> %m
246 define i64 @smax_sext(i32 %a) {
247 ; CHECK-LABEL: @smax_sext(
248 ; CHECK-NEXT:    [[NARROW:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 0)
249 ; CHECK-NEXT:    [[MAX:%.*]] = zext nneg i32 [[NARROW]] to i64
250 ; CHECK-NEXT:    ret i64 [[MAX]]
252   %a_ext = sext i32 %a to i64
253   %cmp = icmp sgt i32 %a, -1
254   %max = select i1 %cmp, i64 %a_ext, i64 0
255   ret i64 %max
258 define <2 x i64> @smax_sext_vec(<2 x i32> %a) {
259 ; CHECK-LABEL: @smax_sext_vec(
260 ; CHECK-NEXT:    [[NARROW:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[A:%.*]], <2 x i32> zeroinitializer)
261 ; CHECK-NEXT:    [[MAX:%.*]] = zext nneg <2 x i32> [[NARROW]] to <2 x i64>
262 ; CHECK-NEXT:    ret <2 x i64> [[MAX]]
264   %a_ext = sext <2 x i32> %a to <2 x i64>
265   %cmp = icmp sgt <2 x i32> %a, <i32 -1, i32 -1>
266   %max = select <2 x i1> %cmp, <2 x i64> %a_ext, <2 x i64> zeroinitializer
267   ret <2 x i64> %max
270 define i64 @smin_sext(i32 %a) {
271 ; CHECK-LABEL: @smin_sext(
272 ; CHECK-NEXT:    [[NARROW:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 0)
273 ; CHECK-NEXT:    [[MIN:%.*]] = sext i32 [[NARROW]] to i64
274 ; CHECK-NEXT:    ret i64 [[MIN]]
276   %a_ext = sext i32 %a to i64
277   %cmp = icmp slt i32 %a, 1
278   %min = select i1 %cmp, i64 %a_ext, i64 0
279   ret i64 %min
282 define <2 x i64>@smin_sext_vec(<2 x i32> %a) {
283 ; CHECK-LABEL: @smin_sext_vec(
284 ; CHECK-NEXT:    [[NARROW:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[A:%.*]], <2 x i32> zeroinitializer)
285 ; CHECK-NEXT:    [[MIN:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
286 ; CHECK-NEXT:    ret <2 x i64> [[MIN]]
288   %a_ext = sext <2 x i32> %a to <2 x i64>
289   %cmp = icmp slt <2 x i32> %a, <i32 1, i32 1>
290   %min = select <2 x i1> %cmp, <2 x i64> %a_ext, <2 x i64> zeroinitializer
291   ret <2 x i64> %min
294 define i64 @umax_sext(i32 %a) {
295 ; CHECK-LABEL: @umax_sext(
296 ; CHECK-NEXT:    [[NARROW:%.*]] = call i32 @llvm.umax.i32(i32 [[A:%.*]], i32 3)
297 ; CHECK-NEXT:    [[MAX:%.*]] = sext i32 [[NARROW]] to i64
298 ; CHECK-NEXT:    ret i64 [[MAX]]
300   %a_ext = sext i32 %a to i64
301   %cmp = icmp ugt i32 %a, 2
302   %max = select i1 %cmp, i64 %a_ext, i64 3
303   ret i64 %max
306 define <2 x i64> @umax_sext_vec(<2 x i32> %a) {
307 ; CHECK-LABEL: @umax_sext_vec(
308 ; CHECK-NEXT:    [[NARROW:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[A:%.*]], <2 x i32> splat (i32 3))
309 ; CHECK-NEXT:    [[MAX:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
310 ; CHECK-NEXT:    ret <2 x i64> [[MAX]]
312   %a_ext = sext <2 x i32> %a to <2 x i64>
313   %cmp = icmp ugt <2 x i32> %a, <i32 2, i32 2>
314   %max = select <2 x i1> %cmp, <2 x i64> %a_ext, <2 x i64> <i64 3, i64 3>
315   ret <2 x i64> %max
318 define i64 @umin_sext(i32 %a) {
319 ; CHECK-LABEL: @umin_sext(
320 ; CHECK-NEXT:    [[NARROW:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 2)
321 ; CHECK-NEXT:    [[MIN:%.*]] = zext nneg i32 [[NARROW]] to i64
322 ; CHECK-NEXT:    ret i64 [[MIN]]
324   %a_ext = sext i32 %a to i64
325   %cmp = icmp ult i32 %a, 3
326   %min = select i1 %cmp, i64 %a_ext, i64 2
327   ret i64 %min
330 define <2 x i64> @umin_sext_vec(<2 x i32> %a) {
331 ; CHECK-LABEL: @umin_sext_vec(
332 ; CHECK-NEXT:    [[NARROW:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[A:%.*]], <2 x i32> splat (i32 2))
333 ; CHECK-NEXT:    [[MIN:%.*]] = zext nneg <2 x i32> [[NARROW]] to <2 x i64>
334 ; CHECK-NEXT:    ret <2 x i64> [[MIN]]
336   %a_ext = sext <2 x i32> %a to <2 x i64>
337   %cmp = icmp ult <2 x i32> %a, <i32 3, i32 3>
338   %min = select <2 x i1> %cmp, <2 x i64> %a_ext, <2 x i64> <i64 2, i64 2>
339   ret <2 x i64> %min
342 define i64 @umax_sext2(i32 %a) {
343 ; CHECK-LABEL: @umax_sext2(
344 ; CHECK-NEXT:    [[NARROW:%.*]] = call i32 @llvm.umax.i32(i32 [[A:%.*]], i32 2)
345 ; CHECK-NEXT:    [[MIN:%.*]] = sext i32 [[NARROW]] to i64
346 ; CHECK-NEXT:    ret i64 [[MIN]]
348   %a_ext = sext i32 %a to i64
349   %cmp = icmp ult i32 %a, 3
350   %min = select i1 %cmp, i64 2, i64 %a_ext
351   ret i64 %min
354 define <2 x i64> @umax_sext2_vec(<2 x i32> %a) {
355 ; CHECK-LABEL: @umax_sext2_vec(
356 ; CHECK-NEXT:    [[NARROW:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[A:%.*]], <2 x i32> splat (i32 2))
357 ; CHECK-NEXT:    [[MIN:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
358 ; CHECK-NEXT:    ret <2 x i64> [[MIN]]
360   %a_ext = sext <2 x i32> %a to <2 x i64>
361   %cmp = icmp ult <2 x i32> %a, <i32 3, i32 3>
362   %min = select <2 x i1> %cmp, <2 x i64> <i64 2, i64 2>, <2 x i64> %a_ext
363   ret <2 x i64> %min
366 define i64 @umin_sext2(i32 %a) {
367 ; CHECK-LABEL: @umin_sext2(
368 ; CHECK-NEXT:    [[NARROW:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 3)
369 ; CHECK-NEXT:    [[MIN:%.*]] = zext nneg i32 [[NARROW]] to i64
370 ; CHECK-NEXT:    ret i64 [[MIN]]
372   %a_ext = sext i32 %a to i64
373   %cmp = icmp ugt i32 %a, 2
374   %min = select i1 %cmp, i64 3, i64 %a_ext
375   ret i64 %min
378 define <2 x i64> @umin_sext2_vec(<2 x i32> %a) {
379 ; CHECK-LABEL: @umin_sext2_vec(
380 ; CHECK-NEXT:    [[NARROW:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[A:%.*]], <2 x i32> splat (i32 3))
381 ; CHECK-NEXT:    [[MIN:%.*]] = zext nneg <2 x i32> [[NARROW]] to <2 x i64>
382 ; CHECK-NEXT:    ret <2 x i64> [[MIN]]
384   %a_ext = sext <2 x i32> %a to <2 x i64>
385   %cmp = icmp ugt <2 x i32> %a, <i32 2, i32 2>
386   %min = select <2 x i1> %cmp, <2 x i64> <i64 3, i64 3>, <2 x i64> %a_ext
387   ret <2 x i64> %min
390 define i64 @umax_zext(i32 %a) {
391 ; CHECK-LABEL: @umax_zext(
392 ; CHECK-NEXT:    [[NARROW:%.*]] = call i32 @llvm.umax.i32(i32 [[A:%.*]], i32 3)
393 ; CHECK-NEXT:    [[MAX:%.*]] = zext i32 [[NARROW]] to i64
394 ; CHECK-NEXT:    ret i64 [[MAX]]
396   %a_ext = zext i32 %a to i64
397   %cmp = icmp ugt i32 %a, 2
398   %max = select i1 %cmp, i64 %a_ext, i64 3
399   ret i64 %max
402 define <2 x i64> @umax_zext_vec(<2 x i32> %a) {
403 ; CHECK-LABEL: @umax_zext_vec(
404 ; CHECK-NEXT:    [[NARROW:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[A:%.*]], <2 x i32> splat (i32 3))
405 ; CHECK-NEXT:    [[MAX:%.*]] = zext <2 x i32> [[NARROW]] to <2 x i64>
406 ; CHECK-NEXT:    ret <2 x i64> [[MAX]]
408   %a_ext = zext <2 x i32> %a to <2 x i64>
409   %cmp = icmp ugt <2 x i32> %a, <i32 2, i32 2>
410   %max = select <2 x i1> %cmp, <2 x i64> %a_ext, <2 x i64> <i64 3, i64 3>
411   ret <2 x i64> %max
414 define i64 @umin_zext(i32 %a) {
415 ; CHECK-LABEL: @umin_zext(
416 ; CHECK-NEXT:    [[NARROW:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 2)
417 ; CHECK-NEXT:    [[MIN:%.*]] = zext nneg i32 [[NARROW]] to i64
418 ; CHECK-NEXT:    ret i64 [[MIN]]
420   %a_ext = zext i32 %a to i64
421   %cmp = icmp ult i32 %a, 3
422   %min = select i1 %cmp, i64 %a_ext, i64 2
423   ret i64 %min
426 define <2 x i64> @umin_zext_vec(<2 x i32> %a) {
427 ; CHECK-LABEL: @umin_zext_vec(
428 ; CHECK-NEXT:    [[NARROW:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[A:%.*]], <2 x i32> splat (i32 2))
429 ; CHECK-NEXT:    [[MIN:%.*]] = zext nneg <2 x i32> [[NARROW]] to <2 x i64>
430 ; CHECK-NEXT:    ret <2 x i64> [[MIN]]
432   %a_ext = zext <2 x i32> %a to <2 x i64>
433   %cmp = icmp ult <2 x i32> %a, <i32 3, i32 3>
434   %min = select <2 x i1> %cmp, <2 x i64> %a_ext, <2 x i64> <i64 2, i64 2>
435   ret <2 x i64> %min
438 ; Don't crash mishandling a pattern that can't be transformed.
440 define <2 x i16> @scalar_select_of_vectors(<2 x i16> %a, <2 x i16> %b, i8 %x) {
441 ; CHECK-LABEL: @scalar_select_of_vectors(
442 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
443 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], <2 x i16> [[A:%.*]], <2 x i16> [[B:%.*]]
444 ; CHECK-NEXT:    ret <2 x i16> [[SEL]]
446   %cmp = icmp slt i8 %x, 0
447   %sel = select i1 %cmp, <2 x i16> %a, <2 x i16> %b
448   ret <2 x i16> %sel