xref: /llvm-project/llvm/test/Transforms/InstSimplify/ConstProp/min-max.ll (revision 6cfd3439d4b99be85f647849168e1076a9737170)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
3
4declare float @llvm.minnum.f32(float, float)
5declare bfloat @llvm.minnum.bf16(bfloat, bfloat)
6declare half @llvm.minnum.f16(half, half)
7declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>)
8declare <4 x bfloat> @llvm.minnum.v4bf16(<4 x bfloat>, <4 x bfloat>)
9declare <4 x half> @llvm.minnum.v4f16(<4 x half>, <4 x half>)
10
11declare float @llvm.maxnum.f32(float, float)
12declare bfloat @llvm.maxnum.bf16(bfloat, bfloat)
13declare half @llvm.maxnum.f16(half, half)
14declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)
15declare <4 x bfloat> @llvm.maxnum.v4bf16(<4 x bfloat>, <4 x bfloat>)
16declare <4 x half> @llvm.maxnum.v4f16(<4 x half>, <4 x half>)
17
18declare float @llvm.minimum.f32(float, float)
19declare bfloat @llvm.minimum.bf16(bfloat, bfloat)
20declare half @llvm.minimum.f16(half, half)
21declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>)
22declare <4 x bfloat> @llvm.minimum.v4bf16(<4 x bfloat>, <4 x bfloat>)
23declare <4 x half> @llvm.minimum.v4f16(<4 x half>, <4 x half>)
24
25declare float @llvm.maximum.f32(float, float)
26declare bfloat @llvm.maximum.bf16(bfloat, bfloat)
27declare half @llvm.maximum.f16(half, half)
28declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>)
29declare <4 x bfloat> @llvm.maximum.v4bf16(<4 x bfloat>, <4 x bfloat>)
30declare <4 x half> @llvm.maximum.v4f16(<4 x half>, <4 x half>)
31
32declare i8 @llvm.smax.i8(i8, i8)
33declare <5 x i8> @llvm.smax.v5i8(<5 x i8>, <5 x i8>)
34
35declare i8 @llvm.smin.i8(i8, i8)
36declare <5 x i8> @llvm.smin.v5i8(<5 x i8>, <5 x i8>)
37
38declare i8 @llvm.umax.i8(i8, i8)
39declare <5 x i8> @llvm.umax.v5i8(<5 x i8>, <5 x i8>)
40
41declare i8 @llvm.umin.i8(i8, i8)
42declare <5 x i8> @llvm.umin.v5i8(<5 x i8>, <5 x i8>)
43
44define float @minnum_float() {
45; CHECK-LABEL: @minnum_float(
46; CHECK-NEXT:    ret float 5.000000e+00
47;
48  %1 = call float @llvm.minnum.f32(float 5.0, float 42.0)
49  ret float %1
50}
51
52define float @minnum_float_p0_n0() {
53; CHECK-LABEL: @minnum_float_p0_n0(
54; CHECK-NEXT:    ret float -0.000000e+00
55;
56  %min = call float @llvm.minnum.f32(float 0.0, float -0.0)
57  ret float %min
58}
59
60define float @minnum_float_n0_p0() {
61; CHECK-LABEL: @minnum_float_n0_p0(
62; CHECK-NEXT:    ret float -0.000000e+00
63;
64  %min = call float @llvm.minnum.f32(float -0.0, float 0.0)
65  ret float %min
66}
67
68define float @minnum_float_p0_qnan() {
69; CHECK-LABEL: @minnum_float_p0_qnan(
70; CHECK-NEXT:    ret float 0.000000e+00
71;
72  %min = call float @llvm.minnum.f32(float 0.0, float 0x7FF8000000000000)
73  ret float %min
74}
75
76define float @minnum_float_qnan_p0() {
77; CHECK-LABEL: @minnum_float_qnan_p0(
78; CHECK-NEXT:    ret float 0.000000e+00
79;
80  %min = call float @llvm.minnum.f32(float 0x7FF8000000000000, float 0.0)
81  ret float %min
82}
83
84define bfloat @minnum_bfloat() {
85; CHECK-LABEL: @minnum_bfloat(
86; CHECK-NEXT:    ret bfloat 0xR40A0
87;
88  %1 = call bfloat @llvm.minnum.bf16(bfloat 5.0, bfloat 42.0)
89  ret bfloat %1
90}
91
92define half @minnum_half() {
93; CHECK-LABEL: @minnum_half(
94; CHECK-NEXT:    ret half 0xH4500
95;
96  %1 = call half @llvm.minnum.f16(half 5.0, half 42.0)
97  ret half %1
98}
99
100; Check that minnum constant folds to propagate non-NaN or smaller argument
101
102define <4 x float> @minnum_float_vec() {
103; CHECK-LABEL: @minnum_float_vec(
104; CHECK-NEXT:    ret <4 x float> <float 0x7FF8000000000000, float 5.000000e+00, float 4.200000e+01, float 5.000000e+00>
105;
106  %1 = call <4 x float> @llvm.minnum.v4f32(<4 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 42., float 42.>, <4 x float> <float 0x7FF8000000000000, float 5., float 0x7FF8000000000000, float 5.>)
107  ret <4 x float> %1
108}
109
110define <4 x bfloat> @minnum_bfloat_vec() {
111; CHECK-LABEL: @minnum_bfloat_vec(
112; CHECK-NEXT:    ret <4 x bfloat> <bfloat 0xR7FC0, bfloat 0xR40A0, bfloat 0xR4228, bfloat 0xR40A0>
113;
114  %1 = call <4 x bfloat> @llvm.minnum.v4bf16(<4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 0x7FF8000000000000, bfloat 42., bfloat 42.>, <4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 5., bfloat 0x7FF8000000000000, bfloat 5.>)
115  ret <4 x bfloat> %1
116}
117
118define <4 x half> @minnum_half_vec() {
119; CHECK-LABEL: @minnum_half_vec(
120; CHECK-NEXT:    ret <4 x half> <half 0xH7E00, half 0xH4500, half 0xH5140, half 0xH4500>
121;
122  %1 = call <4 x half> @llvm.minnum.v4f16(<4 x half> <half 0x7FF8000000000000, half 0x7FF8000000000000, half 42., half 42.>, <4 x half> <half 0x7FF8000000000000, half 5., half 0x7FF8000000000000, half 5.>)
123  ret <4 x half> %1
124}
125
126; Check that minnum constant folds to propagate one of its argument zeros
127
128define <4 x float> @minnum_float_zeros_vec() {
129; CHECK-LABEL: @minnum_float_zeros_vec(
130; CHECK-NEXT:    ret <4 x float> <float 0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>
131;
132  %1 = call <4 x float> @llvm.minnum.v4f32(<4 x float> <float 0.0, float -0.0, float 0.0, float -0.0>, <4 x float> <float 0.0, float 0.0, float -0.0, float -0.0>)
133  ret <4 x float> %1
134}
135
136define float @maxnum_float() {
137; CHECK-LABEL: @maxnum_float(
138; CHECK-NEXT:    ret float 4.200000e+01
139;
140  %1 = call float @llvm.maxnum.f32(float 5.0, float 42.0)
141  ret float %1
142}
143
144define float @maxnum_float_p0_n0() {
145; CHECK-LABEL: @maxnum_float_p0_n0(
146; CHECK-NEXT:    ret float 0.000000e+00
147;
148  %max = call float @llvm.maxnum.f32(float 0.0, float -0.0)
149  ret float %max
150}
151
152define float @maxnum_float_n0_p0() {
153; CHECK-LABEL: @maxnum_float_n0_p0(
154; CHECK-NEXT:    ret float 0.000000e+00
155;
156  %max = call float @llvm.maxnum.f32(float -0.0, float 0.0)
157  ret float %max
158}
159
160define float @maxnum_float_p0_qnan() {
161; CHECK-LABEL: @maxnum_float_p0_qnan(
162; CHECK-NEXT:    ret float 0.000000e+00
163;
164  %max = call float @llvm.maxnum.f32(float 0.0, float 0x7FF8000000000000)
165  ret float %max
166}
167
168define float @maxnum_float_qnan_p0() {
169; CHECK-LABEL: @maxnum_float_qnan_p0(
170; CHECK-NEXT:    ret float 0.000000e+00
171;
172  %max = call float @llvm.maxnum.f32(float 0x7FF8000000000000, float 0.0)
173  ret float %max
174}
175
176define bfloat @maxnum_bfloat() {
177; CHECK-LABEL: @maxnum_bfloat(
178; CHECK-NEXT:    ret bfloat 0xR4228
179;
180  %1 = call bfloat @llvm.maxnum.bf16(bfloat 5.0, bfloat 42.0)
181  ret bfloat %1
182}
183
184define half @maxnum_half() {
185; CHECK-LABEL: @maxnum_half(
186; CHECK-NEXT:    ret half 0xH5140
187;
188  %1 = call half @llvm.maxnum.f16(half 5.0, half 42.0)
189  ret half %1
190}
191
192; Check that maxnum constant folds to propagate non-NaN or greater argument
193
194define <4 x float> @maxnum_float_vec() {
195; CHECK-LABEL: @maxnum_float_vec(
196; CHECK-NEXT:    ret <4 x float> <float 0x7FF8000000000000, float 5.000000e+00, float 4.200000e+01, float 4.200000e+01>
197;
198  %1 = call <4 x float> @llvm.maxnum.v4f32(<4 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 42., float 42.>, <4 x float> <float 0x7FF8000000000000, float 5., float 0x7FF8000000000000, float 5.>)
199  ret <4 x float> %1
200}
201
202define <4 x bfloat> @maxnum_bfloat_vec() {
203; CHECK-LABEL: @maxnum_bfloat_vec(
204; CHECK-NEXT:    ret <4 x bfloat> <bfloat 0xR7FC0, bfloat 0xR40A0, bfloat 0xR4228, bfloat 0xR4228>
205;
206  %1 = call <4 x bfloat> @llvm.maxnum.v4bf16(<4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 0x7FF8000000000000, bfloat 42., bfloat 42.>, <4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 5., bfloat 0x7FF8000000000000, bfloat 5.>)
207  ret <4 x bfloat> %1
208}
209
210define <4 x half> @maxnum_half_vec() {
211; CHECK-LABEL: @maxnum_half_vec(
212; CHECK-NEXT:    ret <4 x half> <half 0xH7E00, half 0xH4500, half 0xH5140, half 0xH5140>
213;
214  %1 = call <4 x half> @llvm.maxnum.v4f16(<4 x half> <half 0x7FF8000000000000, half 0x7FF8000000000000, half 42., half 42.>, <4 x half> <half 0x7FF8000000000000, half 5., half 0x7FF8000000000000, half 5.>)
215  ret <4 x half> %1
216}
217
218; Check that maxnum constant folds to propagate one of its argument zeros
219
220define <4 x float> @maxnum_float_zeros_vec() {
221; CHECK-LABEL: @maxnum_float_zeros_vec(
222; CHECK-NEXT:    ret <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float -0.000000e+00>
223;
224  %1 = call <4 x float> @llvm.maxnum.v4f32(<4 x float> <float 0.0, float -0.0, float 0.0, float -0.0>, <4 x float> <float 0.0, float 0.0, float -0.0, float -0.0>)
225  ret <4 x float> %1
226}
227
228define float @minimum_float() {
229; CHECK-LABEL: @minimum_float(
230; CHECK-NEXT:    ret float 5.000000e+00
231;
232  %1 = call float @llvm.minimum.f32(float 5.0, float 42.0)
233  ret float %1
234}
235
236define bfloat @minimum_bfloat() {
237; CHECK-LABEL: @minimum_bfloat(
238; CHECK-NEXT:    ret bfloat 0xR40A0
239;
240  %1 = call bfloat @llvm.minimum.bf16(bfloat 5.0, bfloat 42.0)
241  ret bfloat %1
242}
243
244define half @minimum_half() {
245; CHECK-LABEL: @minimum_half(
246; CHECK-NEXT:    ret half 0xH4500
247;
248  %1 = call half @llvm.minimum.f16(half 5.0, half 42.0)
249  ret half %1
250}
251
252; Check that minimum propagates its NaN or smaller argument
253
254define <4 x float> @minimum_float_vec() {
255; CHECK-LABEL: @minimum_float_vec(
256; CHECK-NEXT:    ret <4 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000000000000, float 5.000000e+00>
257;
258  %1 = call <4 x float> @llvm.minimum.v4f32(<4 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 42., float 42.>, <4 x float> <float 0x7FF8000000000000, float 5., float 0x7FF8000000000000, float 5.>)
259  ret <4 x float> %1
260}
261
262define <4 x bfloat> @minimum_bfloat_vec() {
263; CHECK-LABEL: @minimum_bfloat_vec(
264; CHECK-NEXT:    ret <4 x bfloat> <bfloat 0xR7FC0, bfloat 0xR7FC0, bfloat 0xR7FC0, bfloat 0xR40A0>
265;
266  %1 = call <4 x bfloat> @llvm.minimum.v4bf16(<4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 0x7FF8000000000000, bfloat 42., bfloat 42.>, <4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 5., bfloat 0x7FF8000000000000, bfloat 5.>)
267  ret <4 x bfloat> %1
268}
269
270define <4 x half> @minimum_half_vec() {
271; CHECK-LABEL: @minimum_half_vec(
272; CHECK-NEXT:    ret <4 x half> <half 0xH7E00, half 0xH7E00, half 0xH7E00, half 0xH4500>
273;
274  %1 = call <4 x half> @llvm.minimum.v4f16(<4 x half> <half 0x7FF8000000000000, half 0x7FF8000000000000, half 42., half 42.>, <4 x half> <half 0x7FF8000000000000, half 5., half 0x7FF8000000000000, half 5.>)
275  ret <4 x half> %1
276}
277
278; Check that minimum treats -0.0 as smaller than 0.0 while constant folding
279
280define <4 x float> @minimum_float_zeros_vec() {
281; CHECK-LABEL: @minimum_float_zeros_vec(
282; CHECK-NEXT:    ret <4 x float> <float 0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>
283;
284  %1 = call <4 x float> @llvm.minimum.v4f32(<4 x float> <float 0.0, float -0.0, float 0.0, float -0.0>, <4 x float> <float 0.0, float 0.0, float -0.0, float -0.0>)
285  ret <4 x float> %1
286}
287
288define float @maximum_float() {
289; CHECK-LABEL: @maximum_float(
290; CHECK-NEXT:    ret float 4.200000e+01
291;
292  %1 = call float @llvm.maximum.f32(float 5.0, float 42.0)
293  ret float %1
294}
295
296define bfloat @maximum_bfloat() {
297; CHECK-LABEL: @maximum_bfloat(
298; CHECK-NEXT:    ret bfloat 0xR4228
299;
300  %1 = call bfloat @llvm.maximum.bf16(bfloat 5.0, bfloat 42.0)
301  ret bfloat %1
302}
303
304define half @maximum_half() {
305; CHECK-LABEL: @maximum_half(
306; CHECK-NEXT:    ret half 0xH5140
307;
308  %1 = call half @llvm.maximum.f16(half 5.0, half 42.0)
309  ret half %1
310}
311
312; Check that maximum propagates its NaN or greater argument
313
314define <4 x float> @maximum_float_vec() {
315; CHECK-LABEL: @maximum_float_vec(
316; CHECK-NEXT:    ret <4 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000000000000, float 4.200000e+01>
317;
318  %1 = call <4 x float> @llvm.maximum.v4f32(<4 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 42., float 42.>, <4 x float> <float 0x7FF8000000000000, float 5., float 0x7FF8000000000000, float 5.>)
319  ret <4 x float> %1
320}
321
322define <4 x bfloat> @maximum_bfloat_vec() {
323; CHECK-LABEL: @maximum_bfloat_vec(
324; CHECK-NEXT:    ret <4 x bfloat> <bfloat 0xR7FC0, bfloat 0xR7FC0, bfloat 0xR7FC0, bfloat 0xR4228>
325;
326  %1 = call <4 x bfloat> @llvm.maximum.v4bf16(<4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 0x7FF8000000000000, bfloat 42., bfloat 42.>, <4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 5., bfloat 0x7FF8000000000000, bfloat 5.>)
327  ret <4 x bfloat> %1
328}
329
330define <4 x half> @maximum_half_vec() {
331; CHECK-LABEL: @maximum_half_vec(
332; CHECK-NEXT:    ret <4 x half> <half 0xH7E00, half 0xH7E00, half 0xH7E00, half 0xH5140>
333;
334  %1 = call <4 x half> @llvm.maximum.v4f16(<4 x half> <half 0x7FF8000000000000, half 0x7FF8000000000000, half 42., half 42.>, <4 x half> <half 0x7FF8000000000000, half 5., half 0x7FF8000000000000, half 5.>)
335  ret <4 x half> %1
336}
337
338; Check that maximum treats -0.0 as smaller than 0.0 while constant folding
339
340define <4 x float> @maximum_float_zeros_vec() {
341; CHECK-LABEL: @maximum_float_zeros_vec(
342; CHECK-NEXT:    ret <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float -0.000000e+00>
343;
344  %1 = call <4 x float> @llvm.maximum.v4f32(<4 x float> <float 0.0, float -0.0, float 0.0, float -0.0>, <4 x float> <float 0.0, float 0.0, float -0.0, float -0.0>)
345  ret <4 x float> %1
346}
347
348define i8 @smax() {
349; CHECK-LABEL: @smax(
350; CHECK-NEXT:    ret i8 -127
351;
352  %r = call i8 @llvm.smax.i8(i8 128, i8 129)
353  ret i8 %r
354}
355
356define <5 x i8> @smax_vec() {
357; CHECK-LABEL: @smax_vec(
358; CHECK-NEXT:    ret <5 x i8> <i8 poison, i8 127, i8 poison, i8 42, i8 127>
359;
360  %r = call <5 x i8> @llvm.smax.v5i8(<5 x i8> <i8 poison, i8 undef, i8 1, i8 42, i8 42>, <5 x i8> <i8 undef, i8 1, i8 poison, i8 42, i8 127>)
361  ret <5 x i8> %r
362}
363
364define i8 @smin() {
365; CHECK-LABEL: @smin(
366; CHECK-NEXT:    ret i8 -128
367;
368  %r = call i8 @llvm.smin.i8(i8 128, i8 127)
369  ret i8 %r
370}
371
372define <5 x i8> @smin_vec() {
373; CHECK-LABEL: @smin_vec(
374; CHECK-NEXT:    ret <5 x i8> <i8 poison, i8 -128, i8 poison, i8 42, i8 -127>
375;
376  %r = call <5 x i8> @llvm.smin.v5i8(<5 x i8> <i8 poison, i8 undef, i8 1, i8 42, i8 42>, <5 x i8> <i8 undef, i8 1, i8 poison, i8 42, i8 129>)
377  ret <5 x i8> %r
378}
379
380define i8 @umax() {
381; CHECK-LABEL: @umax(
382; CHECK-NEXT:    ret i8 -128
383;
384  %r = call i8 @llvm.umax.i8(i8 128, i8 127)
385  ret i8 %r
386}
387
388define <5 x i8> @umax_vec() {
389; CHECK-LABEL: @umax_vec(
390; CHECK-NEXT:    ret <5 x i8> <i8 poison, i8 -1, i8 poison, i8 42, i8 -128>
391;
392  %r = call <5 x i8> @llvm.umax.v5i8(<5 x i8> <i8 poison, i8 undef, i8 1, i8 42, i8 42>, <5 x i8> <i8 undef, i8 1, i8 poison, i8 42, i8 128>)
393  ret <5 x i8> %r
394}
395
396define i8 @umin() {
397; CHECK-LABEL: @umin(
398; CHECK-NEXT:    ret i8 127
399;
400  %r = call i8 @llvm.umin.i8(i8 128, i8 127)
401  ret i8 %r
402}
403
404define <5 x i8> @umin_vec() {
405; CHECK-LABEL: @umin_vec(
406; CHECK-NEXT:    ret <5 x i8> <i8 poison, i8 0, i8 poison, i8 42, i8 42>
407;
408  %r = call <5 x i8> @llvm.umin.v5i8(<5 x i8> <i8 poison, i8 undef, i8 1, i8 42, i8 42>, <5 x i8> <i8 undef, i8 1, i8 poison, i8 42, i8 128>)
409  ret <5 x i8> %r
410}
411