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