1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -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:%.*]] = 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]]
11;
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
16}
17
18; Check this is converted into canonical form, as above.
19define 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]]
25;
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
30}
31
32; Same as @t2, with flipped operands and zext instead of sext.
33define 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]]
39;
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
44}
45
46; Same again, with trunc.
47define 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]]
53;
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
58}
59
60; Same as @t3, but with mismatched signedness between icmp and zext.
61define 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]]
67;
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
72}
73
74define 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]]
80;
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
85}
86
87define 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]]
93;
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
98}
99
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.
104define 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]]
114;
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
123}
124
125; Ensure this doesn't get converted to a min/max.
126define 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]]
132;
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
137}
138
139define 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]]
145;
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
150}
151
152define 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]]
158;
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
163}
164
165; Reuse the first 2 bitcasts as the select operands.
166
167define <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]]
175;
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
183}
184
185; Switch cmp operand order.
186
187define <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]]
195;
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
203}
204
205; Integer cmp should have the same transforms.
206
207define <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]]
215;
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
223}
224
225; SMIN(SMIN(X, 11), 92) -> SMIN(X, 11)
226define 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]]
231;
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
237}
238
239define <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]]
244;
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
250}
251
252; MIN(MIN(X, 24), 83) -> MIN(X, 24)
253define 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]]
258;
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
264}
265
266; SMAX(SMAX(X, 75), 36) -> SMAX(X, 75)
267define 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]]
272;
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
278}
279
280; MAX(MAX(X, 68), 47) -> MAX(X, 68)
281define 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]]
286;
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
292}
293
294; SMIN(SMIN(X, 92), 11) -> SMIN(X, 11)
295define 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]]
300;
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
306}
307
308define <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]]
313;
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
319}
320
321; MIN(MIN(X, 83), 24) -> MIN(X, 24)
322define 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]]
327;
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
333}
334
335; SMAX(SMAX(X, 36), 75) -> SMAX(X, 75)
336define 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]]
341;
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
347}
348
349; MAX(MAX(X, 47), 68) -> MAX(X, 68)
350define 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]]
355;
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
361}
362
363; The next 10 tests are value clamping with constants:
364; https://llvm.org/bugs/show_bug.cgi?id=31693
365
366; (X <s C1) ? C1 : SMIN(X, C2) ==> SMAX(SMIN(X, C2), C1)
367
368define 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]]
375;
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
381}
382
383; (X >s C1) ? C1 : SMAX(X, C2) ==> SMIN(SMAX(X, C2), C1)
384
385define 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]]
392;
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
398}
399
400; (X >s C1) ? SMIN(X, C2) : C1 ==> SMAX(SMIN(X, C2), C1)
401
402define 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]]
409;
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
415}
416
417; (X <s C1) ? SMAX(X, C2) : C1 ==> SMIN(SMAX(X, C1), C2)
418
419define 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]]
426;
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
432}
433
434; (X <u C1) ? C1 : UMIN(X, C2) ==> UMAX(UMIN(X, C2), C1)
435
436define 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]]
443;
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
449}
450
451; (X >u C1) ? C1 : UMAX(X, C2) ==> UMIN(UMAX(X, C2), C1)
452
453define 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]]
460;
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
466}
467
468; (X >u C1) ? UMIN(X, C2) : C1 ==> UMAX(UMIN(X, C2), C1)
469
470define 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]]
477;
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
483}
484
485; (X <u C1) ? UMAX(X, C2) : C1 ==> UMIN(UMAX(X, C2), C1)
486
487define 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]]
494;
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
500}
501
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)
505define 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]]
512;
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
518}
519; Check that there is no infinite loop in case of:
520; (icmp slt smax(NegativeA, B) 0) -> (icmp slt B 0)
521define 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]]
528;
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
534}
535
536; Check that there is no infinite loop because of reverse cmp transformation:
537; (icmp slt smax(PositiveA, B) 2) -> (icmp eq B 1)
538define 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
550;
551
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
556
557truelabel: ; %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
562
563falselabel:
564  ret i32 0
565}
566
567; The next 3 min tests should canonicalize to the same form...and not infinite loop.
568
569define 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]]
575;
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
580}
581
582define 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]]
588;
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
593}
594
595define 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]]
601;
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
606}
607
608; The next 3 max tests should canonicalize to the same form...and not infinite loop.
609
610define 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]]
616;
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
621}
622
623define 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]]
629;
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
634}
635
636define 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]]
642;
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
647}
648
649; The icmp/select form a canonical smax, so don't hide that by folding the final bitcast into the select.
650
651define 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]]
659;
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
666}
667
668; FIXME: Create a canonical umax by bitcasting the select.
669
670define 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]]
677;
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
683}
684
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.
687
688define <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]]
696;
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
703}
704
705; FIXME: Create a canonical umin by bitcasting the select.
706
707define <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]]
714;
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
720}
721
722; Check that we look through cast and recognize min idiom.
723
724define 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]]
730;
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
735}
736
737; Check that we look through cast but min is not recognized.
738
739define 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]]
745;
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
750}
751
752define <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]]
758;
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
763}
764
765define <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]]
771;
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
776}
777
778; Remove a min/max op in a sequence with a common operand.
779; PR35717: https://bugs.llvm.org/show_bug.cgi?id=35717
780
781; min(min(a, b), min(b, c)) --> min(min(a, b), c)
782
783define 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]]
790;
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
798}
799
800; max(max(a, b), max(c, b)) --> max(max(a, b), c)
801
802define <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]]
809;
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
817}
818
819; min(min(b, c), min(a, b)) --> min(min(b, c), a)
820
821define <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]]
828;
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
836}
837
838; max(max(b, c), max(b, a)) --> max(max(b, c), a)
839
840define 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]]
847;
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
855}
856
857declare void @extra_use(i32)
858
859define 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]]
867;
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
876}
877
878define 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]]
886;
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
895}
896
897define 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]]
908;
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
918}
919
920; This would assert. Don't assume that earlier min/max types match a possible later min/max.
921
922define 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:    [[TMP1:%.*]] = select fast 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:    [[TMP2:%.*]] = select fast 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 [[TMP1]], float [[TMP2]]
930; CHECK-NEXT:    ret float [[R]]
931;
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
939}
940
941define 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]]
947;
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
952}
953
954define i32 @add_umin_constant_limit(i32 %x) {
955; CHECK-LABEL: @add_umin_constant_limit(
956; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[X:%.*]], 0
957; CHECK-NEXT:    [[R:%.*]] = select i1 [[DOTNOT]], i32 41, i32 42
958; CHECK-NEXT:    ret i32 [[R]]
959;
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
964}
965
966; Negative test
967; TODO: assert that instsimplify always gets this?
968
969define i32 @add_umin_simplify(i32 %x) {
970; CHECK-LABEL: @add_umin_simplify(
971; CHECK-NEXT:    ret i32 42
972;
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
977}
978
979; Negative test
980; TODO: assert that instsimplify always gets this?
981
982define i32 @add_umin_simplify2(i32 %x) {
983; CHECK-LABEL: @add_umin_simplify2(
984; CHECK-NEXT:    ret i32 42
985;
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
990}
991
992; Negative test
993
994define 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]]
1000;
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
1005}
1006
1007; Negative test
1008
1009define 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]]
1015;
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
1020}
1021
1022; Negative test
1023
1024define 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]]
1031;
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
1037}
1038
1039define <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]]
1045;
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
1050}
1051
1052define 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]]
1058;
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
1063}
1064
1065define 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]]
1071;
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
1076}
1077
1078; Negative test
1079; TODO: assert that instsimplify always gets this?
1080
1081define 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]]
1085;
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
1090}
1091
1092; Negative test
1093; TODO: assert that instsimplify always gets this?
1094
1095define 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]]
1099;
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
1104}
1105
1106; Negative test
1107
1108define 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]]
1114;
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
1119}
1120
1121; Negative test
1122
1123define 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]]
1129;
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
1134}
1135
1136; Negative test
1137
1138define 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]]
1145;
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
1151}
1152
1153define <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]]
1159;
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
1164}
1165
1166define i8 @PR14613_umin(i8 %x) {
1167; CHECK-LABEL: @PR14613_umin(
1168; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 15)
1169; CHECK-NEXT:    ret i8 [[TMP1]]
1170;
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
1177}
1178
1179define i8 @PR14613_umax(i8 %x) {
1180; CHECK-LABEL: @PR14613_umax(
1181; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], -16
1182; CHECK-NEXT:    [[X_OP:%.*]] = add i8 [[X]], 15
1183; CHECK-NEXT:    [[U7:%.*]] = select i1 [[TMP1]], i8 [[X_OP]], i8 -1
1184; CHECK-NEXT:    ret i8 [[U7]]
1185;
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
1192}
1193
1194define 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]]
1200;
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
1205}
1206
1207define 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]]
1213;
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
1218}
1219
1220; Negative test
1221; TODO: assert that instsimplify always gets this?
1222
1223define 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]]
1227;
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
1232}
1233
1234; Negative test
1235; TODO: assert that instsimplify always gets this?
1236
1237define 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]]
1241;
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
1246}
1247
1248; Negative test
1249
1250define 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]]
1256;
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
1261}
1262
1263; Negative test
1264
1265define 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]]
1271;
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
1276}
1277
1278; Negative test
1279
1280define 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]]
1287;
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
1293}
1294
1295define <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]]
1301;
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
1306}
1307
1308define 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]]
1314;
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
1319}
1320
1321define 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]]
1327;
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
1332}
1333
1334; Negative test
1335; TODO: assert that instsimplify always gets this?
1336
1337define 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]]
1341;
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
1346}
1347
1348; Negative test
1349; TODO: assert that instsimplify always gets this?
1350
1351define 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]]
1355;
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
1360}
1361
1362; Negative test
1363
1364define 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]]
1370;
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
1375}
1376
1377; Negative test
1378
1379define 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]]
1385;
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
1390}
1391
1392; Negative test
1393
1394define 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]]
1401;
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
1407}
1408
1409define <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]]
1415;
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
1420}
1421
1422define i8 @PR14613_smin(i8 %x) {
1423; CHECK-LABEL: @PR14613_smin(
1424; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 40
1425; CHECK-NEXT:    [[X_OP:%.*]] = add i8 [[X]], 15
1426; CHECK-NEXT:    [[U7:%.*]] = select i1 [[TMP1]], i8 [[X_OP]], i8 55
1427; CHECK-NEXT:    ret i8 [[U7]]
1428;
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
1435}
1436
1437define i8 @PR14613_smax(i8 %x) {
1438; CHECK-LABEL: @PR14613_smax(
1439; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[X:%.*]], 40
1440; CHECK-NEXT:    [[X_OP:%.*]] = add i8 [[X]], 15
1441; CHECK-NEXT:    [[U7:%.*]] = select i1 [[TMP1]], i8 [[X_OP]], i8 55
1442; CHECK-NEXT:    ret i8 [[U7]]
1443;
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
1450}
1451
1452define i8 @PR46271(<2 x i8> %x) {
1453; CHECK-LABEL: @PR46271(
1454; CHECK-NEXT:    [[A:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
1455; CHECK-NEXT:    [[B:%.*]] = select <2 x i1> [[A]], <2 x i8> [[X]], <2 x i8> <i8 undef, i8 -1>
1456; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i8> [[B]], i32 1
1457; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], -1
1458; CHECK-NEXT:    ret i8 [[R]]
1459;
1460  %a = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
1461  %b = select <2 x i1> %a, <2 x i8> %x, <2 x i8> <i8 undef, i8 -1>
1462  %not = xor <2 x i8> %b, <i8 undef, i8 -1>
1463  %r = extractelement <2 x i8> %not, i32 1
1464  ret i8 %r
1465}
1466