1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4; This is the canonical form for a type-changing min/max.
5define i64 @t1(i32 %a) {
6; CHECK-LABEL: @t1(
7; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 5)
8; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
9; CHECK-NEXT:    ret i64 [[TMP2]]
10;
11  %1 = icmp slt i32 %a, 5
12  %2 = select i1 %1, i32 %a, i32 5
13  %3 = sext i32 %2 to i64
14  ret i64 %3
15}
16
17; Check this is converted into canonical form, as above.
18define i64 @t2(i32 %a) {
19; CHECK-LABEL: @t2(
20; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 5)
21; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
22; CHECK-NEXT:    ret i64 [[TMP2]]
23;
24  %1 = icmp slt i32 %a, 5
25  %2 = sext i32 %a to i64
26  %3 = select i1 %1, i64 %2, i64 5
27  ret i64 %3
28}
29
30; Same as @t2, with flipped operands and zext instead of sext.
31define i64 @t3(i32 %a) {
32; CHECK-LABEL: @t3(
33; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[A:%.*]], i32 5)
34; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[TMP1]] to i64
35; CHECK-NEXT:    ret i64 [[TMP2]]
36;
37  %1 = icmp ult i32 %a, 5
38  %2 = zext i32 %a to i64
39  %3 = select i1 %1, i64 5, i64 %2
40  ret i64 %3
41}
42
43; Same again, with trunc.
44define i32 @t4(i64 %a) {
45; CHECK-LABEL: @t4(
46; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 5)
47; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
48; CHECK-NEXT:    ret i32 [[TMP2]]
49;
50  %1 = icmp slt i64 %a, 5
51  %2 = trunc i64 %a to i32
52  %3 = select i1 %1, i32 %2, i32 5
53  ret i32 %3
54}
55
56; Same as @t3, but with mismatched signedness between icmp and zext.
57define i64 @t5(i32 %a) {
58; CHECK-LABEL: @t5(
59; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 5)
60; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[TMP1]] to i64
61; CHECK-NEXT:    ret i64 [[TMP2]]
62;
63  %1 = icmp slt i32 %a, 5
64  %2 = zext i32 %a to i64
65  %3 = select i1 %1, i64 5, i64 %2
66  ret i64 %3
67}
68
69define float @t6(i32 %a) {
70; CHECK-LABEL: @t6(
71; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 0)
72; CHECK-NEXT:    [[TMP2:%.*]] = sitofp i32 [[TMP1]] to float
73; CHECK-NEXT:    ret float [[TMP2]]
74;
75  %1 = icmp slt i32 %a, 0
76  %2 = select i1 %1, i32 %a, i32 0
77  %3 = sitofp i32 %2 to float
78  ret float %3
79}
80
81define i16 @t7(i32 %a) {
82; CHECK-LABEL: @t7(
83; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 -32768)
84; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
85; CHECK-NEXT:    ret i16 [[TMP2]]
86;
87  %1 = icmp slt i32 %a, -32768
88  %2 = trunc i32 %a to i16
89  %3 = select i1 %1, i16 %2, i16 -32768
90  ret i16 %3
91}
92
93; Just check for no infinite loop. InstSimplify liked to
94; "simplify" -32767 by removing all the sign bits,
95; which led to a canonicalization fight between different
96; parts of instcombine.
97define i32 @t8(i64 %a, i32 %b) {
98; CHECK-LABEL: @t8(
99; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 -32767)
100; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
101; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[B:%.*]], 42
102; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP2]], [[B]]
103; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP3]], i1 true, i1 [[TMP4]]
104; CHECK-NEXT:    [[TMP6:%.*]] = zext i1 [[TMP5]] to i32
105; CHECK-NEXT:    ret i32 [[TMP6]]
106;
107  %1 = icmp slt i64 %a, -32767
108  %2 = select i1 %1, i64 %a, i64 -32767
109  %3 = trunc i64 %2 to i32
110  %4 = icmp slt i32 %b, 42
111  %5 = select i1 %4, i32 42, i32 %3
112  %6 = icmp ne i32 %5, %b
113  %7 = zext i1 %6 to i32
114  ret i32 %7
115}
116
117; Ensure this doesn't get converted to a min/max.
118define i64 @t9(i32 %a) {
119; CHECK-LABEL: @t9(
120; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], -1
121; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[A]] to i64
122; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i64 [[TMP2]], i64 4294967295
123; CHECK-NEXT:    ret i64 [[TMP3]]
124;
125  %1 = icmp sgt i32 %a, -1
126  %2 = sext i32 %a to i64
127  %3 = select i1 %1, i64 %2, i64 4294967295
128  ret i64 %3
129}
130
131define float @t10(i32 %x) {
132; CHECK-LABEL: @t10(
133; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 255)
134; CHECK-NEXT:    [[TMP2:%.*]] = sitofp i32 [[TMP1]] to float
135; CHECK-NEXT:    ret float [[TMP2]]
136;
137  %f_x = sitofp i32 %x to float
138  %cmp = icmp sgt i32 %x, 255
139  %r = select i1 %cmp, float %f_x, float 255.0
140  ret float %r
141}
142
143define float @t11(i64 %x) {
144; CHECK-LABEL: @t11(
145; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.smax.i64(i64 [[X:%.*]], i64 255)
146; CHECK-NEXT:    [[TMP2:%.*]] = sitofp i64 [[TMP1]] to float
147; CHECK-NEXT:    ret float [[TMP2]]
148;
149  %f_x = sitofp i64 %x to float
150  %cmp = icmp sgt i64 %x, 255
151  %r = select i1 %cmp, float %f_x, float 255.0
152  ret float %r
153}
154
155; Reuse the first 2 bitcasts as the select operands.
156
157define <4 x i32> @bitcasts_fcmp_1(<2 x i64> %a, <2 x i64> %b) {
158; CHECK-LABEL: @bitcasts_fcmp_1(
159; CHECK-NEXT:    [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x float>
160; CHECK-NEXT:    [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x float>
161; CHECK-NEXT:    [[T2:%.*]] = fcmp olt <4 x float> [[T1]], [[T0]]
162; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[T2]], <4 x float> [[T0]], <4 x float> [[T1]]
163; CHECK-NEXT:    [[T5:%.*]] = bitcast <4 x float> [[TMP1]] to <4 x i32>
164; CHECK-NEXT:    ret <4 x i32> [[T5]]
165;
166  %t0 = bitcast <2 x i64> %a to <4 x float>
167  %t1 = bitcast <2 x i64> %b to <4 x float>
168  %t2 = fcmp olt <4 x float> %t1, %t0
169  %t3 = bitcast <2 x i64> %a to <4 x i32>
170  %t4 = bitcast <2 x i64> %b to <4 x i32>
171  %t5 = select <4 x i1> %t2, <4 x i32> %t3, <4 x i32> %t4
172  ret <4 x i32> %t5
173}
174
175; Switch cmp operand order.
176
177define <4 x i32> @bitcasts_fcmp_2(<2 x i64> %a, <2 x i64> %b) {
178; CHECK-LABEL: @bitcasts_fcmp_2(
179; CHECK-NEXT:    [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x float>
180; CHECK-NEXT:    [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x float>
181; CHECK-NEXT:    [[T2:%.*]] = fcmp olt <4 x float> [[T0]], [[T1]]
182; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[T2]], <4 x float> [[T0]], <4 x float> [[T1]]
183; CHECK-NEXT:    [[T5:%.*]] = bitcast <4 x float> [[TMP1]] to <4 x i32>
184; CHECK-NEXT:    ret <4 x i32> [[T5]]
185;
186  %t0 = bitcast <2 x i64> %a to <4 x float>
187  %t1 = bitcast <2 x i64> %b to <4 x float>
188  %t2 = fcmp olt <4 x float> %t0, %t1
189  %t3 = bitcast <2 x i64> %a to <4 x i32>
190  %t4 = bitcast <2 x i64> %b to <4 x i32>
191  %t5 = select <4 x i1> %t2, <4 x i32> %t3, <4 x i32> %t4
192  ret <4 x i32> %t5
193}
194
195; Integer cmp should have the same transforms.
196
197define <4 x float> @bitcasts_icmp(<2 x i64> %a, <2 x i64> %b) {
198; CHECK-LABEL: @bitcasts_icmp(
199; CHECK-NEXT:    [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
200; CHECK-NEXT:    [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x i32>
201; CHECK-NEXT:    [[TMP1:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[T1]], <4 x i32> [[T0]])
202; CHECK-NEXT:    [[T5:%.*]] = bitcast <4 x i32> [[TMP1]] to <4 x float>
203; CHECK-NEXT:    ret <4 x float> [[T5]]
204;
205  %t0 = bitcast <2 x i64> %a to <4 x i32>
206  %t1 = bitcast <2 x i64> %b to <4 x i32>
207  %t2 = icmp slt <4 x i32> %t1, %t0
208  %t3 = bitcast <2 x i64> %a to <4 x float>
209  %t4 = bitcast <2 x i64> %b to <4 x float>
210  %t5 = select <4 x i1> %t2, <4 x float> %t3, <4 x float> %t4
211  ret <4 x float> %t5
212}
213
214; SMIN(SMIN(X, 11), 92) -> SMIN(X, 11)
215define i32 @test68(i32 %x) {
216; CHECK-LABEL: @test68(
217; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 11)
218; CHECK-NEXT:    ret i32 [[TMP1]]
219;
220  %cmp = icmp slt i32 11, %x
221  %cond = select i1 %cmp, i32 11, i32 %x
222  %cmp3 = icmp slt i32 92, %cond
223  %retval = select i1 %cmp3, i32 92, i32 %cond
224  ret i32 %retval
225}
226
227define <2 x i32> @test68vec(<2 x i32> %x) {
228; CHECK-LABEL: @test68vec(
229; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 11, i32 11>)
230; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
231;
232  %cmp = icmp slt <2 x i32> <i32 11, i32 11>, %x
233  %cond = select <2 x i1> %cmp, <2 x i32> <i32 11, i32 11>, <2 x i32> %x
234  %cmp3 = icmp slt <2 x i32> <i32 92, i32 92>, %cond
235  %retval = select <2 x i1> %cmp3, <2 x i32> <i32 92, i32 92>, <2 x i32> %cond
236  ret <2 x i32> %retval
237}
238
239; MIN(MIN(X, 24), 83) -> MIN(X, 24)
240define i32 @test69(i32 %x) {
241; CHECK-LABEL: @test69(
242; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 24)
243; CHECK-NEXT:    ret i32 [[TMP1]]
244;
245  %cmp = icmp ult i32 24, %x
246  %cond = select i1 %cmp, i32 24, i32 %x
247  %cmp3 = icmp ult i32 83, %cond
248  %retval = select i1 %cmp3, i32 83, i32 %cond
249  ret i32 %retval
250}
251
252; SMAX(SMAX(X, 75), 36) -> SMAX(X, 75)
253define i32 @test70(i32 %x) {
254; CHECK-LABEL: @test70(
255; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 75)
256; CHECK-NEXT:    ret i32 [[TMP1]]
257;
258  %cmp = icmp slt i32 %x, 75
259  %cond = select i1 %cmp, i32 75, i32 %x
260  %cmp3 = icmp slt i32 %cond, 36
261  %retval = select i1 %cmp3, i32 36, i32 %cond
262  ret i32 %retval
263}
264
265; MAX(MAX(X, 68), 47) -> MAX(X, 68)
266define i32 @test71(i32 %x) {
267; CHECK-LABEL: @test71(
268; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 68)
269; CHECK-NEXT:    ret i32 [[TMP1]]
270;
271  %cmp = icmp ult i32 %x, 68
272  %cond = select i1 %cmp, i32 68, i32 %x
273  %cmp3 = icmp ult i32 %cond, 47
274  %retval = select i1 %cmp3, i32 47, i32 %cond
275  ret i32 %retval
276}
277
278; SMIN(SMIN(X, 92), 11) -> SMIN(X, 11)
279define i32 @test72(i32 %x) {
280; CHECK-LABEL: @test72(
281; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 11)
282; CHECK-NEXT:    ret i32 [[TMP1]]
283;
284  %cmp = icmp sgt i32 %x, 92
285  %cond = select i1 %cmp, i32 92, i32 %x
286  %cmp3 = icmp sgt i32 %cond, 11
287  %retval = select i1 %cmp3, i32 11, i32 %cond
288  ret i32 %retval
289}
290
291define <2 x i32> @test72vec(<2 x i32> %x) {
292; CHECK-LABEL: @test72vec(
293; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 11, i32 11>)
294; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
295;
296  %cmp = icmp sgt <2 x i32> %x, <i32 92, i32 92>
297  %cond = select <2 x i1> %cmp, <2 x i32> <i32 92, i32 92>, <2 x i32> %x
298  %cmp3 = icmp sgt <2 x i32> %cond, <i32 11, i32 11>
299  %retval = select <2 x i1> %cmp3, <2 x i32> <i32 11, i32 11>, <2 x i32> %cond
300  ret <2 x i32> %retval
301}
302
303; MIN(MIN(X, 83), 24) -> MIN(X, 24)
304define i32 @test73(i32 %x) {
305; CHECK-LABEL: @test73(
306; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 24)
307; CHECK-NEXT:    ret i32 [[TMP1]]
308;
309  %cmp = icmp ugt i32 %x, 83
310  %cond = select i1 %cmp, i32 83, i32 %x
311  %cmp3 = icmp ugt i32 %cond, 24
312  %retval = select i1 %cmp3, i32 24, i32 %cond
313  ret i32 %retval
314}
315
316; SMAX(SMAX(X, 36), 75) -> SMAX(X, 75)
317define i32 @test74(i32 %x) {
318; CHECK-LABEL: @test74(
319; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 36)
320; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 75)
321; CHECK-NEXT:    ret i32 [[TMP2]]
322;
323  %cmp = icmp slt i32 %x, 36
324  %cond = select i1 %cmp, i32 36, i32 %x
325  %cmp3 = icmp slt i32 %cond, 75
326  %retval = select i1 %cmp3, i32 75, i32 %cond
327  ret i32 %retval
328}
329
330; MAX(MAX(X, 47), 68) -> MAX(X, 68)
331define i32 @test75(i32 %x) {
332; CHECK-LABEL: @test75(
333; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 68)
334; CHECK-NEXT:    ret i32 [[TMP1]]
335;
336  %cmp = icmp ult i32 %x, 47
337  %cond = select i1 %cmp, i32 47, i32 %x
338  %cmp3 = icmp ult i32 %cond, 68
339  %retval = select i1 %cmp3, i32 68, i32 %cond
340  ret i32 %retval
341}
342
343; The next 10 tests are value clamping with constants:
344; https://llvm.org/bugs/show_bug.cgi?id=31693
345
346; (X <s C1) ? C1 : SMIN(X, C2) ==> SMAX(SMIN(X, C2), C1)
347
348define i32 @clamp_signed1(i32 %x) {
349; CHECK-LABEL: @clamp_signed1(
350; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
351; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 15)
352; CHECK-NEXT:    ret i32 [[TMP2]]
353;
354  %cmp2 = icmp slt i32 %x, 255
355  %min = select i1 %cmp2, i32 %x, i32 255
356  %cmp1 = icmp slt i32 %x, 15
357  %r = select i1 %cmp1, i32 15, i32 %min
358  ret i32 %r
359}
360
361; (X >s C1) ? C1 : SMAX(X, C2) ==> SMIN(SMAX(X, C2), C1)
362
363define i32 @clamp_signed2(i32 %x) {
364; CHECK-LABEL: @clamp_signed2(
365; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 15)
366; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 255)
367; CHECK-NEXT:    ret i32 [[TMP2]]
368;
369  %cmp2 = icmp sgt i32 %x, 15
370  %max = select i1 %cmp2, i32 %x, i32 15
371  %cmp1 = icmp sgt i32 %x, 255
372  %r = select i1 %cmp1, i32 255, i32 %max
373  ret i32 %r
374}
375
376; (X >s C1) ? SMIN(X, C2) : C1 ==> SMAX(SMIN(X, C2), C1)
377
378define i32 @clamp_signed3(i32 %x) {
379; CHECK-LABEL: @clamp_signed3(
380; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
381; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 15)
382; CHECK-NEXT:    ret i32 [[TMP2]]
383;
384  %cmp2 = icmp slt i32 %x, 255
385  %min = select i1 %cmp2, i32 %x, i32 255
386  %cmp1 = icmp sgt i32 %x, 15
387  %r = select i1 %cmp1, i32 %min, i32 15
388  ret i32 %r
389}
390
391; (X <s C1) ? SMAX(X, C2) : C1 ==> SMIN(SMAX(X, C1), C2)
392
393define i32 @clamp_signed4(i32 %x) {
394; CHECK-LABEL: @clamp_signed4(
395; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 15)
396; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 255)
397; CHECK-NEXT:    ret i32 [[TMP2]]
398;
399  %cmp2 = icmp sgt i32 %x, 15
400  %max = select i1 %cmp2, i32 %x, i32 15
401  %cmp1 = icmp slt i32 %x, 255
402  %r = select i1 %cmp1, i32 %max, i32 255
403  ret i32 %r
404}
405
406; (X <u C1) ? C1 : UMIN(X, C2) ==> UMAX(UMIN(X, C2), C1)
407
408define i32 @clamp_unsigned1(i32 %x) {
409; CHECK-LABEL: @clamp_unsigned1(
410; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 255)
411; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 15)
412; CHECK-NEXT:    ret i32 [[TMP2]]
413;
414  %cmp2 = icmp ult i32 %x, 255
415  %min = select i1 %cmp2, i32 %x, i32 255
416  %cmp1 = icmp ult i32 %x, 15
417  %r = select i1 %cmp1, i32 15, i32 %min
418  ret i32 %r
419}
420
421; (X >u C1) ? C1 : UMAX(X, C2) ==> UMIN(UMAX(X, C2), C1)
422
423define i32 @clamp_unsigned2(i32 %x) {
424; CHECK-LABEL: @clamp_unsigned2(
425; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 15)
426; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 255)
427; CHECK-NEXT:    ret i32 [[TMP2]]
428;
429  %cmp2 = icmp ugt i32 %x, 15
430  %max = select i1 %cmp2, i32 %x, i32 15
431  %cmp1 = icmp ugt i32 %x, 255
432  %r = select i1 %cmp1, i32 255, i32 %max
433  ret i32 %r
434}
435
436; (X >u C1) ? UMIN(X, C2) : C1 ==> UMAX(UMIN(X, C2), C1)
437
438define i32 @clamp_unsigned3(i32 %x) {
439; CHECK-LABEL: @clamp_unsigned3(
440; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 255)
441; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 15)
442; CHECK-NEXT:    ret i32 [[TMP2]]
443;
444  %cmp2 = icmp ult i32 %x, 255
445  %min = select i1 %cmp2, i32 %x, i32 255
446  %cmp1 = icmp ugt i32 %x, 15
447  %r = select i1 %cmp1, i32 %min, i32 15
448  ret i32 %r
449}
450
451; (X <u C1) ? UMAX(X, C2) : C1 ==> UMIN(UMAX(X, C2), C1)
452
453define i32 @clamp_unsigned4(i32 %x) {
454; CHECK-LABEL: @clamp_unsigned4(
455; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 15)
456; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 255)
457; CHECK-NEXT:    ret i32 [[TMP2]]
458;
459  %cmp2 = icmp ugt i32 %x, 15
460  %max = select i1 %cmp2, i32 %x, i32 15
461  %cmp1 = icmp ult i32 %x, 255
462  %r = select i1 %cmp1, i32 %max, i32 255
463  ret i32 %r
464}
465
466; Check that clamp is recognized and there is no infinite
467; loop because of reverse cmp transformation:
468; (icmp sgt smin(PositiveA, B) 0) -> (icmp sgt B 0)
469define i32 @clamp_check_for_no_infinite_loop1(i32 %i) {
470; CHECK-LABEL: @clamp_check_for_no_infinite_loop1(
471; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[I:%.*]], i32 255)
472; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 0)
473; CHECK-NEXT:    ret i32 [[TMP2]]
474;
475  %cmp1 = icmp slt i32 %i, 255
476  %sel1 = select i1 %cmp1, i32 %i, i32 255
477  %cmp2 = icmp slt i32 %i, 0
478  %res = select i1 %cmp2, i32 0, i32 %sel1
479  ret i32 %res
480}
481; Check that there is no infinite loop in case of:
482; (icmp slt smax(NegativeA, B) 0) -> (icmp slt B 0)
483define i32 @clamp_check_for_no_infinite_loop2(i32 %i) {
484; CHECK-LABEL: @clamp_check_for_no_infinite_loop2(
485; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[I:%.*]], i32 -255)
486; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 0)
487; CHECK-NEXT:    ret i32 [[TMP2]]
488;
489  %cmp1 = icmp sgt i32 %i, -255
490  %sel1 = select i1 %cmp1, i32 %i, i32 -255
491  %cmp2 = icmp slt i32 %i, 0
492  %res = select i1 %cmp2, i32 %sel1, i32 0
493  ret i32 %res
494}
495
496; Check that there is no infinite loop because of reverse cmp transformation:
497; (icmp slt smax(PositiveA, B) 2) -> (icmp eq B 1)
498define i32 @clamp_check_for_no_infinite_loop3(i32 %i) {
499; CHECK-LABEL: @clamp_check_for_no_infinite_loop3(
500; CHECK-NEXT:    br i1 true, label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]]
501; CHECK:       truelabel:
502; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[I:%.*]], i32 1)
503; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 2)
504; CHECK-NEXT:    [[I7:%.*]] = shl nuw nsw i32 [[TMP2]], 2
505; CHECK-NEXT:    ret i32 [[I7]]
506; CHECK:       falselabel:
507; CHECK-NEXT:    ret i32 0
508;
509
510  %i2 = icmp sgt i32 %i, 1
511  %i3 = select i1 %i2, i32 %i, i32 1
512  %i4 = icmp sgt i32 %i3, 0
513  br i1 %i4, label %truelabel, label %falselabel
514
515truelabel: ; %i<=1, %i3>0
516  %i5 = icmp slt i32 %i3, 2
517  %i6 = select i1 %i5, i32 %i3, i32 2
518  %i7 = shl nuw nsw i32 %i6, 2
519  ret i32 %i7
520
521falselabel:
522  ret i32 0
523}
524
525; The next 3 min tests should canonicalize to the same form...and not infinite loop.
526
527define double @PR31751_umin1(i32 %x) {
528; CHECK-LABEL: @PR31751_umin1(
529; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
530; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[TMP1]] to double
531; CHECK-NEXT:    ret double [[CONV]]
532;
533  %cmp = icmp slt i32 %x, 0
534  %sel = select i1 %cmp, i32 2147483647, i32 %x
535  %conv = sitofp i32 %sel to double
536  ret double %conv
537}
538
539define double @PR31751_umin2(i32 %x) {
540; CHECK-LABEL: @PR31751_umin2(
541; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
542; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[TMP1]] to double
543; CHECK-NEXT:    ret double [[CONV]]
544;
545  %cmp = icmp ult i32 %x, 2147483647
546  %sel = select i1 %cmp, i32 %x, i32 2147483647
547  %conv = sitofp i32 %sel to double
548  ret double %conv
549}
550
551define double @PR31751_umin3(i32 %x) {
552; CHECK-LABEL: @PR31751_umin3(
553; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
554; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[TMP1]] to double
555; CHECK-NEXT:    ret double [[CONV]]
556;
557  %cmp = icmp ugt i32 %x, 2147483647
558  %sel = select i1 %cmp, i32 2147483647, i32 %x
559  %conv = sitofp i32 %sel to double
560  ret double %conv
561}
562
563; The next 3 max tests should canonicalize to the same form...and not infinite loop.
564
565define double @PR31751_umax1(i32 %x) {
566; CHECK-LABEL: @PR31751_umax1(
567; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648)
568; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[TMP1]] to double
569; CHECK-NEXT:    ret double [[CONV]]
570;
571  %cmp = icmp sgt i32 %x, -1
572  %sel = select i1 %cmp, i32 2147483648, i32 %x
573  %conv = sitofp i32 %sel to double
574  ret double %conv
575}
576
577define double @PR31751_umax2(i32 %x) {
578; CHECK-LABEL: @PR31751_umax2(
579; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648)
580; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[TMP1]] to double
581; CHECK-NEXT:    ret double [[CONV]]
582;
583  %cmp = icmp ugt i32 %x, 2147483648
584  %sel = select i1 %cmp, i32 %x, i32 2147483648
585  %conv = sitofp i32 %sel to double
586  ret double %conv
587}
588
589define double @PR31751_umax3(i32 %x) {
590; CHECK-LABEL: @PR31751_umax3(
591; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648)
592; CHECK-NEXT:    [[CONV:%.*]] = sitofp i32 [[TMP1]] to double
593; CHECK-NEXT:    ret double [[CONV]]
594;
595  %cmp = icmp ult i32 %x, 2147483648
596  %sel = select i1 %cmp, i32 2147483648, i32 %x
597  %conv = sitofp i32 %sel to double
598  ret double %conv
599}
600
601; The icmp/select form a canonical smax, so don't hide that by folding the final bitcast into the select.
602
603define float @bitcast_scalar_smax(float %x, float %y) {
604; CHECK-LABEL: @bitcast_scalar_smax(
605; CHECK-NEXT:    [[BCX:%.*]] = bitcast float [[X:%.*]] to i32
606; CHECK-NEXT:    [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32
607; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[BCX]], i32 [[BCY]])
608; CHECK-NEXT:    [[BCS:%.*]] = bitcast i32 [[TMP1]] to float
609; CHECK-NEXT:    ret float [[BCS]]
610;
611  %bcx = bitcast float %x to i32
612  %bcy = bitcast float %y to i32
613  %cmp = icmp sgt i32 %bcx, %bcy
614  %sel = select i1 %cmp, i32 %bcx, i32 %bcy
615  %bcs = bitcast i32 %sel to float
616  ret float %bcs
617}
618
619; FIXME: Create a canonical umax by bitcasting the select.
620
621define float @bitcast_scalar_umax(float %x, float %y) {
622; CHECK-LABEL: @bitcast_scalar_umax(
623; CHECK-NEXT:    [[BCX:%.*]] = bitcast float [[X:%.*]] to i32
624; CHECK-NEXT:    [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32
625; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[BCX]], [[BCY]]
626; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[Y]]
627; CHECK-NEXT:    ret float [[SEL]]
628;
629  %bcx = bitcast float %x to i32
630  %bcy = bitcast float %y to i32
631  %cmp = icmp ugt i32 %bcx, %bcy
632  %sel = select i1 %cmp, float %x, float %y
633  ret float %sel
634}
635
636; PR32306 - https://bugs.llvm.org/show_bug.cgi?id=32306
637; The icmp/select form a canonical smin, so don't hide that by folding the final bitcast into the select.
638
639define <8 x float> @bitcast_vector_smin(<8 x float> %x, <8 x float> %y) {
640; CHECK-LABEL: @bitcast_vector_smin(
641; CHECK-NEXT:    [[BCX:%.*]] = bitcast <8 x float> [[X:%.*]] to <8 x i32>
642; CHECK-NEXT:    [[BCY:%.*]] = bitcast <8 x float> [[Y:%.*]] to <8 x i32>
643; CHECK-NEXT:    [[TMP1:%.*]] = call <8 x i32> @llvm.smin.v8i32(<8 x i32> [[BCX]], <8 x i32> [[BCY]])
644; CHECK-NEXT:    [[BCS:%.*]] = bitcast <8 x i32> [[TMP1]] to <8 x float>
645; CHECK-NEXT:    ret <8 x float> [[BCS]]
646;
647  %bcx = bitcast <8 x float> %x to <8 x i32>
648  %bcy = bitcast <8 x float> %y to <8 x i32>
649  %cmp = icmp slt <8 x i32> %bcx, %bcy
650  %sel = select <8 x i1> %cmp, <8 x i32> %bcx, <8 x i32> %bcy
651  %bcs = bitcast <8 x i32> %sel to <8 x float>
652  ret <8 x float> %bcs
653}
654
655; FIXME: Create a canonical umin by bitcasting the select.
656
657define <8 x float> @bitcast_vector_umin(<8 x float> %x, <8 x float> %y) {
658; CHECK-LABEL: @bitcast_vector_umin(
659; CHECK-NEXT:    [[BCX:%.*]] = bitcast <8 x float> [[X:%.*]] to <8 x i32>
660; CHECK-NEXT:    [[BCY:%.*]] = bitcast <8 x float> [[Y:%.*]] to <8 x i32>
661; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <8 x i32> [[BCX]], [[BCY]]
662; CHECK-NEXT:    [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x float> [[X]], <8 x float> [[Y]]
663; CHECK-NEXT:    ret <8 x float> [[SEL]]
664;
665  %bcx = bitcast <8 x float> %x to <8 x i32>
666  %bcy = bitcast <8 x float> %y to <8 x i32>
667  %cmp = icmp slt <8 x i32> %bcx, %bcy
668  %sel = select <8 x i1> %cmp, <8 x float> %x, <8 x float> %y
669  ret <8 x float> %sel
670}
671
672; Check that we look through cast and recognize min idiom.
673
674define zeroext i8 @look_through_cast1(i32 %x) {
675; CHECK-LABEL: @look_through_cast1(
676; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 511)
677; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8
678; CHECK-NEXT:    ret i8 [[TMP2]]
679;
680  %cmp1 = icmp slt i32 %x, 511
681  %x_trunc = trunc i32 %x to i8
682  %res = select i1 %cmp1, i8 %x_trunc, i8 255
683  ret i8 %res
684}
685
686; Check that we look through cast but min is not recognized.
687
688define zeroext i8 @look_through_cast2(i32 %x) {
689; CHECK-LABEL: @look_through_cast2(
690; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 510
691; CHECK-NEXT:    [[X_TRUNC:%.*]] = trunc i32 [[X]] to i8
692; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP1]], i8 [[X_TRUNC]], i8 -1
693; CHECK-NEXT:    ret i8 [[RES]]
694;
695  %cmp1 = icmp slt i32 %x, 510
696  %x_trunc = trunc i32 %x to i8
697  %res = select i1 %cmp1, i8 %x_trunc, i8 255
698  ret i8 %res
699}
700
701define <2 x i8> @min_through_cast_vec1(<2 x i32> %x) {
702; CHECK-LABEL: @min_through_cast_vec1(
703; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 510, i32 511>)
704; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i8>
705; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
706;
707  %cmp = icmp slt <2 x i32> %x, <i32 510, i32 511>
708  %x_trunc = trunc <2 x i32> %x to <2 x i8>
709  %res = select <2 x i1> %cmp, <2 x i8> %x_trunc, <2 x i8> <i8 254, i8 255>
710  ret <2 x i8> %res
711}
712
713define <2 x i8> @min_through_cast_vec2(<2 x i32> %x) {
714; CHECK-LABEL: @min_through_cast_vec2(
715; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 511, i32 511>)
716; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i8>
717; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
718;
719  %cmp = icmp slt <2 x i32> %x, <i32 511, i32 511>
720  %x_trunc = trunc <2 x i32> %x to <2 x i8>
721  %res = select <2 x i1> %cmp, <2 x i8> %x_trunc, <2 x i8> <i8 255, i8 255>
722  ret <2 x i8> %res
723}
724
725; Remove a min/max op in a sequence with a common operand.
726; PR35717: https://bugs.llvm.org/show_bug.cgi?id=35717
727
728; min(min(a, b), min(b, c)) --> min(min(a, b), c)
729
730define i32 @common_factor_smin(i32 %a, i32 %b, i32 %c) {
731; CHECK-LABEL: @common_factor_smin(
732; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[B:%.*]], i32 [[C:%.*]])
733; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 [[A:%.*]])
734; CHECK-NEXT:    ret i32 [[TMP2]]
735;
736  %cmp_ab = icmp slt i32 %a, %b
737  %min_ab = select i1 %cmp_ab, i32 %a, i32 %b
738  %cmp_bc = icmp slt i32 %b, %c
739  %min_bc = select i1 %cmp_bc, i32 %b, i32 %c
740  %cmp_ab_bc = icmp slt i32 %min_ab, %min_bc
741  %min_abc = select i1 %cmp_ab_bc, i32 %min_ab, i32 %min_bc
742  ret i32 %min_abc
743}
744
745; max(max(a, b), max(c, b)) --> max(max(a, b), c)
746
747define <2 x i32> @common_factor_smax(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
748; CHECK-LABEL: @common_factor_smax(
749; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[C:%.*]], <2 x i32> [[B:%.*]])
750; CHECK-NEXT:    [[TMP2:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[TMP1]], <2 x i32> [[A:%.*]])
751; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
752;
753  %cmp_ab = icmp sgt <2 x i32> %a, %b
754  %max_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b
755  %cmp_cb = icmp sgt <2 x i32> %c, %b
756  %max_cb = select <2 x i1> %cmp_cb, <2 x i32> %c, <2 x i32> %b
757  %cmp_ab_cb = icmp sgt <2 x i32> %max_ab, %max_cb
758  %max_abc = select <2 x i1> %cmp_ab_cb, <2 x i32> %max_ab, <2 x i32> %max_cb
759  ret <2 x i32> %max_abc
760}
761
762; min(min(b, c), min(a, b)) --> min(min(b, c), a)
763
764define <2 x i32> @common_factor_umin(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
765; CHECK-LABEL: @common_factor_umin(
766; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]])
767; CHECK-NEXT:    [[TMP2:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[TMP1]], <2 x i32> [[C:%.*]])
768; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
769;
770  %cmp_bc = icmp ult <2 x i32> %b, %c
771  %min_bc = select <2 x i1> %cmp_bc, <2 x i32> %b, <2 x i32> %c
772  %cmp_ab = icmp ult <2 x i32> %a, %b
773  %min_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b
774  %cmp_bc_ab = icmp ult <2 x i32> %min_bc, %min_ab
775  %min_abc = select <2 x i1> %cmp_bc_ab, <2 x i32> %min_bc, <2 x i32> %min_ab
776  ret <2 x i32> %min_abc
777}
778
779; max(max(b, c), max(b, a)) --> max(max(b, c), a)
780
781define i32 @common_factor_umax(i32 %a, i32 %b, i32 %c) {
782; CHECK-LABEL: @common_factor_umax(
783; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[A:%.*]])
784; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[C:%.*]])
785; CHECK-NEXT:    ret i32 [[TMP2]]
786;
787  %cmp_bc = icmp ugt i32 %b, %c
788  %max_bc = select i1 %cmp_bc, i32 %b, i32 %c
789  %cmp_ba = icmp ugt i32 %b, %a
790  %max_ba = select i1 %cmp_ba, i32 %b, i32 %a
791  %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba
792  %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba
793  ret i32 %max_abc
794}
795
796declare void @extra_use(i32)
797
798define i32 @common_factor_umax_extra_use_lhs(i32 %a, i32 %b, i32 %c) {
799; CHECK-LABEL: @common_factor_umax_extra_use_lhs(
800; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[C:%.*]])
801; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[A:%.*]])
802; CHECK-NEXT:    call void @extra_use(i32 [[TMP1]])
803; CHECK-NEXT:    ret i32 [[TMP2]]
804;
805  %cmp_bc = icmp ugt i32 %b, %c
806  %max_bc = select i1 %cmp_bc, i32 %b, i32 %c
807  %cmp_ba = icmp ugt i32 %b, %a
808  %max_ba = select i1 %cmp_ba, i32 %b, i32 %a
809  %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba
810  %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba
811  call void @extra_use(i32 %max_bc)
812  ret i32 %max_abc
813}
814
815define i32 @common_factor_umax_extra_use_rhs(i32 %a, i32 %b, i32 %c) {
816; CHECK-LABEL: @common_factor_umax_extra_use_rhs(
817; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[A:%.*]])
818; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[C:%.*]])
819; CHECK-NEXT:    call void @extra_use(i32 [[TMP1]])
820; CHECK-NEXT:    ret i32 [[TMP2]]
821;
822  %cmp_bc = icmp ugt i32 %b, %c
823  %max_bc = select i1 %cmp_bc, i32 %b, i32 %c
824  %cmp_ba = icmp ugt i32 %b, %a
825  %max_ba = select i1 %cmp_ba, i32 %b, i32 %a
826  %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba
827  %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba
828  call void @extra_use(i32 %max_ba)
829  ret i32 %max_abc
830}
831
832define i32 @common_factor_umax_extra_use_both(i32 %a, i32 %b, i32 %c) {
833; CHECK-LABEL: @common_factor_umax_extra_use_both(
834; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[C:%.*]])
835; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[B]], i32 [[A:%.*]])
836; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[TMP2]])
837; CHECK-NEXT:    call void @extra_use(i32 [[TMP1]])
838; CHECK-NEXT:    call void @extra_use(i32 [[TMP2]])
839; CHECK-NEXT:    ret i32 [[TMP3]]
840;
841  %cmp_bc = icmp ugt i32 %b, %c
842  %max_bc = select i1 %cmp_bc, i32 %b, i32 %c
843  %cmp_ba = icmp ugt i32 %b, %a
844  %max_ba = select i1 %cmp_ba, i32 %b, i32 %a
845  %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba
846  %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba
847  call void @extra_use(i32 %max_bc)
848  call void @extra_use(i32 %max_ba)
849  ret i32 %max_abc
850}
851
852; This would assert. Don't assume that earlier min/max types match a possible later min/max.
853
854define float @not_min_of_min(i8 %i, float %x) {
855; CHECK-LABEL: @not_min_of_min(
856; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp fast oge float [[X:%.*]], 1.000000e+00
857; CHECK-NEXT:    [[TMP1:%.*]] = select fast i1 [[CMP1_INV]], float 1.000000e+00, float [[X]]
858; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp fast oge float [[X]], 2.000000e+00
859; CHECK-NEXT:    [[TMP2:%.*]] = select fast i1 [[CMP2_INV]], float 2.000000e+00, float [[X]]
860; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i8 [[I:%.*]], 16
861; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP3]], float [[TMP1]], float [[TMP2]]
862; CHECK-NEXT:    ret float [[R]]
863;
864  %cmp1 = fcmp fast ult float %x, 1.0
865  %min1 = select i1 %cmp1, float %x, float 1.0
866  %cmp2 = fcmp fast ult float %x, 2.0
867  %min2 = select i1 %cmp2, float %x, float 2.0
868  %cmp3 = icmp ult i8 %i, 16
869  %r = select i1 %cmp3, float %min1, float %min2
870  ret float %r
871}
872
873define i32 @add_umin(i32 %x) {
874; CHECK-LABEL: @add_umin(
875; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 27)
876; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 15
877; CHECK-NEXT:    ret i32 [[TMP2]]
878;
879  %a = add nuw i32 %x, 15
880  %c = icmp ult i32 %a, 42
881  %r = select i1 %c, i32 %a, i32 42
882  ret i32 %r
883}
884
885define i32 @add_umin_constant_limit(i32 %x) {
886; CHECK-LABEL: @add_umin_constant_limit(
887; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[X:%.*]], 0
888; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTNOT]], i32 41, i32 42
889; CHECK-NEXT:    ret i32 [[TMP1]]
890;
891  %a = add nuw i32 %x, 41
892  %c = icmp ult i32 %a, 42
893  %r = select i1 %c, i32 %a, i32 42
894  ret i32 %r
895}
896
897; Negative test
898; TODO: assert that instsimplify always gets this?
899
900define i32 @add_umin_simplify(i32 %x) {
901; CHECK-LABEL: @add_umin_simplify(
902; CHECK-NEXT:    ret i32 42
903;
904  %a = add nuw i32 %x, 42
905  %c = icmp ult i32 %a, 42
906  %r = select i1 %c, i32 %a, i32 42
907  ret i32 %r
908}
909
910; Negative test
911; TODO: assert that instsimplify always gets this?
912
913define i32 @add_umin_simplify2(i32 %x) {
914; CHECK-LABEL: @add_umin_simplify2(
915; CHECK-NEXT:    ret i32 42
916;
917  %a = add nuw i32 %x, 43
918  %c = icmp ult i32 %a, 42
919  %r = select i1 %c, i32 %a, i32 42
920  ret i32 %r
921}
922
923; Negative test
924
925define i32 @add_umin_wrong_pred(i32 %x) {
926; CHECK-LABEL: @add_umin_wrong_pred(
927; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
928; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42)
929; CHECK-NEXT:    ret i32 [[TMP1]]
930;
931  %a = add nuw i32 %x, 15
932  %c = icmp slt i32 %a, 42
933  %r = select i1 %c, i32 %a, i32 42
934  ret i32 %r
935}
936
937; Negative test
938
939define i32 @add_umin_wrong_wrap(i32 %x) {
940; CHECK-LABEL: @add_umin_wrong_wrap(
941; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
942; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42)
943; CHECK-NEXT:    ret i32 [[TMP1]]
944;
945  %a = add nsw i32 %x, 15
946  %c = icmp ult i32 %a, 42
947  %r = select i1 %c, i32 %a, i32 42
948  ret i32 %r
949}
950
951; Negative test
952
953define i32 @add_umin_extra_use(i32 %x, i32* %p) {
954; CHECK-LABEL: @add_umin_extra_use(
955; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
956; CHECK-NEXT:    store i32 [[A]], i32* [[P:%.*]], align 4
957; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42)
958; CHECK-NEXT:    ret i32 [[TMP1]]
959;
960  %a = add nuw i32 %x, 15
961  store i32 %a, i32* %p
962  %c = icmp ult i32 %a, 42
963  %r = select i1 %c, i32 %a, i32 42
964  ret i32 %r
965}
966
967define <2 x i16> @add_umin_vec(<2 x i16> %x) {
968; CHECK-LABEL: @add_umin_vec(
969; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> <i16 225, i16 225>)
970; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw <2 x i16> [[TMP1]], <i16 15, i16 15>
971; CHECK-NEXT:    ret <2 x i16> [[TMP2]]
972;
973  %a = add nuw <2 x i16> %x, <i16 15, i16 15>
974  %c = icmp ult <2 x i16> %a, <i16 240, i16 240>
975  %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240>
976  ret <2 x i16> %r
977}
978
979define i37 @add_umax(i37 %x) {
980; CHECK-LABEL: @add_umax(
981; CHECK-NEXT:    [[TMP1:%.*]] = call i37 @llvm.umax.i37(i37 [[X:%.*]], i37 37)
982; CHECK-NEXT:    [[TMP2:%.*]] = add nuw i37 [[TMP1]], 5
983; CHECK-NEXT:    ret i37 [[TMP2]]
984;
985  %a = add nuw i37 %x, 5
986  %c = icmp ugt i37 %a, 42
987  %r = select i1 %c, i37 %a, i37 42
988  ret i37 %r
989}
990
991define i37 @add_umax_constant_limit(i37 %x) {
992; CHECK-LABEL: @add_umax_constant_limit(
993; CHECK-NEXT:    [[TMP1:%.*]] = call i37 @llvm.umax.i37(i37 [[X:%.*]], i37 1)
994; CHECK-NEXT:    [[TMP2:%.*]] = add nuw i37 [[TMP1]], 81
995; CHECK-NEXT:    ret i37 [[TMP2]]
996;
997  %a = add nuw i37 %x, 81
998  %c = icmp ugt i37 %a, 82
999  %r = select i1 %c, i37 %a, i37 82
1000  ret i37 %r
1001}
1002
1003; Negative test
1004; TODO: assert that instsimplify always gets this?
1005
1006define i37 @add_umax_simplify(i37 %x) {
1007; CHECK-LABEL: @add_umax_simplify(
1008; CHECK-NEXT:    [[A:%.*]] = add nuw i37 [[X:%.*]], 42
1009; CHECK-NEXT:    ret i37 [[A]]
1010;
1011  %a = add nuw i37 %x, 42
1012  %c = icmp ugt i37 %a, 42
1013  %r = select i1 %c, i37 %a, i37 42
1014  ret i37 %r
1015}
1016
1017; Negative test
1018; TODO: assert that instsimplify always gets this?
1019
1020define i32 @add_umax_simplify2(i32 %x) {
1021; CHECK-LABEL: @add_umax_simplify2(
1022; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 57
1023; CHECK-NEXT:    ret i32 [[A]]
1024;
1025  %a = add nuw i32 %x, 57
1026  %c = icmp ugt i32 %a, 56
1027  %r = select i1 %c, i32 %a, i32 56
1028  ret i32 %r
1029}
1030
1031; Negative test
1032
1033define i32 @add_umax_wrong_pred(i32 %x) {
1034; CHECK-LABEL: @add_umax_wrong_pred(
1035; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1036; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42)
1037; CHECK-NEXT:    ret i32 [[TMP1]]
1038;
1039  %a = add nuw i32 %x, 15
1040  %c = icmp sgt i32 %a, 42
1041  %r = select i1 %c, i32 %a, i32 42
1042  ret i32 %r
1043}
1044
1045; Negative test
1046
1047; Without the nuw that would allow pushing the add through the umax, the
1048; add + icmp ugt combination can be interpreted as a range check, and would
1049; normally be canonicalized to use ult instead. However, this is not done when
1050; used as part of a umax to avoid breaking the SPF pattern.
1051define i32 @add_umax_wrong_wrap(i32 %x) {
1052; CHECK-LABEL: @add_umax_wrong_wrap(
1053; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1054; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42)
1055; CHECK-NEXT:    ret i32 [[TMP1]]
1056;
1057  %a = add nsw i32 %x, 15
1058  %c = icmp ugt i32 %a, 42
1059  %r = select i1 %c, i32 %a, i32 42
1060  ret i32 %r
1061}
1062
1063; Negative test
1064
1065define i32 @add_umax_extra_use(i32 %x, i32* %p) {
1066; CHECK-LABEL: @add_umax_extra_use(
1067; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1068; CHECK-NEXT:    store i32 [[A]], i32* [[P:%.*]], align 4
1069; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42)
1070; CHECK-NEXT:    ret i32 [[TMP1]]
1071;
1072  %a = add nuw i32 %x, 15
1073  store i32 %a, i32* %p
1074  %c = icmp ugt i32 %a, 42
1075  %r = select i1 %c, i32 %a, i32 42
1076  ret i32 %r
1077}
1078
1079define <2 x i33> @add_umax_vec(<2 x i33> %x) {
1080; CHECK-LABEL: @add_umax_vec(
1081; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i33> @llvm.umax.v2i33(<2 x i33> [[X:%.*]], <2 x i33> <i33 235, i33 235>)
1082; CHECK-NEXT:    [[TMP2:%.*]] = add nuw <2 x i33> [[TMP1]], <i33 5, i33 5>
1083; CHECK-NEXT:    ret <2 x i33> [[TMP2]]
1084;
1085  %a = add nuw <2 x i33> %x, <i33 5, i33 5>
1086  %c = icmp ugt <2 x i33> %a, <i33 240, i33 240>
1087  %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240>
1088  ret <2 x i33> %r
1089}
1090
1091define i8 @PR14613_umin(i8 %x) {
1092; CHECK-LABEL: @PR14613_umin(
1093; CHECK-NEXT:    [[NARROW:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 15)
1094; CHECK-NEXT:    ret i8 [[NARROW]]
1095;
1096  %u4 = zext i8 %x to i32
1097  %u5 = add nuw nsw i32 %u4, 15
1098  %u6 = icmp ult i32 %u5, 255
1099  %u7 = select i1 %u6, i32 %u5, i32 255
1100  %r = trunc i32 %u7 to i8
1101  ret i8 %r
1102}
1103
1104define i8 @PR14613_umax(i8 %x) {
1105; CHECK-LABEL: @PR14613_umax(
1106; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 -16)
1107; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i8 [[TMP1]], 15
1108; CHECK-NEXT:    ret i8 [[TMP2]]
1109;
1110  %u4 = zext i8 %x to i32
1111  %u5 = add nuw nsw i32 %u4, 15
1112  %u6 = icmp ugt i32 %u5, 255
1113  %u7 = select i1 %u6, i32 %u5, i32 255
1114  %r = trunc i32 %u7 to i8
1115  ret i8 %r
1116}
1117
1118define i32 @add_smin(i32 %x) {
1119; CHECK-LABEL: @add_smin(
1120; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 27)
1121; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i32 [[TMP1]], 15
1122; CHECK-NEXT:    ret i32 [[TMP2]]
1123;
1124  %a = add nsw i32 %x, 15
1125  %c = icmp slt i32 %a, 42
1126  %r = select i1 %c, i32 %a, i32 42
1127  ret i32 %r
1128}
1129
1130define i32 @add_smin_constant_limit(i32 %x) {
1131; CHECK-LABEL: @add_smin_constant_limit(
1132; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 2147483646)
1133; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i32 [[TMP1]], -3
1134; CHECK-NEXT:    ret i32 [[TMP2]]
1135;
1136  %a = add nsw i32 %x, -3
1137  %c = icmp slt i32 %a, 2147483643
1138  %r = select i1 %c, i32 %a, i32 2147483643
1139  ret i32 %r
1140}
1141
1142; Negative test
1143; TODO: assert that instsimplify always gets this?
1144
1145define i32 @add_smin_simplify(i32 %x) {
1146; CHECK-LABEL: @add_smin_simplify(
1147; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], -3
1148; CHECK-NEXT:    ret i32 [[A]]
1149;
1150  %a = add nsw i32 %x, -3
1151  %c = icmp slt i32 %a, 2147483644
1152  %r = select i1 %c, i32 %a, i32 2147483644
1153  ret i32 %r
1154}
1155
1156; Negative test
1157; TODO: assert that instsimplify always gets this?
1158
1159define i32 @add_smin_simplify2(i32 %x) {
1160; CHECK-LABEL: @add_smin_simplify2(
1161; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], -3
1162; CHECK-NEXT:    ret i32 [[A]]
1163;
1164  %a = add nsw i32 %x, -3
1165  %c = icmp slt i32 %a, 2147483645
1166  %r = select i1 %c, i32 %a, i32 2147483645
1167  ret i32 %r
1168}
1169
1170; Negative test
1171
1172define i32 @add_smin_wrong_pred(i32 %x) {
1173; CHECK-LABEL: @add_smin_wrong_pred(
1174; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1175; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42)
1176; CHECK-NEXT:    ret i32 [[TMP1]]
1177;
1178  %a = add nsw i32 %x, 15
1179  %c = icmp ult i32 %a, 42
1180  %r = select i1 %c, i32 %a, i32 42
1181  ret i32 %r
1182}
1183
1184; Negative test
1185
1186define i32 @add_smin_wrong_wrap(i32 %x) {
1187; CHECK-LABEL: @add_smin_wrong_wrap(
1188; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1189; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42)
1190; CHECK-NEXT:    ret i32 [[TMP1]]
1191;
1192  %a = add nuw i32 %x, 15
1193  %c = icmp slt i32 %a, 42
1194  %r = select i1 %c, i32 %a, i32 42
1195  ret i32 %r
1196}
1197
1198; Negative test
1199
1200define i32 @add_smin_extra_use(i32 %x, i32* %p) {
1201; CHECK-LABEL: @add_smin_extra_use(
1202; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1203; CHECK-NEXT:    store i32 [[A]], i32* [[P:%.*]], align 4
1204; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42)
1205; CHECK-NEXT:    ret i32 [[TMP1]]
1206;
1207  %a = add nsw i32 %x, 15
1208  store i32 %a, i32* %p
1209  %c = icmp slt i32 %a, 42
1210  %r = select i1 %c, i32 %a, i32 42
1211  ret i32 %r
1212}
1213
1214define <2 x i16> @add_smin_vec(<2 x i16> %x) {
1215; CHECK-LABEL: @add_smin_vec(
1216; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> <i16 225, i16 225>)
1217; CHECK-NEXT:    [[TMP2:%.*]] = add nsw <2 x i16> [[TMP1]], <i16 15, i16 15>
1218; CHECK-NEXT:    ret <2 x i16> [[TMP2]]
1219;
1220  %a = add nsw <2 x i16> %x, <i16 15, i16 15>
1221  %c = icmp slt <2 x i16> %a, <i16 240, i16 240>
1222  %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240>
1223  ret <2 x i16> %r
1224}
1225
1226define i37 @add_smax(i37 %x) {
1227; CHECK-LABEL: @add_smax(
1228; CHECK-NEXT:    [[TMP1:%.*]] = call i37 @llvm.smax.i37(i37 [[X:%.*]], i37 37)
1229; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw i37 [[TMP1]], 5
1230; CHECK-NEXT:    ret i37 [[TMP2]]
1231;
1232  %a = add nsw i37 %x, 5
1233  %c = icmp sgt i37 %a, 42
1234  %r = select i1 %c, i37 %a, i37 42
1235  ret i37 %r
1236}
1237
1238define i8 @add_smax_constant_limit(i8 %x) {
1239; CHECK-LABEL: @add_smax_constant_limit(
1240; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -127)
1241; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i8 [[TMP1]], 125
1242; CHECK-NEXT:    ret i8 [[TMP2]]
1243;
1244  %a = add nsw i8 %x, 125
1245  %c = icmp sgt i8 %a, -2
1246  %r = select i1 %c, i8 %a, i8 -2
1247  ret i8 %r
1248}
1249
1250; Negative test
1251; TODO: assert that instsimplify always gets this?
1252
1253define i8 @add_smax_simplify(i8 %x) {
1254; CHECK-LABEL: @add_smax_simplify(
1255; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X:%.*]], 126
1256; CHECK-NEXT:    ret i8 [[A]]
1257;
1258  %a = add nsw i8 %x, 126
1259  %c = icmp sgt i8 %a, -2
1260  %r = select i1 %c, i8 %a, i8 -2
1261  ret i8 %r
1262}
1263
1264; Negative test
1265; TODO: assert that instsimplify always gets this?
1266
1267define i8 @add_smax_simplify2(i8 %x) {
1268; CHECK-LABEL: @add_smax_simplify2(
1269; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X:%.*]], 127
1270; CHECK-NEXT:    ret i8 [[A]]
1271;
1272  %a = add nsw i8 %x, 127
1273  %c = icmp sgt i8 %a, -2
1274  %r = select i1 %c, i8 %a, i8 -2
1275  ret i8 %r
1276}
1277
1278; Negative test
1279
1280define i32 @add_smax_wrong_pred(i32 %x) {
1281; CHECK-LABEL: @add_smax_wrong_pred(
1282; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1283; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42)
1284; CHECK-NEXT:    ret i32 [[TMP1]]
1285;
1286  %a = add nsw i32 %x, 15
1287  %c = icmp ugt i32 %a, 42
1288  %r = select i1 %c, i32 %a, i32 42
1289  ret i32 %r
1290}
1291
1292; Negative test
1293
1294define i32 @add_smax_wrong_wrap(i32 %x) {
1295; CHECK-LABEL: @add_smax_wrong_wrap(
1296; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15
1297; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42)
1298; CHECK-NEXT:    ret i32 [[TMP1]]
1299;
1300  %a = add nuw i32 %x, 15
1301  %c = icmp sgt i32 %a, 42
1302  %r = select i1 %c, i32 %a, i32 42
1303  ret i32 %r
1304}
1305
1306; Negative test
1307
1308define i32 @add_smax_extra_use(i32 %x, i32* %p) {
1309; CHECK-LABEL: @add_smax_extra_use(
1310; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15
1311; CHECK-NEXT:    store i32 [[A]], i32* [[P:%.*]], align 4
1312; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42)
1313; CHECK-NEXT:    ret i32 [[TMP1]]
1314;
1315  %a = add nsw i32 %x, 15
1316  store i32 %a, i32* %p
1317  %c = icmp sgt i32 %a, 42
1318  %r = select i1 %c, i32 %a, i32 42
1319  ret i32 %r
1320}
1321
1322define <2 x i33> @add_smax_vec(<2 x i33> %x) {
1323; CHECK-LABEL: @add_smax_vec(
1324; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i33> @llvm.smax.v2i33(<2 x i33> [[X:%.*]], <2 x i33> <i33 235, i33 235>)
1325; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw <2 x i33> [[TMP1]], <i33 5, i33 5>
1326; CHECK-NEXT:    ret <2 x i33> [[TMP2]]
1327;
1328  %a = add nsw <2 x i33> %x, <i33 5, i33 5>
1329  %c = icmp sgt <2 x i33> %a, <i33 240, i33 240>
1330  %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240>
1331  ret <2 x i33> %r
1332}
1333
1334define i8 @PR14613_smin(i8 %x) {
1335; CHECK-LABEL: @PR14613_smin(
1336; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 40)
1337; CHECK-NEXT:    [[NARROW:%.*]] = add nsw i8 [[TMP1]], 15
1338; CHECK-NEXT:    ret i8 [[NARROW]]
1339;
1340  %u4 = sext i8 %x to i32
1341  %u5 = add nuw nsw i32 %u4, 15
1342  %u6 = icmp slt i32 %u5, 55
1343  %u7 = select i1 %u6, i32 %u5, i32 55
1344  %r = trunc i32 %u7 to i8
1345  ret i8 %r
1346}
1347
1348define i8 @PR14613_smax(i8 %x) {
1349; CHECK-LABEL: @PR14613_smax(
1350; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 40)
1351; CHECK-NEXT:    [[NARROW:%.*]] = add nuw i8 [[TMP1]], 15
1352; CHECK-NEXT:    ret i8 [[NARROW]]
1353;
1354  %u4 = sext i8 %x to i32
1355  %u5 = add nuw nsw i32 %u4, 15
1356  %u6 = icmp sgt i32 %u5, 55
1357  %u7 = select i1 %u6, i32 %u5, i32 55
1358  %r = trunc i32 %u7 to i8
1359  ret i8 %r
1360}
1361
1362define i8 @PR46271(<2 x i8> %x) {
1363; CHECK-LABEL: @PR46271(
1364; CHECK-NEXT:    [[A:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
1365; CHECK-NEXT:    [[B:%.*]] = select <2 x i1> [[A]], <2 x i8> [[X]], <2 x i8> <i8 poison, i8 -1>
1366; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i8> [[B]], i64 1
1367; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], -1
1368; CHECK-NEXT:    ret i8 [[R]]
1369;
1370  %a = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
1371  %b = select <2 x i1> %a, <2 x i8> %x, <2 x i8> <i8 undef, i8 -1>
1372  %not = xor <2 x i8> %b, <i8 undef, i8 -1>
1373  %r = extractelement <2 x i8> %not, i32 1
1374  ret i8 %r
1375}
1376
1377define i32 @twoway_clamp_lt(i32 %num) {
1378; CHECK-LABEL: @twoway_clamp_lt(
1379; CHECK-NEXT:  entry:
1380; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[NUM:%.*]], 13767
1381; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[TMP0]], i32 13768, i32 13767
1382; CHECK-NEXT:    ret i32 [[TMP1]]
1383;
1384entry:
1385  %cmp1 = icmp slt i32 %num, 13768
1386  %s1 = select i1 %cmp1, i32 %num, i32 13768
1387  %cmp2 = icmp sgt i32 %s1, 13767
1388  %r = select i1 %cmp2, i32 %s1, i32 13767
1389  ret i32 %r
1390}
1391
1392define i32 @twoway_clamp_gt(i32 %num) {
1393; CHECK-LABEL: @twoway_clamp_gt(
1394; CHECK-NEXT:  entry:
1395; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.smax.i32(i32 [[NUM:%.*]], i32 13767)
1396; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 13768)
1397; CHECK-NEXT:    ret i32 [[TMP1]]
1398;
1399entry:
1400  %cmp1 = icmp sgt i32 %num, 13767
1401  %s1 = select i1 %cmp1, i32 %num, i32 13767
1402  %cmp2 = icmp slt i32 %s1, 13768
1403  %r = select i1 %cmp2, i32 %s1, i32 13768
1404  ret i32 %r
1405}
1406
1407define i32 @twoway_clamp_gt_nonconst(i32 %num, i32 %k) {
1408; CHECK-LABEL: @twoway_clamp_gt_nonconst(
1409; CHECK-NEXT:  entry:
1410; CHECK-NEXT:    [[K1:%.*]] = add i32 [[K:%.*]], 1
1411; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.smax.i32(i32 [[NUM:%.*]], i32 [[K]])
1412; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP0]], i32 [[K1]])
1413; CHECK-NEXT:    ret i32 [[TMP1]]
1414;
1415entry:
1416  %k1 = add i32 %k, 1
1417  %cmp1 = icmp sgt i32 %num, %k
1418  %s1 = select i1 %cmp1, i32 %num, i32 %k
1419  %cmp2 = icmp slt i32 %s1, %k1
1420  %r = select i1 %cmp2, i32 %s1, i32 %k1
1421  ret i32 %r
1422}
1423