[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / minmax-fold.ll
blob47588565c5ced2d8b8d6922d746fb1cf79d06e5c
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 ; This is the canonical form for a type-changing min/max.
5 define i64 @t1(i32 %a) {
6 ; CHECK-LABEL: @t1(
7 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[A:%.*]], 5
8 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 5
9 ; CHECK-NEXT:    [[TMP3:%.*]] = sext i32 [[TMP2]] to i64
10 ; CHECK-NEXT:    ret i64 [[TMP3]]
12   %1 = icmp slt i32 %a, 5
13   %2 = select i1 %1, i32 %a, i32 5
14   %3 = sext i32 %2 to i64
15   ret i64 %3
18 ; Check this is converted into canonical form, as above.
19 define i64 @t2(i32 %a) {
20 ; CHECK-LABEL: @t2(
21 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[A:%.*]], 5
22 ; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 5
23 ; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[NARROW]] to i64
24 ; CHECK-NEXT:    ret i64 [[TMP2]]
26   %1 = icmp slt i32 %a, 5
27   %2 = sext i32 %a to i64
28   %3 = select i1 %1, i64 %2, i64 5
29   ret i64 %3
32 ; Same as @t2, with flipped operands and zext instead of sext.
33 define i64 @t3(i32 %a) {
34 ; CHECK-LABEL: @t3(
35 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 5
36 ; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 5
37 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[NARROW]] to i64
38 ; CHECK-NEXT:    ret i64 [[TMP2]]
40   %1 = icmp ult i32 %a, 5
41   %2 = zext i32 %a to i64
42   %3 = select i1 %1, i64 5, i64 %2
43   ret i64 %3
46 ; Same again, with trunc.
47 define i32 @t4(i64 %a) {
48 ; CHECK-LABEL: @t4(
49 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[A:%.*]], 5
50 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[A]], i64 5
51 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 [[TMP2]] to i32
52 ; CHECK-NEXT:    ret i32 [[TMP3]]
54   %1 = icmp slt i64 %a, 5
55   %2 = trunc i64 %a to i32
56   %3 = select i1 %1, i32 %2, i32 5
57   ret i32 %3
60 ; Same as @t3, but with mismatched signedness between icmp and zext.
61 define i64 @t5(i32 %a) {
62 ; CHECK-LABEL: @t5(
63 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 5
64 ; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 5
65 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[NARROW]] to i64
66 ; CHECK-NEXT:    ret i64 [[TMP2]]
68   %1 = icmp slt i32 %a, 5
69   %2 = zext i32 %a to i64
70   %3 = select i1 %1, i64 5, i64 %2
71   ret i64 %3
74 define float @t6(i32 %a) {
75 ; CHECK-LABEL: @t6(
76 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[A:%.*]], 0
77 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 0
78 ; CHECK-NEXT:    [[TMP3:%.*]] = sitofp i32 [[TMP2]] to float
79 ; CHECK-NEXT:    ret float [[TMP3]]
81   %1 = icmp slt i32 %a, 0
82   %2 = select i1 %1, i32 %a, i32 0
83   %3 = sitofp i32 %2 to float
84   ret float %3
87 define i16 @t7(i32 %a) {
88 ; CHECK-LABEL: @t7(
89 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[A:%.*]], -32768
90 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 -32768
91 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc i32 [[TMP2]] to i16
92 ; CHECK-NEXT:    ret i16 [[TMP3]]
94   %1 = icmp slt i32 %a, -32768
95   %2 = trunc i32 %a to i16
96   %3 = select i1 %1, i16 %2, i16 -32768
97   ret i16 %3
100 ; Just check for no infinite loop. InstSimplify liked to
101 ; "simplify" -32767 by removing all the sign bits,
102 ; which led to a canonicalization fight between different
103 ; parts of instcombine.
104 define i32 @t8(i64 %a, i32 %b) {
105 ; CHECK-LABEL: @t8(
106 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[A:%.*]], -32767
107 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[A]], i64 -32767
108 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 [[TMP2]] to i32
109 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i32 [[B:%.*]], 42
110 ; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP4]], i32 42, i32 [[TMP3]]
111 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp ne i32 [[TMP5]], [[B]]
112 ; CHECK-NEXT:    [[TMP7:%.*]] = zext i1 [[TMP6]] to i32
113 ; CHECK-NEXT:    ret i32 [[TMP7]]
115   %1 = icmp slt i64 %a, -32767
116   %2 = select i1 %1, i64 %a, i64 -32767
117   %3 = trunc i64 %2 to i32
118   %4 = icmp slt i32 %b, 42
119   %5 = select i1 %4, i32 42, i32 %3
120   %6 = icmp ne i32 %5, %b
121   %7 = zext i1 %6 to i32
122   ret i32 %7
125 ; Ensure this doesn't get converted to a min/max.
126 define i64 @t9(i32 %a) {
127 ; CHECK-LABEL: @t9(
128 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], -1
129 ; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[A]] to i64
130 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i64 [[TMP2]], i64 4294967295
131 ; CHECK-NEXT:    ret i64 [[TMP3]]
133   %1 = icmp sgt i32 %a, -1
134   %2 = sext i32 %a to i64
135   %3 = select i1 %1, i64 %2, i64 4294967295
136   ret i64 %3
139 define float @t10(i32 %x) {
140 ; CHECK-LABEL: @t10(
141 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], 255
142 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 255
143 ; CHECK-NEXT:    [[TMP2:%.*]] = sitofp i32 [[R1]] to float
144 ; CHECK-NEXT:    ret float [[TMP2]]
146   %f_x = sitofp i32 %x to float
147   %cmp = icmp sgt i32 %x, 255
148   %r = select i1 %cmp, float %f_x, float 255.0
149   ret float %r
152 define float @t11(i64 %x) {
153 ; CHECK-LABEL: @t11(
154 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[X:%.*]], 255
155 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[TMP1]], i64 [[X]], i64 255
156 ; CHECK-NEXT:    [[TMP2:%.*]] = sitofp i64 [[R1]] to float
157 ; CHECK-NEXT:    ret float [[TMP2]]
159   %f_x = sitofp i64 %x to float
160   %cmp = icmp sgt i64 %x, 255
161   %r = select i1 %cmp, float %f_x, float 255.0
162   ret float %r
165 ; Reuse the first 2 bitcasts as the select operands.
167 define <4 x i32> @bitcasts_fcmp_1(<2 x i64> %a, <2 x i64> %b) {
168 ; CHECK-LABEL: @bitcasts_fcmp_1(
169 ; CHECK-NEXT:    [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x float>
170 ; CHECK-NEXT:    [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x float>
171 ; CHECK-NEXT:    [[T2:%.*]] = fcmp olt <4 x float> [[T1]], [[T0]]
172 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[T2]], <4 x float> [[T0]], <4 x float> [[T1]]
173 ; CHECK-NEXT:    [[T5:%.*]] = bitcast <4 x float> [[TMP1]] to <4 x i32>
174 ; CHECK-NEXT:    ret <4 x i32> [[T5]]
176   %t0 = bitcast <2 x i64> %a to <4 x float>
177   %t1 = bitcast <2 x i64> %b to <4 x float>
178   %t2 = fcmp olt <4 x float> %t1, %t0
179   %t3 = bitcast <2 x i64> %a to <4 x i32>
180   %t4 = bitcast <2 x i64> %b to <4 x i32>
181   %t5 = select <4 x i1> %t2, <4 x i32> %t3, <4 x i32> %t4
182   ret <4 x i32> %t5
185 ; Switch cmp operand order.
187 define <4 x i32> @bitcasts_fcmp_2(<2 x i64> %a, <2 x i64> %b) {
188 ; CHECK-LABEL: @bitcasts_fcmp_2(
189 ; CHECK-NEXT:    [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x float>
190 ; CHECK-NEXT:    [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x float>
191 ; CHECK-NEXT:    [[T2:%.*]] = fcmp olt <4 x float> [[T0]], [[T1]]
192 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[T2]], <4 x float> [[T0]], <4 x float> [[T1]]
193 ; CHECK-NEXT:    [[T5:%.*]] = bitcast <4 x float> [[TMP1]] to <4 x i32>
194 ; CHECK-NEXT:    ret <4 x i32> [[T5]]
196   %t0 = bitcast <2 x i64> %a to <4 x float>
197   %t1 = bitcast <2 x i64> %b to <4 x float>
198   %t2 = fcmp olt <4 x float> %t0, %t1
199   %t3 = bitcast <2 x i64> %a to <4 x i32>
200   %t4 = bitcast <2 x i64> %b to <4 x i32>
201   %t5 = select <4 x i1> %t2, <4 x i32> %t3, <4 x i32> %t4
202   ret <4 x i32> %t5
205 ; Integer cmp should have the same transforms.
207 define <4 x float> @bitcasts_icmp(<2 x i64> %a, <2 x i64> %b) {
208 ; CHECK-LABEL: @bitcasts_icmp(
209 ; CHECK-NEXT:    [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
210 ; CHECK-NEXT:    [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x i32>
211 ; CHECK-NEXT:    [[T2:%.*]] = icmp slt <4 x i32> [[T1]], [[T0]]
212 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[T2]], <4 x i32> [[T0]], <4 x i32> [[T1]]
213 ; CHECK-NEXT:    [[T5:%.*]] = bitcast <4 x i32> [[TMP1]] to <4 x float>
214 ; CHECK-NEXT:    ret <4 x float> [[T5]]
216   %t0 = bitcast <2 x i64> %a to <4 x i32>
217   %t1 = bitcast <2 x i64> %b to <4 x i32>
218   %t2 = icmp slt <4 x i32> %t1, %t0
219   %t3 = bitcast <2 x i64> %a to <4 x float>
220   %t4 = bitcast <2 x i64> %b to <4 x float>
221   %t5 = select <4 x i1> %t2, <4 x float> %t3, <4 x float> %t4
222   ret <4 x float> %t5
225 ; SMIN(SMIN(X, 11), 92) -> SMIN(X, 11)
226 define i32 @test68(i32 %x) {
227 ; CHECK-LABEL: @test68(
228 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 11
229 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 11
230 ; CHECK-NEXT:    ret i32 [[COND]]
232   %cmp = icmp slt i32 11, %x
233   %cond = select i1 %cmp, i32 11, i32 %x
234   %cmp3 = icmp slt i32 92, %cond
235   %retval = select i1 %cmp3, i32 92, i32 %cond
236   ret i32 %retval
239 define <2 x i32> @test68vec(<2 x i32> %x) {
240 ; CHECK-LABEL: @test68vec(
241 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 11, i32 11>
242 ; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> <i32 11, i32 11>
243 ; CHECK-NEXT:    ret <2 x i32> [[COND]]
245   %cmp = icmp slt <2 x i32> <i32 11, i32 11>, %x
246   %cond = select <2 x i1> %cmp, <2 x i32> <i32 11, i32 11>, <2 x i32> %x
247   %cmp3 = icmp slt <2 x i32> <i32 92, i32 92>, %cond
248   %retval = select <2 x i1> %cmp3, <2 x i32> <i32 92, i32 92>, <2 x i32> %cond
249   ret <2 x i32> %retval
252 ; MIN(MIN(X, 24), 83) -> MIN(X, 24)
253 define i32 @test69(i32 %x) {
254 ; CHECK-LABEL: @test69(
255 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], 24
256 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 24
257 ; CHECK-NEXT:    ret i32 [[COND]]
259   %cmp = icmp ult i32 24, %x
260   %cond = select i1 %cmp, i32 24, i32 %x
261   %cmp3 = icmp ult i32 83, %cond
262   %retval = select i1 %cmp3, i32 83, i32 %cond
263   ret i32 %retval
266 ; SMAX(SMAX(X, 75), 36) -> SMAX(X, 75)
267 define i32 @test70(i32 %x) {
268 ; CHECK-LABEL: @test70(
269 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], 75
270 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 75
271 ; CHECK-NEXT:    ret i32 [[COND]]
273   %cmp = icmp slt i32 %x, 75
274   %cond = select i1 %cmp, i32 75, i32 %x
275   %cmp3 = icmp slt i32 %cond, 36
276   %retval = select i1 %cmp3, i32 36, i32 %cond
277   ret i32 %retval
280 ; MAX(MAX(X, 68), 47) -> MAX(X, 68)
281 define i32 @test71(i32 %x) {
282 ; CHECK-LABEL: @test71(
283 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 68
284 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 68
285 ; CHECK-NEXT:    ret i32 [[COND]]
287   %cmp = icmp ult i32 %x, 68
288   %cond = select i1 %cmp, i32 68, i32 %x
289   %cmp3 = icmp ult i32 %cond, 47
290   %retval = select i1 %cmp3, i32 47, i32 %cond
291   ret i32 %retval
294 ; SMIN(SMIN(X, 92), 11) -> SMIN(X, 11)
295 define i32 @test72(i32 %x) {
296 ; CHECK-LABEL: @test72(
297 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 11
298 ; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 11
299 ; CHECK-NEXT:    ret i32 [[RETVAL]]
301   %cmp = icmp sgt i32 %x, 92
302   %cond = select i1 %cmp, i32 92, i32 %x
303   %cmp3 = icmp sgt i32 %cond, 11
304   %retval = select i1 %cmp3, i32 11, i32 %cond
305   ret i32 %retval
308 define <2 x i32> @test72vec(<2 x i32> %x) {
309 ; CHECK-LABEL: @test72vec(
310 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 11, i32 11>
311 ; CHECK-NEXT:    [[RETVAL:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> <i32 11, i32 11>
312 ; CHECK-NEXT:    ret <2 x i32> [[RETVAL]]
314   %cmp = icmp sgt <2 x i32> %x, <i32 92, i32 92>
315   %cond = select <2 x i1> %cmp, <2 x i32> <i32 92, i32 92>, <2 x i32> %x
316   %cmp3 = icmp sgt <2 x i32> %cond, <i32 11, i32 11>
317   %retval = select <2 x i1> %cmp3, <2 x i32> <i32 11, i32 11>, <2 x i32> %cond
318   ret <2 x i32> %retval
321 ; MIN(MIN(X, 83), 24) -> MIN(X, 24)
322 define i32 @test73(i32 %x) {
323 ; CHECK-LABEL: @test73(
324 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], 24
325 ; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 24
326 ; CHECK-NEXT:    ret i32 [[RETVAL]]
328   %cmp = icmp ugt i32 %x, 83
329   %cond = select i1 %cmp, i32 83, i32 %x
330   %cmp3 = icmp ugt i32 %cond, 24
331   %retval = select i1 %cmp3, i32 24, i32 %cond
332   ret i32 %retval
335 ; SMAX(SMAX(X, 36), 75) -> SMAX(X, 75)
336 define i32 @test74(i32 %x) {
337 ; CHECK-LABEL: @test74(
338 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], 75
339 ; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 75
340 ; CHECK-NEXT:    ret i32 [[RETVAL]]
342   %cmp = icmp slt i32 %x, 36
343   %cond = select i1 %cmp, i32 36, i32 %x
344   %cmp3 = icmp slt i32 %cond, 75
345   %retval = select i1 %cmp3, i32 75, i32 %cond
346   ret i32 %retval
349 ; MAX(MAX(X, 47), 68) -> MAX(X, 68)
350 define i32 @test75(i32 %x) {
351 ; CHECK-LABEL: @test75(
352 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 68
353 ; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 68
354 ; CHECK-NEXT:    ret i32 [[RETVAL]]
356   %cmp = icmp ult i32 %x, 47
357   %cond = select i1 %cmp, i32 47, i32 %x
358   %cmp3 = icmp ult i32 %cond, 68
359   %retval = select i1 %cmp3, i32 68, i32 %cond
360   ret i32 %retval
363 ; The next 10 tests are value clamping with constants:
364 ; https://llvm.org/bugs/show_bug.cgi?id=31693
366 ; (X <s C1) ? C1 : SMIN(X, C2) ==> SMAX(SMIN(X, C2), C1)
368 define i32 @clamp_signed1(i32 %x) {
369 ; CHECK-LABEL: @clamp_signed1(
370 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X:%.*]], 255
371 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 255
372 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[MIN]], 15
373 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 [[MIN]], i32 15
374 ; CHECK-NEXT:    ret i32 [[R]]
376   %cmp2 = icmp slt i32 %x, 255
377   %min = select i1 %cmp2, i32 %x, i32 255
378   %cmp1 = icmp slt i32 %x, 15
379   %r = select i1 %cmp1, i32 15, i32 %min
380   ret i32 %r
383 ; (X >s C1) ? C1 : SMAX(X, C2) ==> SMIN(SMAX(X, C2), C1)
385 define i32 @clamp_signed2(i32 %x) {
386 ; CHECK-LABEL: @clamp_signed2(
387 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X:%.*]], 15
388 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 15
389 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[MAX]], 255
390 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 [[MAX]], i32 255
391 ; CHECK-NEXT:    ret i32 [[R]]
393   %cmp2 = icmp sgt i32 %x, 15
394   %max = select i1 %cmp2, i32 %x, i32 15
395   %cmp1 = icmp sgt i32 %x, 255
396   %r = select i1 %cmp1, i32 255, i32 %max
397   ret i32 %r
400 ; (X >s C1) ? SMIN(X, C2) : C1 ==> SMAX(SMIN(X, C2), C1)
402 define i32 @clamp_signed3(i32 %x) {
403 ; CHECK-LABEL: @clamp_signed3(
404 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X:%.*]], 255
405 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 255
406 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[MIN]], 15
407 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 [[MIN]], i32 15
408 ; CHECK-NEXT:    ret i32 [[R]]
410   %cmp2 = icmp slt i32 %x, 255
411   %min = select i1 %cmp2, i32 %x, i32 255
412   %cmp1 = icmp sgt i32 %x, 15
413   %r = select i1 %cmp1, i32 %min, i32 15
414   ret i32 %r
417 ; (X <s C1) ? SMAX(X, C2) : C1 ==> SMIN(SMAX(X, C1), C2)
419 define i32 @clamp_signed4(i32 %x) {
420 ; CHECK-LABEL: @clamp_signed4(
421 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X:%.*]], 15
422 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 15
423 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[MAX]], 255
424 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 [[MAX]], i32 255
425 ; CHECK-NEXT:    ret i32 [[R]]
427   %cmp2 = icmp sgt i32 %x, 15
428   %max = select i1 %cmp2, i32 %x, i32 15
429   %cmp1 = icmp slt i32 %x, 255
430   %r = select i1 %cmp1, i32 %max, i32 255
431   ret i32 %r
434 ; (X <u C1) ? C1 : UMIN(X, C2) ==> UMAX(UMIN(X, C2), C1)
436 define i32 @clamp_unsigned1(i32 %x) {
437 ; CHECK-LABEL: @clamp_unsigned1(
438 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[X:%.*]], 255
439 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 255
440 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[MIN]], 15
441 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 [[MIN]], i32 15
442 ; CHECK-NEXT:    ret i32 [[R]]
444   %cmp2 = icmp ult i32 %x, 255
445   %min = select i1 %cmp2, i32 %x, i32 255
446   %cmp1 = icmp ult i32 %x, 15
447   %r = select i1 %cmp1, i32 15, i32 %min
448   ret i32 %r
451 ; (X >u C1) ? C1 : UMAX(X, C2) ==> UMIN(UMAX(X, C2), C1)
453 define i32 @clamp_unsigned2(i32 %x) {
454 ; CHECK-LABEL: @clamp_unsigned2(
455 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[X:%.*]], 15
456 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 15
457 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[MAX]], 255
458 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 [[MAX]], i32 255
459 ; CHECK-NEXT:    ret i32 [[R]]
461   %cmp2 = icmp ugt i32 %x, 15
462   %max = select i1 %cmp2, i32 %x, i32 15
463   %cmp1 = icmp ugt i32 %x, 255
464   %r = select i1 %cmp1, i32 255, i32 %max
465   ret i32 %r
468 ; (X >u C1) ? UMIN(X, C2) : C1 ==> UMAX(UMIN(X, C2), C1)
470 define i32 @clamp_unsigned3(i32 %x) {
471 ; CHECK-LABEL: @clamp_unsigned3(
472 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[X:%.*]], 255
473 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 255
474 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[MIN]], 15
475 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 [[MIN]], i32 15
476 ; CHECK-NEXT:    ret i32 [[R]]
478   %cmp2 = icmp ult i32 %x, 255
479   %min = select i1 %cmp2, i32 %x, i32 255
480   %cmp1 = icmp ugt i32 %x, 15
481   %r = select i1 %cmp1, i32 %min, i32 15
482   ret i32 %r
485 ; (X <u C1) ? UMAX(X, C2) : C1 ==> UMIN(UMAX(X, C2), C1)
487 define i32 @clamp_unsigned4(i32 %x) {
488 ; CHECK-LABEL: @clamp_unsigned4(
489 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[X:%.*]], 15
490 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 15
491 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[MAX]], 255
492 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 [[MAX]], i32 255
493 ; CHECK-NEXT:    ret i32 [[R]]
495   %cmp2 = icmp ugt i32 %x, 15
496   %max = select i1 %cmp2, i32 %x, i32 15
497   %cmp1 = icmp ult i32 %x, 255
498   %r = select i1 %cmp1, i32 %max, i32 255
499   ret i32 %r
502 ; Check that clamp is recognized and there is no infinite
503 ; loop because of reverse cmp transformation:
504 ; (icmp sgt smin(PositiveA, B) 0) -> (icmp sgt B 0)
505 define i32 @clamp_check_for_no_infinite_loop1(i32 %i) {
506 ; CHECK-LABEL: @clamp_check_for_no_infinite_loop1(
507 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I:%.*]], 255
508 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[I]], i32 255
509 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SEL1]], 0
510 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[TMP1]], i32 [[SEL1]], i32 0
511 ; CHECK-NEXT:    ret i32 [[RES]]
513   %cmp1 = icmp slt i32 %i, 255
514   %sel1 = select i1 %cmp1, i32 %i, i32 255
515   %cmp2 = icmp slt i32 %i, 0
516   %res = select i1 %cmp2, i32 0, i32 %sel1
517   ret i32 %res
519 ; Check that there is no infinite loop in case of:
520 ; (icmp slt smax(NegativeA, B) 0) -> (icmp slt B 0)
521 define i32 @clamp_check_for_no_infinite_loop2(i32 %i) {
522 ; CHECK-LABEL: @clamp_check_for_no_infinite_loop2(
523 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[I:%.*]], -255
524 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[I]], i32 -255
525 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[SEL1]], 0
526 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[TMP1]], i32 [[SEL1]], i32 0
527 ; CHECK-NEXT:    ret i32 [[RES]]
529   %cmp1 = icmp sgt i32 %i, -255
530   %sel1 = select i1 %cmp1, i32 %i, i32 -255
531   %cmp2 = icmp slt i32 %i, 0
532   %res = select i1 %cmp2, i32 %sel1, i32 0
533   ret i32 %res
536 ; Check that there is no infinite loop because of reverse cmp transformation:
537 ; (icmp slt smax(PositiveA, B) 2) -> (icmp eq B 1)
538 define i32 @clamp_check_for_no_infinite_loop3(i32 %i) {
539 ; CHECK-LABEL: @clamp_check_for_no_infinite_loop3(
540 ; CHECK-NEXT:    [[I2:%.*]] = icmp sgt i32 [[I:%.*]], 1
541 ; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i32 [[I]], i32 1
542 ; CHECK-NEXT:    br i1 true, label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]]
543 ; CHECK:       truelabel:
544 ; CHECK-NEXT:    [[I5:%.*]] = icmp slt i32 [[I3]], 2
545 ; CHECK-NEXT:    [[I6:%.*]] = select i1 [[I5]], i32 [[I3]], i32 2
546 ; CHECK-NEXT:    [[I7:%.*]] = shl nuw nsw i32 [[I6]], 2
547 ; CHECK-NEXT:    ret i32 [[I7]]
548 ; CHECK:       falselabel:
549 ; CHECK-NEXT:    ret i32 0
552   %i2 = icmp sgt i32 %i, 1
553   %i3 = select i1 %i2, i32 %i, i32 1
554   %i4 = icmp sgt i32 %i3, 0
555   br i1 %i4, label %truelabel, label %falselabel
557 truelabel: ; %i<=1, %i3>0
558   %i5 = icmp slt i32 %i3, 2
559   %i6 = select i1 %i5, i32 %i3, i32 2
560   %i7 = shl nuw nsw i32 %i6, 2
561   ret i32 %i7
563 falselabel:
564   ret i32 0
567 ; The next 3 min tests should canonicalize to the same form...and not infinite loop.
569 define double @PR31751_umin1(i32 %x) {
570 ; CHECK-LABEL: @PR31751_umin1(
571 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], 2147483647
572 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 2147483647
573 ; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[SEL]] to double
574 ; CHECK-NEXT:    ret double [[CONV]]
576   %cmp = icmp slt i32 %x, 0
577   %sel = select i1 %cmp, i32 2147483647, i32 %x
578   %conv = sitofp i32 %sel to double
579   ret double %conv
582 define double @PR31751_umin2(i32 %x) {
583 ; CHECK-LABEL: @PR31751_umin2(
584 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 2147483647
585 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[X]], i32 2147483647
586 ; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[SEL]] to double
587 ; CHECK-NEXT:    ret double [[CONV]]
589   %cmp = icmp ult i32 %x, 2147483647
590   %sel = select i1 %cmp, i32 %x, i32 2147483647
591   %conv = sitofp i32 %sel to double
592   ret double %conv
595 define double @PR31751_umin3(i32 %x) {
596 ; CHECK-LABEL: @PR31751_umin3(
597 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], 2147483647
598 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 2147483647
599 ; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[SEL]] to double
600 ; CHECK-NEXT:    ret double [[CONV]]
602   %cmp = icmp ugt i32 %x, 2147483647
603   %sel = select i1 %cmp, i32 2147483647, i32 %x
604   %conv = sitofp i32 %sel to double
605   ret double %conv
608 ; The next 3 max tests should canonicalize to the same form...and not infinite loop.
610 define double @PR31751_umax1(i32 %x) {
611 ; CHECK-LABEL: @PR31751_umax1(
612 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], -2147483648
613 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -2147483648
614 ; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[SEL]] to double
615 ; CHECK-NEXT:    ret double [[CONV]]
617   %cmp = icmp sgt i32 %x, -1
618   %sel = select i1 %cmp, i32 2147483648, i32 %x
619   %conv = sitofp i32 %sel to double
620   ret double %conv
623 define double @PR31751_umax2(i32 %x) {
624 ; CHECK-LABEL: @PR31751_umax2(
625 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -2147483648
626 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[X]], i32 -2147483648
627 ; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[SEL]] to double
628 ; CHECK-NEXT:    ret double [[CONV]]
630   %cmp = icmp ugt i32 %x, 2147483648
631   %sel = select i1 %cmp, i32 %x, i32 2147483648
632   %conv = sitofp i32 %sel to double
633   ret double %conv
636 define double @PR31751_umax3(i32 %x) {
637 ; CHECK-LABEL: @PR31751_umax3(
638 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], -2147483648
639 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -2147483648
640 ; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[SEL]] to double
641 ; CHECK-NEXT:    ret double [[CONV]]
643   %cmp = icmp ult i32 %x, 2147483648
644   %sel = select i1 %cmp, i32 2147483648, i32 %x
645   %conv = sitofp i32 %sel to double
646   ret double %conv
649 ; The icmp/select form a canonical smax, so don't hide that by folding the final bitcast into the select.
651 define float @bitcast_scalar_smax(float %x, float %y) {
652 ; CHECK-LABEL: @bitcast_scalar_smax(
653 ; CHECK-NEXT:    [[BCX:%.*]] = bitcast float [[X:%.*]] to i32
654 ; CHECK-NEXT:    [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32
655 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[BCX]], [[BCY]]
656 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[BCX]], i32 [[BCY]]
657 ; CHECK-NEXT:    [[BCS:%.*]] = bitcast i32 [[SEL]] to float
658 ; CHECK-NEXT:    ret float [[BCS]]
660   %bcx = bitcast float %x to i32
661   %bcy = bitcast float %y to i32
662   %cmp = icmp sgt i32 %bcx, %bcy
663   %sel = select i1 %cmp, i32 %bcx, i32 %bcy
664   %bcs = bitcast i32 %sel to float
665   ret float %bcs
668 ; FIXME: Create a canonical umax by bitcasting the select.
670 define float @bitcast_scalar_umax(float %x, float %y) {
671 ; CHECK-LABEL: @bitcast_scalar_umax(
672 ; CHECK-NEXT:    [[BCX:%.*]] = bitcast float [[X:%.*]] to i32
673 ; CHECK-NEXT:    [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32
674 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[BCX]], [[BCY]]
675 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[Y]]
676 ; CHECK-NEXT:    ret float [[SEL]]
678   %bcx = bitcast float %x to i32
679   %bcy = bitcast float %y to i32
680   %cmp = icmp ugt i32 %bcx, %bcy
681   %sel = select i1 %cmp, float %x, float %y
682   ret float %sel
685 ; PR32306 - https://bugs.llvm.org/show_bug.cgi?id=32306
686 ; The icmp/select form a canonical smin, so don't hide that by folding the final bitcast into the select.
688 define <8 x float> @bitcast_vector_smin(<8 x float> %x, <8 x float> %y) {
689 ; CHECK-LABEL: @bitcast_vector_smin(
690 ; CHECK-NEXT:    [[BCX:%.*]] = bitcast <8 x float> [[X:%.*]] to <8 x i32>
691 ; CHECK-NEXT:    [[BCY:%.*]] = bitcast <8 x float> [[Y:%.*]] to <8 x i32>
692 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <8 x i32> [[BCX]], [[BCY]]
693 ; CHECK-NEXT:    [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i32> [[BCX]], <8 x i32> [[BCY]]
694 ; CHECK-NEXT:    [[BCS:%.*]] = bitcast <8 x i32> [[SEL]] to <8 x float>
695 ; CHECK-NEXT:    ret <8 x float> [[BCS]]
697   %bcx = bitcast <8 x float> %x to <8 x i32>
698   %bcy = bitcast <8 x float> %y to <8 x i32>
699   %cmp = icmp slt <8 x i32> %bcx, %bcy
700   %sel = select <8 x i1> %cmp, <8 x i32> %bcx, <8 x i32> %bcy
701   %bcs = bitcast <8 x i32> %sel to <8 x float>
702   ret <8 x float> %bcs
705 ; FIXME: Create a canonical umin by bitcasting the select.
707 define <8 x float> @bitcast_vector_umin(<8 x float> %x, <8 x float> %y) {
708 ; CHECK-LABEL: @bitcast_vector_umin(
709 ; CHECK-NEXT:    [[BCX:%.*]] = bitcast <8 x float> [[X:%.*]] to <8 x i32>
710 ; CHECK-NEXT:    [[BCY:%.*]] = bitcast <8 x float> [[Y:%.*]] to <8 x i32>
711 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <8 x i32> [[BCX]], [[BCY]]
712 ; CHECK-NEXT:    [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x float> [[X]], <8 x float> [[Y]]
713 ; CHECK-NEXT:    ret <8 x float> [[SEL]]
715   %bcx = bitcast <8 x float> %x to <8 x i32>
716   %bcy = bitcast <8 x float> %y to <8 x i32>
717   %cmp = icmp slt <8 x i32> %bcx, %bcy
718   %sel = select <8 x i1> %cmp, <8 x float> %x, <8 x float> %y
719   ret <8 x float> %sel
722 ; Check that we look through cast and recognize min idiom.
724 define zeroext i8 @look_through_cast1(i32 %x) {
725 ; CHECK-LABEL: @look_through_cast1(
726 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 511
727 ; CHECK-NEXT:    [[RES1:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 511
728 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[RES1]] to i8
729 ; CHECK-NEXT:    ret i8 [[TMP2]]
731   %cmp1 = icmp slt i32 %x, 511
732   %x_trunc = trunc i32 %x to i8
733   %res = select i1 %cmp1, i8 %x_trunc, i8 255
734   ret i8 %res
737 ; Check that we look through cast but min is not recognized.
739 define zeroext i8 @look_through_cast2(i32 %x) {
740 ; CHECK-LABEL: @look_through_cast2(
741 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 510
742 ; CHECK-NEXT:    [[X_TRUNC:%.*]] = trunc i32 [[X]] to i8
743 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP1]], i8 [[X_TRUNC]], i8 -1
744 ; CHECK-NEXT:    ret i8 [[RES]]
746   %cmp1 = icmp slt i32 %x, 510
747   %x_trunc = trunc i32 %x to i8
748   %res = select i1 %cmp1, i8 %x_trunc, i8 255
749   ret i8 %res
752 define <2 x i8> @min_through_cast_vec1(<2 x i32> %x) {
753 ; CHECK-LABEL: @min_through_cast_vec1(
754 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 510, i32 511>
755 ; CHECK-NEXT:    [[RES1:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> <i32 510, i32 511>
756 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i32> [[RES1]] to <2 x i8>
757 ; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
759   %cmp = icmp slt <2 x i32> %x, <i32 510, i32 511>
760   %x_trunc = trunc <2 x i32> %x to <2 x i8>
761   %res = select <2 x i1> %cmp, <2 x i8> %x_trunc, <2 x i8> <i8 254, i8 255>
762   ret <2 x i8> %res
765 define <2 x i8> @min_through_cast_vec2(<2 x i32> %x) {
766 ; CHECK-LABEL: @min_through_cast_vec2(
767 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 511, i32 511>
768 ; CHECK-NEXT:    [[RES1:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> <i32 511, i32 511>
769 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i32> [[RES1]] to <2 x i8>
770 ; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
772   %cmp = icmp slt <2 x i32> %x, <i32 511, i32 511>
773   %x_trunc = trunc <2 x i32> %x to <2 x i8>
774   %res = select <2 x i1> %cmp, <2 x i8> %x_trunc, <2 x i8> <i8 255, i8 255>
775   ret <2 x i8> %res
778 ; Remove a min/max op in a sequence with a common operand.
779 ; PR35717: https://bugs.llvm.org/show_bug.cgi?id=35717
781 ; min(min(a, b), min(b, c)) --> min(min(a, b), c)
783 define i32 @common_factor_smin(i32 %a, i32 %b, i32 %c) {
784 ; CHECK-LABEL: @common_factor_smin(
785 ; CHECK-NEXT:    [[CMP_AB:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
786 ; CHECK-NEXT:    [[MIN_AB:%.*]] = select i1 [[CMP_AB]], i32 [[A]], i32 [[B]]
787 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[MIN_AB]], [[C:%.*]]
788 ; CHECK-NEXT:    [[MIN_ABC:%.*]] = select i1 [[TMP1]], i32 [[MIN_AB]], i32 [[C]]
789 ; CHECK-NEXT:    ret i32 [[MIN_ABC]]
791   %cmp_ab = icmp slt i32 %a, %b
792   %min_ab = select i1 %cmp_ab, i32 %a, i32 %b
793   %cmp_bc = icmp slt i32 %b, %c
794   %min_bc = select i1 %cmp_bc, i32 %b, i32 %c
795   %cmp_ab_bc = icmp slt i32 %min_ab, %min_bc
796   %min_abc = select i1 %cmp_ab_bc, i32 %min_ab, i32 %min_bc
797   ret i32 %min_abc
800 ; max(max(a, b), max(c, b)) --> max(max(a, b), c)
802 define <2 x i32> @common_factor_smax(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
803 ; CHECK-LABEL: @common_factor_smax(
804 ; CHECK-NEXT:    [[CMP_AB:%.*]] = icmp sgt <2 x i32> [[A:%.*]], [[B:%.*]]
805 ; CHECK-NEXT:    [[MAX_AB:%.*]] = select <2 x i1> [[CMP_AB]], <2 x i32> [[A]], <2 x i32> [[B]]
806 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i32> [[MAX_AB]], [[C:%.*]]
807 ; CHECK-NEXT:    [[MAX_ABC:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[MAX_AB]], <2 x i32> [[C]]
808 ; CHECK-NEXT:    ret <2 x i32> [[MAX_ABC]]
810   %cmp_ab = icmp sgt <2 x i32> %a, %b
811   %max_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b
812   %cmp_cb = icmp sgt <2 x i32> %c, %b
813   %max_cb = select <2 x i1> %cmp_cb, <2 x i32> %c, <2 x i32> %b
814   %cmp_ab_cb = icmp sgt <2 x i32> %max_ab, %max_cb
815   %max_abc = select <2 x i1> %cmp_ab_cb, <2 x i32> %max_ab, <2 x i32> %max_cb
816   ret <2 x i32> %max_abc
819 ; min(min(b, c), min(a, b)) --> min(min(b, c), a)
821 define <2 x i32> @common_factor_umin(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
822 ; CHECK-LABEL: @common_factor_umin(
823 ; CHECK-NEXT:    [[CMP_BC:%.*]] = icmp ult <2 x i32> [[B:%.*]], [[C:%.*]]
824 ; CHECK-NEXT:    [[MIN_BC:%.*]] = select <2 x i1> [[CMP_BC]], <2 x i32> [[B]], <2 x i32> [[C]]
825 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult <2 x i32> [[MIN_BC]], [[A:%.*]]
826 ; CHECK-NEXT:    [[MIN_ABC:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[MIN_BC]], <2 x i32> [[A]]
827 ; CHECK-NEXT:    ret <2 x i32> [[MIN_ABC]]
829   %cmp_bc = icmp ult <2 x i32> %b, %c
830   %min_bc = select <2 x i1> %cmp_bc, <2 x i32> %b, <2 x i32> %c
831   %cmp_ab = icmp ult <2 x i32> %a, %b
832   %min_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b
833   %cmp_bc_ab = icmp ult <2 x i32> %min_bc, %min_ab
834   %min_abc = select <2 x i1> %cmp_bc_ab, <2 x i32> %min_bc, <2 x i32> %min_ab
835   ret <2 x i32> %min_abc
838 ; max(max(b, c), max(b, a)) --> max(max(b, c), a)
840 define i32 @common_factor_umax(i32 %a, i32 %b, i32 %c) {
841 ; CHECK-LABEL: @common_factor_umax(
842 ; CHECK-NEXT:    [[CMP_BC:%.*]] = icmp ugt i32 [[B:%.*]], [[C:%.*]]
843 ; CHECK-NEXT:    [[MAX_BC:%.*]] = select i1 [[CMP_BC]], i32 [[B]], i32 [[C]]
844 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[MAX_BC]], [[A:%.*]]
845 ; CHECK-NEXT:    [[MAX_ABC:%.*]] = select i1 [[TMP1]], i32 [[MAX_BC]], i32 [[A]]
846 ; CHECK-NEXT:    ret i32 [[MAX_ABC]]
848   %cmp_bc = icmp ugt i32 %b, %c
849   %max_bc = select i1 %cmp_bc, i32 %b, i32 %c
850   %cmp_ba = icmp ugt i32 %b, %a
851   %max_ba = select i1 %cmp_ba, i32 %b, i32 %a
852   %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba
853   %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba
854   ret i32 %max_abc
857 declare void @extra_use(i32)
859 define i32 @common_factor_umax_extra_use_lhs(i32 %a, i32 %b, i32 %c) {
860 ; CHECK-LABEL: @common_factor_umax_extra_use_lhs(
861 ; CHECK-NEXT:    [[CMP_BC:%.*]] = icmp ugt i32 [[B:%.*]], [[C:%.*]]
862 ; CHECK-NEXT:    [[MAX_BC:%.*]] = select i1 [[CMP_BC]], i32 [[B]], i32 [[C]]
863 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[MAX_BC]], [[A:%.*]]
864 ; CHECK-NEXT:    [[MAX_ABC:%.*]] = select i1 [[TMP1]], i32 [[MAX_BC]], i32 [[A]]
865 ; CHECK-NEXT:    call void @extra_use(i32 [[MAX_BC]])
866 ; CHECK-NEXT:    ret i32 [[MAX_ABC]]
868   %cmp_bc = icmp ugt i32 %b, %c
869   %max_bc = select i1 %cmp_bc, i32 %b, i32 %c
870   %cmp_ba = icmp ugt i32 %b, %a
871   %max_ba = select i1 %cmp_ba, i32 %b, i32 %a
872   %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba
873   %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba
874   call void @extra_use(i32 %max_bc)
875   ret i32 %max_abc
878 define i32 @common_factor_umax_extra_use_rhs(i32 %a, i32 %b, i32 %c) {
879 ; CHECK-LABEL: @common_factor_umax_extra_use_rhs(
880 ; CHECK-NEXT:    [[CMP_BA:%.*]] = icmp ugt i32 [[B:%.*]], [[A:%.*]]
881 ; CHECK-NEXT:    [[MAX_BA:%.*]] = select i1 [[CMP_BA]], i32 [[B]], i32 [[A]]
882 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[MAX_BA]], [[C:%.*]]
883 ; CHECK-NEXT:    [[MAX_ABC:%.*]] = select i1 [[TMP1]], i32 [[MAX_BA]], i32 [[C]]
884 ; CHECK-NEXT:    call void @extra_use(i32 [[MAX_BA]])
885 ; CHECK-NEXT:    ret i32 [[MAX_ABC]]
887   %cmp_bc = icmp ugt i32 %b, %c
888   %max_bc = select i1 %cmp_bc, i32 %b, i32 %c
889   %cmp_ba = icmp ugt i32 %b, %a
890   %max_ba = select i1 %cmp_ba, i32 %b, i32 %a
891   %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba
892   %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba
893   call void @extra_use(i32 %max_ba)
894   ret i32 %max_abc
897 define i32 @common_factor_umax_extra_use_both(i32 %a, i32 %b, i32 %c) {
898 ; CHECK-LABEL: @common_factor_umax_extra_use_both(
899 ; CHECK-NEXT:    [[CMP_BC:%.*]] = icmp ugt i32 [[B:%.*]], [[C:%.*]]
900 ; CHECK-NEXT:    [[MAX_BC:%.*]] = select i1 [[CMP_BC]], i32 [[B]], i32 [[C]]
901 ; CHECK-NEXT:    [[CMP_BA:%.*]] = icmp ugt i32 [[B]], [[A:%.*]]
902 ; CHECK-NEXT:    [[MAX_BA:%.*]] = select i1 [[CMP_BA]], i32 [[B]], i32 [[A]]
903 ; CHECK-NEXT:    [[CMP_BC_BA:%.*]] = icmp ugt i32 [[MAX_BC]], [[MAX_BA]]
904 ; CHECK-NEXT:    [[MAX_ABC:%.*]] = select i1 [[CMP_BC_BA]], i32 [[MAX_BC]], i32 [[MAX_BA]]
905 ; CHECK-NEXT:    call void @extra_use(i32 [[MAX_BC]])
906 ; CHECK-NEXT:    call void @extra_use(i32 [[MAX_BA]])
907 ; CHECK-NEXT:    ret i32 [[MAX_ABC]]
909   %cmp_bc = icmp ugt i32 %b, %c
910   %max_bc = select i1 %cmp_bc, i32 %b, i32 %c
911   %cmp_ba = icmp ugt i32 %b, %a
912   %max_ba = select i1 %cmp_ba, i32 %b, i32 %a
913   %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba
914   %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba
915   call void @extra_use(i32 %max_bc)
916   call void @extra_use(i32 %max_ba)
917   ret i32 %max_abc
920 ; This would assert. Don't assume that earlier min/max types match a possible later min/max.
922 define float @not_min_of_min(i8 %i, float %x) {
923 ; CHECK-LABEL: @not_min_of_min(
924 ; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp fast oge float [[X:%.*]], 1.000000e+00
925 ; CHECK-NEXT:    [[MIN1:%.*]] = select i1 [[CMP1_INV]], float 1.000000e+00, float [[X]]
926 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp fast oge float [[X]], 2.000000e+00
927 ; CHECK-NEXT:    [[MIN2:%.*]] = select i1 [[CMP2_INV]], float 2.000000e+00, float [[X]]
928 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i8 [[I:%.*]], 16
929 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP3]], float [[MIN1]], float [[MIN2]]
930 ; CHECK-NEXT:    ret float [[R]]
932   %cmp1 = fcmp fast ult float %x, 1.0
933   %min1 = select i1 %cmp1, float %x, float 1.0
934   %cmp2 = fcmp fast ult float %x, 2.0
935   %min2 = select i1 %cmp2, float %x, float 2.0
936   %cmp3 = icmp ult i8 %i, 16
937   %r = select i1 %cmp3, float %min1, float %min2
938   ret float %r
941 define i32 @add_umin(i32 %x) {
942 ; CHECK-LABEL: @add_umin(
943 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], 27
944 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 27
945 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[TMP2]], 15
946 ; CHECK-NEXT:    ret i32 [[R]]
948   %a = add nuw i32 %x, 15
949   %c = icmp ult i32 %a, 42
950   %r = select i1 %c, i32 %a, i32 42
951   ret i32 %r
954 define i32 @add_umin_constant_limit(i32 %x) {
955 ; CHECK-LABEL: @add_umin_constant_limit(
956 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 0
957 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 41, i32 42
958 ; CHECK-NEXT:    ret i32 [[R]]
960   %a = add nuw i32 %x, 41
961   %c = icmp ult i32 %a, 42
962   %r = select i1 %c, i32 %a, i32 42
963   ret i32 %r
966 ; Negative test
967 ; TODO: assert that instsimplify always gets this?
969 define i32 @add_umin_simplify(i32 %x) {
970 ; CHECK-LABEL: @add_umin_simplify(
971 ; CHECK-NEXT:    ret i32 42
973   %a = add nuw i32 %x, 42
974   %c = icmp ult i32 %a, 42
975   %r = select i1 %c, i32 %a, i32 42
976   ret i32 %r
979 ; Negative test
980 ; TODO: assert that instsimplify always gets this?
982 define i32 @add_umin_simplify2(i32 %x) {
983 ; CHECK-LABEL: @add_umin_simplify2(
984 ; CHECK-NEXT:    ret i32 42
986   %a = add nuw i32 %x, 43
987   %c = icmp ult i32 %a, 42
988   %r = select i1 %c, i32 %a, i32 42
989   ret i32 %r
992 ; Negative test
994 define i32 @add_umin_wrong_pred(i32 %x) {
995 ; CHECK-LABEL: @add_umin_wrong_pred(
996 ; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
997 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A]], 42
998 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
999 ; CHECK-NEXT:    ret i32 [[R]]
1001   %a = add nuw i32 %x, 15
1002   %c = icmp slt i32 %a, 42
1003   %r = select i1 %c, i32 %a, i32 42
1004   ret i32 %r
1007 ; Negative test
1009 define i32 @add_umin_wrong_wrap(i32 %x) {
1010 ; CHECK-LABEL: @add_umin_wrong_wrap(
1011 ; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1012 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A]], 42
1013 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1014 ; CHECK-NEXT:    ret i32 [[R]]
1016   %a = add nsw i32 %x, 15
1017   %c = icmp ult i32 %a, 42
1018   %r = select i1 %c, i32 %a, i32 42
1019   ret i32 %r
1022 ; Negative test
1024 define i32 @add_umin_extra_use(i32 %x, i32* %p) {
1025 ; CHECK-LABEL: @add_umin_extra_use(
1026 ; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1027 ; CHECK-NEXT:    store i32 [[A]], i32* [[P:%.*]], align 4
1028 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A]], 42
1029 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1030 ; CHECK-NEXT:    ret i32 [[R]]
1032   %a = add nuw i32 %x, 15
1033   store i32 %a, i32* %p
1034   %c = icmp ult i32 %a, 42
1035   %r = select i1 %c, i32 %a, i32 42
1036   ret i32 %r
1039 define <2 x i16> @add_umin_vec(<2 x i16> %x) {
1040 ; CHECK-LABEL: @add_umin_vec(
1041 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult <2 x i16> [[X:%.*]], <i16 225, i16 225>
1042 ; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i16> [[X]], <2 x i16> <i16 225, i16 225>
1043 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i16> [[TMP2]], <i16 15, i16 15>
1044 ; CHECK-NEXT:    ret <2 x i16> [[R]]
1046   %a = add nuw <2 x i16> %x, <i16 15, i16 15>
1047   %c = icmp ult <2 x i16> %a, <i16 240, i16 240>
1048   %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240>
1049   ret <2 x i16> %r
1052 define i37 @add_umax(i37 %x) {
1053 ; CHECK-LABEL: @add_umax(
1054 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i37 [[X:%.*]], 37
1055 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i37 [[X]], i37 37
1056 ; CHECK-NEXT:    [[R:%.*]] = add nuw i37 [[TMP2]], 5
1057 ; CHECK-NEXT:    ret i37 [[R]]
1059   %a = add nuw i37 %x, 5
1060   %c = icmp ugt i37 %a, 42
1061   %r = select i1 %c, i37 %a, i37 42
1062   ret i37 %r
1065 define i37 @add_umax_constant_limit(i37 %x) {
1066 ; CHECK-LABEL: @add_umax_constant_limit(
1067 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i37 [[X:%.*]], 1
1068 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i37 [[X]], i37 1
1069 ; CHECK-NEXT:    [[R:%.*]] = add nuw i37 [[TMP2]], 81
1070 ; CHECK-NEXT:    ret i37 [[R]]
1072   %a = add nuw i37 %x, 81
1073   %c = icmp ugt i37 %a, 82
1074   %r = select i1 %c, i37 %a, i37 82
1075   ret i37 %r
1078 ; Negative test
1079 ; TODO: assert that instsimplify always gets this?
1081 define i37 @add_umax_simplify(i37 %x) {
1082 ; CHECK-LABEL: @add_umax_simplify(
1083 ; CHECK-NEXT:    [[A:%.*]] = add i37 [[X:%.*]], 42
1084 ; CHECK-NEXT:    ret i37 [[A]]
1086   %a = add nuw i37 %x, 42
1087   %c = icmp ugt i37 %a, 42
1088   %r = select i1 %c, i37 %a, i37 42
1089   ret i37 %r
1092 ; Negative test
1093 ; TODO: assert that instsimplify always gets this?
1095 define i32 @add_umax_simplify2(i32 %x) {
1096 ; CHECK-LABEL: @add_umax_simplify2(
1097 ; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 57
1098 ; CHECK-NEXT:    ret i32 [[A]]
1100   %a = add nuw i32 %x, 57
1101   %c = icmp ugt i32 %a, 56
1102   %r = select i1 %c, i32 %a, i32 56
1103   ret i32 %r
1106 ; Negative test
1108 define i32 @add_umax_wrong_pred(i32 %x) {
1109 ; CHECK-LABEL: @add_umax_wrong_pred(
1110 ; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1111 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], 42
1112 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1113 ; CHECK-NEXT:    ret i32 [[R]]
1115   %a = add nuw i32 %x, 15
1116   %c = icmp sgt i32 %a, 42
1117   %r = select i1 %c, i32 %a, i32 42
1118   ret i32 %r
1121 ; Negative test
1123 define i32 @add_umax_wrong_wrap(i32 %x) {
1124 ; CHECK-LABEL: @add_umax_wrong_wrap(
1125 ; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1126 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A]], 42
1127 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1128 ; CHECK-NEXT:    ret i32 [[R]]
1130   %a = add nsw i32 %x, 15
1131   %c = icmp ugt i32 %a, 42
1132   %r = select i1 %c, i32 %a, i32 42
1133   ret i32 %r
1136 ; Negative test
1138 define i32 @add_umax_extra_use(i32 %x, i32* %p) {
1139 ; CHECK-LABEL: @add_umax_extra_use(
1140 ; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1141 ; CHECK-NEXT:    store i32 [[A]], i32* [[P:%.*]], align 4
1142 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A]], 42
1143 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1144 ; CHECK-NEXT:    ret i32 [[R]]
1146   %a = add nuw i32 %x, 15
1147   store i32 %a, i32* %p
1148   %c = icmp ugt i32 %a, 42
1149   %r = select i1 %c, i32 %a, i32 42
1150   ret i32 %r
1153 define <2 x i33> @add_umax_vec(<2 x i33> %x) {
1154 ; CHECK-LABEL: @add_umax_vec(
1155 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt <2 x i33> [[X:%.*]], <i33 235, i33 235>
1156 ; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i33> [[X]], <2 x i33> <i33 235, i33 235>
1157 ; CHECK-NEXT:    [[R:%.*]] = add nuw <2 x i33> [[TMP2]], <i33 5, i33 5>
1158 ; CHECK-NEXT:    ret <2 x i33> [[R]]
1160   %a = add nuw <2 x i33> %x, <i33 5, i33 5>
1161   %c = icmp ugt <2 x i33> %a, <i33 240, i33 240>
1162   %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240>
1163   ret <2 x i33> %r
1166 define i8 @PR14613_umin(i8 %x) {
1167 ; CHECK-LABEL: @PR14613_umin(
1168 ; CHECK-NEXT:    [[U7:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 15)
1169 ; CHECK-NEXT:    ret i8 [[U7]]
1171   %u4 = zext i8 %x to i32
1172   %u5 = add nuw nsw i32 %u4, 15
1173   %u6 = icmp ult i32 %u5, 255
1174   %u7 = select i1 %u6, i32 %u5, i32 255
1175   %r = trunc i32 %u7 to i8
1176   ret i8 %r
1179 define i8 @PR14613_umax(i8 %x) {
1180 ; CHECK-LABEL: @PR14613_umax(
1181 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], -16
1182 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 -16
1183 ; CHECK-NEXT:    [[U7:%.*]] = add nsw i8 [[TMP2]], 15
1184 ; CHECK-NEXT:    ret i8 [[U7]]
1186   %u4 = zext i8 %x to i32
1187   %u5 = add nuw nsw i32 %u4, 15
1188   %u6 = icmp ugt i32 %u5, 255
1189   %u7 = select i1 %u6, i32 %u5, i32 255
1190   %r = trunc i32 %u7 to i8
1191   ret i8 %r
1194 define i32 @add_smin(i32 %x) {
1195 ; CHECK-LABEL: @add_smin(
1196 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 27
1197 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 27
1198 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP2]], 15
1199 ; CHECK-NEXT:    ret i32 [[R]]
1201   %a = add nsw i32 %x, 15
1202   %c = icmp slt i32 %a, 42
1203   %r = select i1 %c, i32 %a, i32 42
1204   ret i32 %r
1207 define i32 @add_smin_constant_limit(i32 %x) {
1208 ; CHECK-LABEL: @add_smin_constant_limit(
1209 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 2147483646
1210 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 2147483646
1211 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP2]], -3
1212 ; CHECK-NEXT:    ret i32 [[R]]
1214   %a = add nsw i32 %x, -3
1215   %c = icmp slt i32 %a, 2147483643
1216   %r = select i1 %c, i32 %a, i32 2147483643
1217   ret i32 %r
1220 ; Negative test
1221 ; TODO: assert that instsimplify always gets this?
1223 define i32 @add_smin_simplify(i32 %x) {
1224 ; CHECK-LABEL: @add_smin_simplify(
1225 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[X:%.*]], -3
1226 ; CHECK-NEXT:    ret i32 [[R]]
1228   %a = add nsw i32 %x, -3
1229   %c = icmp slt i32 %a, 2147483644
1230   %r = select i1 %c, i32 %a, i32 2147483644
1231   ret i32 %r
1234 ; Negative test
1235 ; TODO: assert that instsimplify always gets this?
1237 define i32 @add_smin_simplify2(i32 %x) {
1238 ; CHECK-LABEL: @add_smin_simplify2(
1239 ; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], -3
1240 ; CHECK-NEXT:    ret i32 [[A]]
1242   %a = add nsw i32 %x, -3
1243   %c = icmp slt i32 %a, 2147483645
1244   %r = select i1 %c, i32 %a, i32 2147483645
1245   ret i32 %r
1248 ; Negative test
1250 define i32 @add_smin_wrong_pred(i32 %x) {
1251 ; CHECK-LABEL: @add_smin_wrong_pred(
1252 ; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1253 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A]], 42
1254 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1255 ; CHECK-NEXT:    ret i32 [[R]]
1257   %a = add nsw i32 %x, 15
1258   %c = icmp ult i32 %a, 42
1259   %r = select i1 %c, i32 %a, i32 42
1260   ret i32 %r
1263 ; Negative test
1265 define i32 @add_smin_wrong_wrap(i32 %x) {
1266 ; CHECK-LABEL: @add_smin_wrong_wrap(
1267 ; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1268 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A]], 42
1269 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1270 ; CHECK-NEXT:    ret i32 [[R]]
1272   %a = add nuw i32 %x, 15
1273   %c = icmp slt i32 %a, 42
1274   %r = select i1 %c, i32 %a, i32 42
1275   ret i32 %r
1278 ; Negative test
1280 define i32 @add_smin_extra_use(i32 %x, i32* %p) {
1281 ; CHECK-LABEL: @add_smin_extra_use(
1282 ; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1283 ; CHECK-NEXT:    store i32 [[A]], i32* [[P:%.*]], align 4
1284 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A]], 42
1285 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1286 ; CHECK-NEXT:    ret i32 [[R]]
1288   %a = add nsw i32 %x, 15
1289   store i32 %a, i32* %p
1290   %c = icmp slt i32 %a, 42
1291   %r = select i1 %c, i32 %a, i32 42
1292   ret i32 %r
1295 define <2 x i16> @add_smin_vec(<2 x i16> %x) {
1296 ; CHECK-LABEL: @add_smin_vec(
1297 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i16> [[X:%.*]], <i16 225, i16 225>
1298 ; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i16> [[X]], <2 x i16> <i16 225, i16 225>
1299 ; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i16> [[TMP2]], <i16 15, i16 15>
1300 ; CHECK-NEXT:    ret <2 x i16> [[R]]
1302   %a = add nsw <2 x i16> %x, <i16 15, i16 15>
1303   %c = icmp slt <2 x i16> %a, <i16 240, i16 240>
1304   %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240>
1305   ret <2 x i16> %r
1308 define i37 @add_smax(i37 %x) {
1309 ; CHECK-LABEL: @add_smax(
1310 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i37 [[X:%.*]], 37
1311 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i37 [[X]], i37 37
1312 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i37 [[TMP2]], 5
1313 ; CHECK-NEXT:    ret i37 [[R]]
1315   %a = add nsw i37 %x, 5
1316   %c = icmp sgt i37 %a, 42
1317   %r = select i1 %c, i37 %a, i37 42
1318   ret i37 %r
1321 define i8 @add_smax_constant_limit(i8 %x) {
1322 ; CHECK-LABEL: @add_smax_constant_limit(
1323 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[X:%.*]], -127
1324 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 -127
1325 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[TMP2]], 125
1326 ; CHECK-NEXT:    ret i8 [[R]]
1328   %a = add nsw i8 %x, 125
1329   %c = icmp sgt i8 %a, -2
1330   %r = select i1 %c, i8 %a, i8 -2
1331   ret i8 %r
1334 ; Negative test
1335 ; TODO: assert that instsimplify always gets this?
1337 define i8 @add_smax_simplify(i8 %x) {
1338 ; CHECK-LABEL: @add_smax_simplify(
1339 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[X:%.*]], 126
1340 ; CHECK-NEXT:    ret i8 [[R]]
1342   %a = add nsw i8 %x, 126
1343   %c = icmp sgt i8 %a, -2
1344   %r = select i1 %c, i8 %a, i8 -2
1345   ret i8 %r
1348 ; Negative test
1349 ; TODO: assert that instsimplify always gets this?
1351 define i8 @add_smax_simplify2(i8 %x) {
1352 ; CHECK-LABEL: @add_smax_simplify2(
1353 ; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X:%.*]], 127
1354 ; CHECK-NEXT:    ret i8 [[A]]
1356   %a = add nsw i8 %x, 127
1357   %c = icmp sgt i8 %a, -2
1358   %r = select i1 %c, i8 %a, i8 -2
1359   ret i8 %r
1362 ; Negative test
1364 define i32 @add_smax_wrong_pred(i32 %x) {
1365 ; CHECK-LABEL: @add_smax_wrong_pred(
1366 ; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1367 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A]], 42
1368 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1369 ; CHECK-NEXT:    ret i32 [[R]]
1371   %a = add nsw i32 %x, 15
1372   %c = icmp ugt i32 %a, 42
1373   %r = select i1 %c, i32 %a, i32 42
1374   ret i32 %r
1377 ; Negative test
1379 define i32 @add_smax_wrong_wrap(i32 %x) {
1380 ; CHECK-LABEL: @add_smax_wrong_wrap(
1381 ; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1382 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], 42
1383 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1384 ; CHECK-NEXT:    ret i32 [[R]]
1386   %a = add nuw i32 %x, 15
1387   %c = icmp sgt i32 %a, 42
1388   %r = select i1 %c, i32 %a, i32 42
1389   ret i32 %r
1392 ; Negative test
1394 define i32 @add_smax_extra_use(i32 %x, i32* %p) {
1395 ; CHECK-LABEL: @add_smax_extra_use(
1396 ; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1397 ; CHECK-NEXT:    store i32 [[A]], i32* [[P:%.*]], align 4
1398 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], 42
1399 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 42
1400 ; CHECK-NEXT:    ret i32 [[R]]
1402   %a = add nsw i32 %x, 15
1403   store i32 %a, i32* %p
1404   %c = icmp sgt i32 %a, 42
1405   %r = select i1 %c, i32 %a, i32 42
1406   ret i32 %r
1409 define <2 x i33> @add_smax_vec(<2 x i33> %x) {
1410 ; CHECK-LABEL: @add_smax_vec(
1411 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i33> [[X:%.*]], <i33 235, i33 235>
1412 ; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i33> [[X]], <2 x i33> <i33 235, i33 235>
1413 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i33> [[TMP2]], <i33 5, i33 5>
1414 ; CHECK-NEXT:    ret <2 x i33> [[R]]
1416   %a = add nsw <2 x i33> %x, <i33 5, i33 5>
1417   %c = icmp sgt <2 x i33> %a, <i33 240, i33 240>
1418   %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240>
1419   ret <2 x i33> %r
1422 define i8 @PR14613_smin(i8 %x) {
1423 ; CHECK-LABEL: @PR14613_smin(
1424 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 40
1425 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 40
1426 ; CHECK-NEXT:    [[U7:%.*]] = add nsw i8 [[TMP2]], 15
1427 ; CHECK-NEXT:    ret i8 [[U7]]
1429   %u4 = sext i8 %x to i32
1430   %u5 = add nuw nsw i32 %u4, 15
1431   %u6 = icmp slt i32 %u5, 55
1432   %u7 = select i1 %u6, i32 %u5, i32 55
1433   %r = trunc i32 %u7 to i8
1434   ret i8 %r
1437 define i8 @PR14613_smax(i8 %x) {
1438 ; CHECK-LABEL: @PR14613_smax(
1439 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[X:%.*]], 40
1440 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 40
1441 ; CHECK-NEXT:    [[U7:%.*]] = add nuw i8 [[TMP2]], 15
1442 ; CHECK-NEXT:    ret i8 [[U7]]
1444   %u4 = sext i8 %x to i32
1445   %u5 = add nuw nsw i32 %u4, 15
1446   %u6 = icmp sgt i32 %u5, 55
1447   %u7 = select i1 %u6, i32 %u5, i32 55
1448   %r = trunc i32 %u7 to i8
1449   ret i8 %r