[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstSimplify / floating-point-arithmetic.ll
blobee097ffab094516dab411d4c05a8ac7edfc9b5c6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instsimplify -S | FileCheck %s
4 ; fneg (fneg X) ==> X
5 define float @fneg_fneg_var(float %a) {
6 ; CHECK-LABEL: @fneg_fneg_var(
7 ; CHECK-NEXT:    ret float [[A:%.*]]
9   %r  = fneg float %a
10   %r1 = fneg float %r
11   ret float %r1
14 ; fneg (fsub -0.0, X) ==> X
15 define float @fsub_-0_x(float %a) {
16 ; CHECK-LABEL: @fsub_-0_x(
17 ; CHECK-NEXT:    ret float [[A:%.*]]
19   %t1 = fsub float -0.0, %a
20   %ret = fneg float %t1
21   ret float %ret
24 define <2 x float> @fsub_-0_x_vec(<2 x float> %a) {
25 ; CHECK-LABEL: @fsub_-0_x_vec(
26 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
28   %t1 = fsub <2 x float> <float -0.0, float -0.0>, %a
29   %ret = fneg <2 x float> %t1
30   ret <2 x float> %ret
33 define <2 x float> @fsub_-0_x_vec_undef_elts(<2 x float> %a) {
34 ; CHECK-LABEL: @fsub_-0_x_vec_undef_elts(
35 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
37   %t1 = fsub <2 x float> <float -0.0, float undef>, %a
38   %ret = fneg <2 x float> %t1
39   ret <2 x float> %ret
42 define <2 x float> @fsub_negzero_vec_undef_elts(<2 x float> %x) {
43 ; CHECK-LABEL: @fsub_negzero_vec_undef_elts(
44 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
46   %r = fsub nsz <2 x float> %x, <float undef, float -0.0>
47   ret <2 x float> %r
50 ; fsub -0.0, (fsub -0.0, X) ==> X
51 define float @fsub_-0_-0_x(float %a) {
52 ; CHECK-LABEL: @fsub_-0_-0_x(
53 ; CHECK-NEXT:    ret float [[A:%.*]]
55   %t1 = fsub float -0.0, %a
56   %ret = fsub float -0.0, %t1
57   ret float %ret
60 ; fsub -0.0, (fneg X) ==> X
61 define float @fneg_x(float %a) {
62 ; CHECK-LABEL: @fneg_x(
63 ; CHECK-NEXT:    ret float [[A:%.*]]
65   %t1 = fneg float %a
66   %ret = fsub float -0.0, %t1
67   ret float %ret
70 define <2 x float> @fsub_-0_-0_x_vec(<2 x float> %a) {
71 ; CHECK-LABEL: @fsub_-0_-0_x_vec(
72 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
74   %t1 = fsub <2 x float> <float -0.0, float -0.0>, %a
75   %ret = fsub <2 x float> <float -0.0, float -0.0>, %t1
76   ret <2 x float> %ret
79 define <2 x float> @fneg_x_vec(<2 x float> %a) {
80 ; CHECK-LABEL: @fneg_x_vec(
81 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
83   %t1 = fneg <2 x float> %a
84   %ret = fsub <2 x float> <float -0.0, float -0.0>, %t1
85   ret <2 x float> %ret
88 define <2 x float> @fsub_-0_-0_x_vec_undef_elts(<2 x float> %a) {
89 ; CHECK-LABEL: @fsub_-0_-0_x_vec_undef_elts(
90 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
92   %t1 = fsub <2 x float> <float undef, float -0.0>, %a
93   %ret = fsub <2 x float> <float -0.0, float undef>, %t1
94   ret <2 x float> %ret
97 define <2 x float> @fneg_x_vec_undef_elts(<2 x float> %a) {
98 ; CHECK-LABEL: @fneg_x_vec_undef_elts(
99 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
101   %t1 = fneg <2 x float> %a
102   %ret = fsub <2 x float> <float -0.0, float undef>, %t1
103   ret <2 x float> %ret
106 ; fsub -0.0, (fsub 0.0, X) != X
107 define float @fsub_-0_0_x(float %a) {
108 ; CHECK-LABEL: @fsub_-0_0_x(
109 ; CHECK-NEXT:    [[T1:%.*]] = fsub float 0.000000e+00, [[A:%.*]]
110 ; CHECK-NEXT:    [[RET:%.*]] = fsub float -0.000000e+00, [[T1]]
111 ; CHECK-NEXT:    ret float [[RET]]
113   %t1 = fsub float 0.0, %a
114   %ret = fsub float -0.0, %t1
115   ret float %ret
118 ; fsub 0.0, (fsub -0.0, X) != X
119 define float @fsub_0_-0_x(float %a) {
120 ; CHECK-LABEL: @fsub_0_-0_x(
121 ; CHECK-NEXT:    [[T1:%.*]] = fsub float -0.000000e+00, [[A:%.*]]
122 ; CHECK-NEXT:    [[RET:%.*]] = fsub float 0.000000e+00, [[T1]]
123 ; CHECK-NEXT:    ret float [[RET]]
125   %t1 = fsub float -0.0, %a
126   %ret = fsub float 0.0, %t1
127   ret float %ret
130 ; fsub X, 0 ==> X
131 define float @fsub_x_0(float %x) {
132 ; CHECK-LABEL: @fsub_x_0(
133 ; CHECK-NEXT:    ret float [[X:%.*]]
135   %r = fsub float %x, 0.0
136   ret float %r
139 define <2 x float> @fsub_x_0_vec_undef(<2 x float> %x) {
140 ; CHECK-LABEL: @fsub_x_0_vec_undef(
141 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
143   %r = fsub <2 x float> %x, <float undef, float 0.0>
144   ret <2 x float> %r
147 ; fadd X, -0 ==> X
148 define float @fadd_x_n0(float %a) {
149 ; CHECK-LABEL: @fadd_x_n0(
150 ; CHECK-NEXT:    ret float [[A:%.*]]
152   %ret = fadd float %a, -0.0
153   ret float %ret
156 define <2 x float> @fadd_x_n0_vec_undef_elt(<2 x float> %a) {
157 ; CHECK-LABEL: @fadd_x_n0_vec_undef_elt(
158 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
160   %ret = fadd <2 x float> %a, <float -0.0, float undef>
161   ret <2 x float> %ret
164 ; fmul X, 1.0 ==> X
165 define double @fmul_X_1(double %a) {
166 ; CHECK-LABEL: @fmul_X_1(
167 ; CHECK-NEXT:    ret double [[A:%.*]]
169   %b = fmul double 1.0, %a
170   ret double %b
173 ; PR2642
174 define <4 x float> @fmul_X_1_vec(<4 x float> %x) {
175 ; CHECK-LABEL: @fmul_X_1_vec(
176 ; CHECK-NEXT:    ret <4 x float> [[X:%.*]]
178   %m = fmul <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0>
179   ret <4 x float> %m
182 ; fdiv X, 1.0 ==> X
183 define float @fdiv_x_1(float %a) {
184 ; CHECK-LABEL: @fdiv_x_1(
185 ; CHECK-NEXT:    ret float [[A:%.*]]
187   %ret = fdiv float %a, 1.0
188   ret float %ret
191 ; We can't optimize away the fadd in this test because the input
192 ; value to the function and subsequently to the fadd may be -0.0.
193 ; In that one special case, the result of the fadd should be +0.0
194 ; rather than the first parameter of the fadd.
196 ; Fragile test warning: We need 6 sqrt calls to trigger the bug
197 ; because the internal logic has a magic recursion limit of 6.
198 ; This is presented without any explanation or ability to customize.
200 declare float @sqrtf(float)
202 define float @PR22688(float %x) {
203 ; CHECK-LABEL: @PR22688(
204 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @sqrtf(float [[X:%.*]])
205 ; CHECK-NEXT:    [[TMP2:%.*]] = call float @sqrtf(float [[TMP1]])
206 ; CHECK-NEXT:    [[TMP3:%.*]] = call float @sqrtf(float [[TMP2]])
207 ; CHECK-NEXT:    [[TMP4:%.*]] = call float @sqrtf(float [[TMP3]])
208 ; CHECK-NEXT:    [[TMP5:%.*]] = call float @sqrtf(float [[TMP4]])
209 ; CHECK-NEXT:    [[TMP6:%.*]] = call float @sqrtf(float [[TMP5]])
210 ; CHECK-NEXT:    [[TMP7:%.*]] = fadd float [[TMP6]], 0.000000e+00
211 ; CHECK-NEXT:    ret float [[TMP7]]
213   %1 = call float @sqrtf(float %x)
214   %2 = call float @sqrtf(float %1)
215   %3 = call float @sqrtf(float %2)
216   %4 = call float @sqrtf(float %3)
217   %5 = call float @sqrtf(float %4)
218   %6 = call float @sqrtf(float %5)
219   %7 = fadd float %6, 0.0
220   ret float %7
223 declare float @llvm.fabs.f32(float)
224 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
225 declare float @llvm.sqrt.f32(float)
227 define float @fabs_select_positive_constants(i32 %c) {
228 ; CHECK-LABEL: @fabs_select_positive_constants(
229 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
230 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
231 ; CHECK-NEXT:    ret float [[SELECT]]
233   %cmp = icmp eq i32 %c, 0
234   %select = select i1 %cmp, float 1.0, float 2.0
235   %fabs = call float @llvm.fabs.f32(float %select)
236   ret float %fabs
239 define <2 x float> @fabs_select_positive_constants_vector(i32 %c) {
240 ; CHECK-LABEL: @fabs_select_positive_constants_vector(
241 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
242 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> <float 2.000000e+00, float 2.000000e+00>
243 ; CHECK-NEXT:    ret <2 x float> [[SELECT]]
245   %cmp = icmp eq i32 %c, 0
246   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
247   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
248   ret <2 x float> %fabs
251 define float @fabs_select_constant_variable(i32 %c, float %x) {
252 ; CHECK-LABEL: @fabs_select_constant_variable(
253 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
254 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float [[X:%.*]]
255 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
256 ; CHECK-NEXT:    ret float [[FABS]]
258   %cmp = icmp eq i32 %c, 0
259   %select = select i1 %cmp, float 1.0, float %x
260   %fabs = call float @llvm.fabs.f32(float %select)
261   ret float %fabs
264 define <2 x float> @fabs_select_constant_variable_vector(i32 %c, <2 x float> %x) {
265 ; CHECK-LABEL: @fabs_select_constant_variable_vector(
266 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
267 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]]
268 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
269 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
271   %cmp = icmp eq i32 %c, 0
272   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> %x
273   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
274   ret <2 x float> %fabs
277 define float @fabs_select_neg0_pos0(i32 %c) {
278 ; CHECK-LABEL: @fabs_select_neg0_pos0(
279 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
280 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float 0.000000e+00
281 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
282 ; CHECK-NEXT:    ret float [[FABS]]
284   %cmp = icmp eq i32 %c, 0
285   %select = select i1 %cmp, float -0.0, float 0.0
286   %fabs = call float @llvm.fabs.f32(float %select)
287   ret float %fabs
290 define <2 x float> @fabs_select_neg0_pos0_vector(i32 %c) {
291 ; CHECK-LABEL: @fabs_select_neg0_pos0_vector(
292 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
293 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> zeroinitializer
294 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
295 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
297   %cmp = icmp eq i32 %c, 0
298   %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float 0.0, float 0.0>
299   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
300   ret <2 x float> %fabs
303 define float @fabs_select_neg0_neg1(i32 %c) {
304 ; CHECK-LABEL: @fabs_select_neg0_neg1(
305 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
306 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float -1.000000e+00
307 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
308 ; CHECK-NEXT:    ret float [[FABS]]
310   %cmp = icmp eq i32 %c, 0
311   %select = select i1 %cmp, float -0.0, float -1.0
312   %fabs = call float @llvm.fabs.f32(float %select)
313   ret float %fabs
316 define <2 x float> @fabs_select_neg0_neg1_vector(i32 %c) {
317 ; CHECK-LABEL: @fabs_select_neg0_neg1_vector(
318 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
319 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> <float -1.000000e+00, float -1.000000e+00>
320 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
321 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
323   %cmp = icmp eq i32 %c, 0
324   %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float -1.0, float -1.0>
325   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
326   ret <2 x float> %fabs
329 define float @fabs_select_nan_nan(i32 %c) {
330 ; CHECK-LABEL: @fabs_select_nan_nan(
331 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
332 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0x7FF8000000000000, float 0x7FF8000100000000
333 ; CHECK-NEXT:    ret float [[SELECT]]
335   %cmp = icmp eq i32 %c, 0
336   %select = select i1 %cmp, float 0x7FF8000000000000, float 0x7FF8000100000000
337   %fabs = call float @llvm.fabs.f32(float %select)
338   ret float %fabs
341 define <2 x float> @fabs_select_nan_nan_vector(i32 %c) {
342 ; CHECK-LABEL: @fabs_select_nan_nan_vector(
343 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
344 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
345 ; CHECK-NEXT:    ret <2 x float> [[SELECT]]
347   %cmp = icmp eq i32 %c, 0
348   %select = select i1 %cmp, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
349   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
350   ret <2 x float> %fabs
353 define float @fabs_select_negnan_nan(i32 %c) {
354 ; CHECK-LABEL: @fabs_select_negnan_nan(
355 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
356 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000000000000
357 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
358 ; CHECK-NEXT:    ret float [[FABS]]
360   %cmp = icmp eq i32 %c, 0
361   %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000000000000
362   %fabs = call float @llvm.fabs.f32(float %select)
363   ret float %fabs
366 define <2 x float> @fabs_select_negnan_nan_vector(i32 %c) {
367 ; CHECK-LABEL: @fabs_select_negnan_nan_vector(
368 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
369 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
370 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
371 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
373   %cmp = icmp eq i32 %c, 0
374   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
375   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
376   ret <2 x float> %fabs
379 define float @fabs_select_negnan_negnan(i32 %c) {
380 ; CHECK-LABEL: @fabs_select_negnan_negnan(
381 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
382 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000100000000
383 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
384 ; CHECK-NEXT:    ret float [[FABS]]
386   %cmp = icmp eq i32 %c, 0
387   %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000100000000
388   %fabs = call float @llvm.fabs.f32(float %select)
389   ret float %fabs
392 define <2 x float> @fabs_select_negnan_negnan_vector(i32 %c) {
393 ; CHECK-LABEL: @fabs_select_negnan_negnan_vector(
394 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
395 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
396 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
397 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
399   %cmp = icmp eq i32 %c, 0
400   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
401   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
402   ret <2 x float> %fabs
405 define float @fabs_select_negnan_negzero(i32 %c) {
406 ; CHECK-LABEL: @fabs_select_negnan_negzero(
407 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
408 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float -0.000000e+00
409 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
410 ; CHECK-NEXT:    ret float [[FABS]]
412   %cmp = icmp eq i32 %c, 0
413   %select = select i1 %cmp, float 0xFFF8000000000000, float -0.0
414   %fabs = call float @llvm.fabs.f32(float %select)
415   ret float %fabs
418 define <2 x float> @fabs_select_negnan_negzero_vector(i32 %c) {
419 ; CHECK-LABEL: @fabs_select_negnan_negzero_vector(
420 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
421 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.000000e+00, float -0.000000e+00>
422 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
423 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
425   %cmp = icmp eq i32 %c, 0
426   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.0, float -0.0>
427   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
428   ret <2 x float> %fabs
431 define float @fabs_select_negnan_zero(i32 %c) {
432 ; CHECK-LABEL: @fabs_select_negnan_zero(
433 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
434 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0.000000e+00
435 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
436 ; CHECK-NEXT:    ret float [[FABS]]
438   %cmp = icmp eq i32 %c, 0
439   %select = select i1 %cmp, float 0xFFF8000000000000, float 0.0
440   %fabs = call float @llvm.fabs.f32(float %select)
441   ret float %fabs
444 define <2 x float> @fabs_select_negnan_zero_vector(i32 %c) {
445 ; CHECK-LABEL: @fabs_select_negnan_zero_vector(
446 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
447 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> zeroinitializer
448 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
449 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
451   %cmp = icmp eq i32 %c, 0
452   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0.0, float 0.0>
453   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
454   ret <2 x float> %fabs
457 ; The fabs can't be eliminated because llvm.sqrt.f32 may return -0 or NaN with
458 ; an arbitrary sign bit.
459 define float @fabs_sqrt(float %a) {
460 ; CHECK-LABEL: @fabs_sqrt(
461 ; CHECK-NEXT:    [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
462 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
463 ; CHECK-NEXT:    ret float [[FABS]]
465   %sqrt = call float @llvm.sqrt.f32(float %a)
466   %fabs = call float @llvm.fabs.f32(float %sqrt)
467   ret float %fabs
470 ; The fabs can't be eliminated because the nnan sqrt may still return -0.
471 define float @fabs_sqrt_nnan(float %a) {
472 ; CHECK-LABEL: @fabs_sqrt_nnan(
473 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
474 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
475 ; CHECK-NEXT:    ret float [[FABS]]
477   %sqrt = call nnan float @llvm.sqrt.f32(float %a)
478   %fabs = call float @llvm.fabs.f32(float %sqrt)
479   ret float %fabs
482 ; The fabs can't be eliminated because the nsz sqrt may still return NaN.
483 define float @fabs_sqrt_nsz(float %a) {
484 ; CHECK-LABEL: @fabs_sqrt_nsz(
485 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz float @llvm.sqrt.f32(float [[A:%.*]])
486 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
487 ; CHECK-NEXT:    ret float [[FABS]]
489   %sqrt = call nsz float @llvm.sqrt.f32(float %a)
490   %fabs = call float @llvm.fabs.f32(float %sqrt)
491   ret float %fabs
494 ; The fabs can be eliminated because we're nsz and nnan.
495 define float @fabs_sqrt_nnan_nsz(float %a) {
496 ; CHECK-LABEL: @fabs_sqrt_nnan_nsz(
497 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan nsz float @llvm.sqrt.f32(float [[A:%.*]])
498 ; CHECK-NEXT:    ret float [[SQRT]]
500   %sqrt = call nnan nsz float @llvm.sqrt.f32(float %a)
501   %fabs = call float @llvm.fabs.f32(float %sqrt)
502   ret float %fabs
505 ; The second fabs can be eliminated because the operand to sqrt cannot be -0.
506 define float @fabs_sqrt_nnan_fabs(float %a) {
507 ; CHECK-LABEL: @fabs_sqrt_nnan_fabs(
508 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
509 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[B]])
510 ; CHECK-NEXT:    ret float [[SQRT]]
512   %b = call float @llvm.fabs.f32(float %a)
513   %sqrt = call nnan float @llvm.sqrt.f32(float %b)
514   %fabs = call float @llvm.fabs.f32(float %sqrt)
515   ret float %fabs
518 define float @fabs_select_positive_constants_vector_extract(i32 %c) {
519 ; CHECK-LABEL: @fabs_select_positive_constants_vector_extract(
520 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
521 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> <float 2.000000e+00, float 2.000000e+00>
522 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <2 x float> [[SELECT]], i32 0
523 ; CHECK-NEXT:    ret float [[EXTRACT]]
525   %cmp = icmp eq i32 %c, 0
526   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
527   %extract = extractelement <2 x float> %select, i32 0
528   %fabs = call float @llvm.fabs.f32(float %extract)
529   ret float %fabs
532 declare float @llvm.minnum.f32(float, float)
533 declare float @llvm.maxnum.f32(float, float)
534 declare double @llvm.minnum.f64(double, double)
535 declare double @llvm.maxnum.f64(double, double)
536 declare <2 x double> @llvm.minnum.v2f64(<2 x double>, <2 x double>)
537 declare <2 x double> @llvm.maxnum.v2f64(<2 x double>, <2 x double>)
539 ; From the LangRef for minnum/maxnum:
540 ; "If either operand is a NaN, returns the other non-NaN operand."
542 define double @maxnum_nan_op0(double %x) {
543 ; CHECK-LABEL: @maxnum_nan_op0(
544 ; CHECK-NEXT:    ret double [[X:%.*]]
546   %r = call double @llvm.maxnum.f64(double 0x7ff8000000000000, double %x)
547   ret double %r
550 define double @maxnum_nan_op1(double %x) {
551 ; CHECK-LABEL: @maxnum_nan_op1(
552 ; CHECK-NEXT:    ret double [[X:%.*]]
554   %r = call double @llvm.maxnum.f64(double %x, double 0x7ff800000000dead)
555   ret double %r
558 define double @minnum_nan_op0(double %x) {
559 ; CHECK-LABEL: @minnum_nan_op0(
560 ; CHECK-NEXT:    ret double [[X:%.*]]
562   %r = call double @llvm.minnum.f64(double 0x7ff8000dead00000, double %x)
563   ret double %r
566 define double @minnum_nan_op1(double %x) {
567 ; CHECK-LABEL: @minnum_nan_op1(
568 ; CHECK-NEXT:    ret double [[X:%.*]]
570   %r = call double @llvm.minnum.f64(double %x, double 0x7ff800dead00dead)
571   ret double %r
574 define <2 x double> @maxnum_nan_op0_vec(<2 x double> %x) {
575 ; CHECK-LABEL: @maxnum_nan_op0_vec(
576 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
578   %r = call <2 x double> @llvm.maxnum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> %x)
579   ret <2 x double> %r
582 define <2 x double> @maxnum_nan_op1_vec(<2 x double> %x) {
583 ; CHECK-LABEL: @maxnum_nan_op1_vec(
584 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
586   %r = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800000000dead, double 0x7ff8ffffffffffff>)
587   ret <2 x double> %r
590 define <2 x double> @minnum_nan_op0_vec(<2 x double> %x) {
591 ; CHECK-LABEL: @minnum_nan_op0_vec(
592 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
594   %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> <double undef, double 0x7ff8000dead00000>, <2 x double> %x)
595   ret <2 x double> %r
598 define <2 x double> @minnum_nan_op1_vec(<2 x double> %x) {
599 ; CHECK-LABEL: @minnum_nan_op1_vec(
600 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
602   %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800dead00dead, double 0x7ff800dead00dead>)
603   ret <2 x double> %r
606 define float @maxnum_undef_op1(float %x) {
607 ; CHECK-LABEL: @maxnum_undef_op1(
608 ; CHECK-NEXT:    ret float [[X:%.*]]
610   %val = call float @llvm.maxnum.f32(float %x, float undef)
611   ret float %val
614 define float @maxnum_undef_op0(float %x) {
615 ; CHECK-LABEL: @maxnum_undef_op0(
616 ; CHECK-NEXT:    ret float [[X:%.*]]
618   %val = call float @llvm.maxnum.f32(float undef, float %x)
619   ret float %val
622 define float @minnum_undef_op1(float %x) {
623 ; CHECK-LABEL: @minnum_undef_op1(
624 ; CHECK-NEXT:    ret float [[X:%.*]]
626   %val = call float @llvm.minnum.f32(float %x, float undef)
627   ret float %val
630 define float @minnum_undef_op0(float %x) {
631 ; CHECK-LABEL: @minnum_undef_op0(
632 ; CHECK-NEXT:    ret float [[X:%.*]]
634   %val = call float @llvm.minnum.f32(float undef, float %x)
635   ret float %val
638 define float @minnum_undef_undef(float %x) {
639 ; CHECK-LABEL: @minnum_undef_undef(
640 ; CHECK-NEXT:    ret float undef
642   %val = call float @llvm.minnum.f32(float undef, float undef)
643   ret float %val
646 define float @maxnum_undef_undef(float %x) {
647 ; CHECK-LABEL: @maxnum_undef_undef(
648 ; CHECK-NEXT:    ret float undef
650   %val = call float @llvm.maxnum.f32(float undef, float undef)
651   ret float %val
654 define float @minnum_same_args(float %x) {
655 ; CHECK-LABEL: @minnum_same_args(
656 ; CHECK-NEXT:    ret float [[X:%.*]]
658   %y = call float @llvm.minnum.f32(float %x, float %x)
659   ret float %y
662 define float @maxnum_same_args(float %x) {
663 ; CHECK-LABEL: @maxnum_same_args(
664 ; CHECK-NEXT:    ret float [[X:%.*]]
666   %y = call float @llvm.maxnum.f32(float %x, float %x)
667   ret float %y
670 define float @minnum_x_minnum_x_y(float %x, float %y) {
671 ; CHECK-LABEL: @minnum_x_minnum_x_y(
672 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
673 ; CHECK-NEXT:    ret float [[A]]
675   %a = call float @llvm.minnum.f32(float %x, float %y)
676   %b = call float @llvm.minnum.f32(float %x, float %a)
677   ret float %b
680 define float @minnum_y_minnum_x_y(float %x, float %y) {
681 ; CHECK-LABEL: @minnum_y_minnum_x_y(
682 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
683 ; CHECK-NEXT:    ret float [[A]]
685   %a = call float @llvm.minnum.f32(float %x, float %y)
686   %b = call float @llvm.minnum.f32(float %y, float %a)
687   ret float %b
690 define float @minnum_x_y_minnum_x(float %x, float %y) {
691 ; CHECK-LABEL: @minnum_x_y_minnum_x(
692 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
693 ; CHECK-NEXT:    ret float [[A]]
695   %a = call float @llvm.minnum.f32(float %x, float %y)
696   %b = call float @llvm.minnum.f32(float %a, float %x)
697   ret float %b
700 define float @minnum_x_y_minnum_y(float %x, float %y) {
701 ; CHECK-LABEL: @minnum_x_y_minnum_y(
702 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
703 ; CHECK-NEXT:    ret float [[A]]
705   %a = call float @llvm.minnum.f32(float %x, float %y)
706   %b = call float @llvm.minnum.f32(float %a, float %y)
707   ret float %b
710 ; negative test
712 define float @minnum_z_minnum_x_y(float %x, float %y, float %z) {
713 ; CHECK-LABEL: @minnum_z_minnum_x_y(
714 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
715 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.minnum.f32(float [[Z:%.*]], float [[A]])
716 ; CHECK-NEXT:    ret float [[B]]
718   %a = call float @llvm.minnum.f32(float %x, float %y)
719   %b = call float @llvm.minnum.f32(float %z, float %a)
720   ret float %b
723 ; negative test
725 define float @minnum_x_y_minnum_z(float %x, float %y, float %z) {
726 ; CHECK-LABEL: @minnum_x_y_minnum_z(
727 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
728 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[Z:%.*]])
729 ; CHECK-NEXT:    ret float [[B]]
731   %a = call float @llvm.minnum.f32(float %x, float %y)
732   %b = call float @llvm.minnum.f32(float %a, float %z)
733   ret float %b
736 ; minnum(X, -INF) --> -INF
738 define float @minnum_neginf(float %x) {
739 ; CHECK-LABEL: @minnum_neginf(
740 ; CHECK-NEXT:    ret float 0xFFF0000000000000
742   %val = call float @llvm.minnum.f32(float %x, float 0xFFF0000000000000)
743   ret float %val
746 define <2 x double> @minnum_neginf_commute_vec(<2 x double> %x) {
747 ; CHECK-LABEL: @minnum_neginf_commute_vec(
748 ; CHECK-NEXT:    ret <2 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000>
750   %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000>, <2 x double> %x)
751   ret <2 x double> %r
754 ; negative test
756 define float @minnum_inf(float %x) {
757 ; CHECK-LABEL: @minnum_inf(
758 ; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.minnum.f32(float 0x7FF0000000000000, float [[X:%.*]])
759 ; CHECK-NEXT:    ret float [[VAL]]
761   %val = call float @llvm.minnum.f32(float 0x7FF0000000000000, float %x)
762   ret float %val
764 define float @maxnum_x_maxnum_x_y(float %x, float %y) {
765 ; CHECK-LABEL: @maxnum_x_maxnum_x_y(
766 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
767 ; CHECK-NEXT:    ret float [[A]]
769   %a = call float @llvm.maxnum.f32(float %x, float %y)
770   %b = call float @llvm.maxnum.f32(float %x, float %a)
771   ret float %b
774 define float @maxnum_y_maxnum_x_y(float %x, float %y) {
775 ; CHECK-LABEL: @maxnum_y_maxnum_x_y(
776 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
777 ; CHECK-NEXT:    ret float [[A]]
779   %a = call float @llvm.maxnum.f32(float %x, float %y)
780   %b = call float @llvm.maxnum.f32(float %y, float %a)
781   ret float %b
784 define float @maxnum_x_y_maxnum_x(float %x, float %y) {
785 ; CHECK-LABEL: @maxnum_x_y_maxnum_x(
786 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
787 ; CHECK-NEXT:    ret float [[A]]
789   %a = call float @llvm.maxnum.f32(float %x, float %y)
790   %b = call float @llvm.maxnum.f32(float %a, float %x)
791   ret float %b
794 define float @maxnum_x_y_maxnum_y(float %x, float %y) {
795 ; CHECK-LABEL: @maxnum_x_y_maxnum_y(
796 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
797 ; CHECK-NEXT:    ret float [[A]]
799   %a = call float @llvm.maxnum.f32(float %x, float %y)
800   %b = call float @llvm.maxnum.f32(float %a, float %y)
801   ret float %b
804 ; negative test
806 define float @maxnum_z_maxnum_x_y(float %x, float %y, float %z) {
807 ; CHECK-LABEL: @maxnum_z_maxnum_x_y(
808 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
809 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.maxnum.f32(float [[Z:%.*]], float [[A]])
810 ; CHECK-NEXT:    ret float [[B]]
812   %a = call float @llvm.maxnum.f32(float %x, float %y)
813   %b = call float @llvm.maxnum.f32(float %z, float %a)
814   ret float %b
817 ; negative test
819 define float @maxnum_x_y_maxnum_z(float %x, float %y, float %z) {
820 ; CHECK-LABEL: @maxnum_x_y_maxnum_z(
821 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
822 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[Z:%.*]])
823 ; CHECK-NEXT:    ret float [[B]]
825   %a = call float @llvm.maxnum.f32(float %x, float %y)
826   %b = call float @llvm.maxnum.f32(float %a, float %z)
827   ret float %b
830 ; maxnum(X, INF) --> INF
832 define <2 x double> @maxnum_inf(<2 x double> %x) {
833 ; CHECK-LABEL: @maxnum_inf(
834 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF0000000000000, double 0x7FF0000000000000>
836   %val = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %x, <2 x double><double 0x7FF0000000000000, double 0x7FF0000000000000>)
837   ret <2 x double> %val
840 define float @maxnum_inf_commute(float %x) {
841 ; CHECK-LABEL: @maxnum_inf_commute(
842 ; CHECK-NEXT:    ret float 0x7FF0000000000000
844   %val = call float @llvm.maxnum.f32(float 0x7FF0000000000000, float %x)
845   ret float %val
848 ; negative test
850 define float @maxnum_neginf(float %x) {
851 ; CHECK-LABEL: @maxnum_neginf(
852 ; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.maxnum.f32(float 0xFFF0000000000000, float [[X:%.*]])
853 ; CHECK-NEXT:    ret float [[VAL]]
855   %val = call float @llvm.maxnum.f32(float 0xFFF0000000000000, float %x)
856   ret float %val
859 declare float @llvm.minimum.f32(float, float)
860 declare float @llvm.maximum.f32(float, float)
861 declare double @llvm.minimum.f64(double, double)
862 declare double @llvm.maximum.f64(double, double)
863 declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>)
864 declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>)
866 ; From the LangRef for minimum/maximum:
867 ; "If either operand is a NaN, returns NaN."
869 define double @maximum_nan_op0(double %x) {
870 ; CHECK-LABEL: @maximum_nan_op0(
871 ; CHECK-NEXT:    ret double 0x7FF8000000000000
873   %r = call double @llvm.maximum.f64(double 0x7ff8000000000000, double %x)
874   ret double %r
877 define double @maximum_nan_op1(double %x) {
878 ; CHECK-LABEL: @maximum_nan_op1(
879 ; CHECK-NEXT:    ret double 0x7FF800000000DEAD
881   %r = call double @llvm.maximum.f64(double %x, double 0x7ff800000000dead)
882   ret double %r
885 define double @minimum_nan_op0(double %x) {
886 ; CHECK-LABEL: @minimum_nan_op0(
887 ; CHECK-NEXT:    ret double 0x7FF8000DEAD00000
889   %r = call double @llvm.minimum.f64(double 0x7ff8000dead00000, double %x)
890   ret double %r
893 define double @minimum_nan_op1(double %x) {
894 ; CHECK-LABEL: @minimum_nan_op1(
895 ; CHECK-NEXT:    ret double 0x7FF800DEAD00DEAD
897   %r = call double @llvm.minimum.f64(double %x, double 0x7ff800dead00dead)
898   ret double %r
901 define <2 x double> @maximum_nan_op0_vec(<2 x double> %x) {
902 ; CHECK-LABEL: @maximum_nan_op0_vec(
903 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double undef>
905   %r = call <2 x double> @llvm.maximum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> %x)
906   ret <2 x double> %r
909 define <2 x double> @maximum_nan_op1_vec(<2 x double> %x) {
910 ; CHECK-LABEL: @maximum_nan_op1_vec(
911 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF800000000DEAD, double 0x7FF8FFFFFFFFFFFF>
913   %r = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800000000dead, double 0x7ff8ffffffffffff>)
914   ret <2 x double> %r
917 define <2 x double> @minimum_nan_op0_vec(<2 x double> %x) {
918 ; CHECK-LABEL: @minimum_nan_op0_vec(
919 ; CHECK-NEXT:    ret <2 x double> <double undef, double 0x7FF8000DEAD00000>
921   %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> <double undef, double 0x7ff8000dead00000>, <2 x double> %x)
922   ret <2 x double> %r
925 define <2 x double> @minimum_nan_op1_vec(<2 x double> %x) {
926 ; CHECK-LABEL: @minimum_nan_op1_vec(
927 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF800DEAD00DEAD, double 0x7FF800DEAD00DEAD>
929   %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800dead00dead, double 0x7ff800dead00dead>)
930   ret <2 x double> %r
933 define float @maximum_undef_op1(float %x) {
934 ; CHECK-LABEL: @maximum_undef_op1(
935 ; CHECK-NEXT:    ret float [[X:%.*]]
937   %val = call float @llvm.maximum.f32(float %x, float undef)
938   ret float %val
941 define float @maximum_undef_op0(float %x) {
942 ; CHECK-LABEL: @maximum_undef_op0(
943 ; CHECK-NEXT:    ret float [[X:%.*]]
945   %val = call float @llvm.maximum.f32(float undef, float %x)
946   ret float %val
949 define float @minimum_undef_op1(float %x) {
950 ; CHECK-LABEL: @minimum_undef_op1(
951 ; CHECK-NEXT:    ret float [[X:%.*]]
953   %val = call float @llvm.minimum.f32(float %x, float undef)
954   ret float %val
957 define float @minimum_undef_op0(float %x) {
958 ; CHECK-LABEL: @minimum_undef_op0(
959 ; CHECK-NEXT:    ret float [[X:%.*]]
961   %val = call float @llvm.minimum.f32(float undef, float %x)
962   ret float %val
965 define float @minimum_undef_undef(float %x) {
966 ; CHECK-LABEL: @minimum_undef_undef(
967 ; CHECK-NEXT:    ret float undef
969   %val = call float @llvm.minimum.f32(float undef, float undef)
970   ret float %val
973 define float @maximum_undef_undef(float %x) {
974 ; CHECK-LABEL: @maximum_undef_undef(
975 ; CHECK-NEXT:    ret float undef
977   %val = call float @llvm.maximum.f32(float undef, float undef)
978   ret float %val
981 define float @minimum_same_args(float %x) {
982 ; CHECK-LABEL: @minimum_same_args(
983 ; CHECK-NEXT:    ret float [[X:%.*]]
985   %y = call float @llvm.minimum.f32(float %x, float %x)
986   ret float %y
989 define float @maximum_same_args(float %x) {
990 ; CHECK-LABEL: @maximum_same_args(
991 ; CHECK-NEXT:    ret float [[X:%.*]]
993   %y = call float @llvm.maximum.f32(float %x, float %x)
994   ret float %y
997 define float @minimum_x_minimum_x_y(float %x, float %y) {
998 ; CHECK-LABEL: @minimum_x_minimum_x_y(
999 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1000 ; CHECK-NEXT:    ret float [[A]]
1002   %a = call float @llvm.minimum.f32(float %x, float %y)
1003   %b = call float @llvm.minimum.f32(float %x, float %a)
1004   ret float %b
1007 define float @minimum_y_minimum_x_y(float %x, float %y) {
1008 ; CHECK-LABEL: @minimum_y_minimum_x_y(
1009 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1010 ; CHECK-NEXT:    ret float [[A]]
1012   %a = call float @llvm.minimum.f32(float %x, float %y)
1013   %b = call float @llvm.minimum.f32(float %y, float %a)
1014   ret float %b
1017 define float @minimum_x_y_minimum_x(float %x, float %y) {
1018 ; CHECK-LABEL: @minimum_x_y_minimum_x(
1019 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1020 ; CHECK-NEXT:    ret float [[A]]
1022   %a = call float @llvm.minimum.f32(float %x, float %y)
1023   %b = call float @llvm.minimum.f32(float %a, float %x)
1024   ret float %b
1027 define float @minimum_x_y_minimum_y(float %x, float %y) {
1028 ; CHECK-LABEL: @minimum_x_y_minimum_y(
1029 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1030 ; CHECK-NEXT:    ret float [[A]]
1032   %a = call float @llvm.minimum.f32(float %x, float %y)
1033   %b = call float @llvm.minimum.f32(float %a, float %y)
1034   ret float %b
1037 ; negative test
1039 define float @minimum_z_minimum_x_y(float %x, float %y, float %z) {
1040 ; CHECK-LABEL: @minimum_z_minimum_x_y(
1041 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1042 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.minimum.f32(float [[Z:%.*]], float [[A]])
1043 ; CHECK-NEXT:    ret float [[B]]
1045   %a = call float @llvm.minimum.f32(float %x, float %y)
1046   %b = call float @llvm.minimum.f32(float %z, float %a)
1047   ret float %b
1050 ; negative test
1052 define float @minimum_x_y_minimum_z(float %x, float %y, float %z) {
1053 ; CHECK-LABEL: @minimum_x_y_minimum_z(
1054 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1055 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.minimum.f32(float [[A]], float [[Z:%.*]])
1056 ; CHECK-NEXT:    ret float [[B]]
1058   %a = call float @llvm.minimum.f32(float %x, float %y)
1059   %b = call float @llvm.minimum.f32(float %a, float %z)
1060   ret float %b
1063 ; minimum(X, -INF) --> -INF
1065 define float @minimum_neginf(float %x) {
1066 ; CHECK-LABEL: @minimum_neginf(
1067 ; CHECK-NEXT:    ret float 0xFFF0000000000000
1069   %val = call float @llvm.minimum.f32(float %x, float 0xFFF0000000000000)
1070   ret float %val
1073 define <2 x double> @minimum_neginf_commute_vec(<2 x double> %x) {
1074 ; CHECK-LABEL: @minimum_neginf_commute_vec(
1075 ; CHECK-NEXT:    ret <2 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000>
1077   %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000>, <2 x double> %x)
1078   ret <2 x double> %r
1081 ; negative test
1083 define float @minimum_inf(float %x) {
1084 ; CHECK-LABEL: @minimum_inf(
1085 ; CHECK-NEXT:    [[VAL:%.*]] = call float @llvm.minimum.f32(float 0x7FF0000000000000, float [[X:%.*]])
1086 ; CHECK-NEXT:    ret float [[VAL]]
1088   %val = call float @llvm.minimum.f32(float 0x7FF0000000000000, float %x)
1089   ret float %val
1091 define float @maximum_x_maximum_x_y(float %x, float %y) {
1092 ; CHECK-LABEL: @maximum_x_maximum_x_y(
1093 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1094 ; CHECK-NEXT:    ret float [[A]]
1096   %a = call float @llvm.maximum.f32(float %x, float %y)
1097   %b = call float @llvm.maximum.f32(float %x, float %a)
1098   ret float %b
1101 define float @maximum_y_maximum_x_y(float %x, float %y) {
1102 ; CHECK-LABEL: @maximum_y_maximum_x_y(
1103 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1104 ; CHECK-NEXT:    ret float [[A]]
1106   %a = call float @llvm.maximum.f32(float %x, float %y)
1107   %b = call float @llvm.maximum.f32(float %y, float %a)
1108   ret float %b
1111 define float @maximum_x_y_maximum_x(float %x, float %y) {
1112 ; CHECK-LABEL: @maximum_x_y_maximum_x(
1113 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1114 ; CHECK-NEXT:    ret float [[A]]
1116   %a = call float @llvm.maximum.f32(float %x, float %y)
1117   %b = call float @llvm.maximum.f32(float %a, float %x)
1118   ret float %b
1121 define float @maximum_x_y_maximum_y(float %x, float %y) {
1122 ; CHECK-LABEL: @maximum_x_y_maximum_y(
1123 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1124 ; CHECK-NEXT:    ret float [[A]]
1126   %a = call float @llvm.maximum.f32(float %x, float %y)
1127   %b = call float @llvm.maximum.f32(float %a, float %y)
1128   ret float %b
1131 ; negative test
1133 define float @maximum_z_maximum_x_y(float %x, float %y, float %z) {
1134 ; CHECK-LABEL: @maximum_z_maximum_x_y(
1135 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1136 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.maximum.f32(float [[Z:%.*]], float [[A]])
1137 ; CHECK-NEXT:    ret float [[B]]
1139   %a = call float @llvm.maximum.f32(float %x, float %y)
1140   %b = call float @llvm.maximum.f32(float %z, float %a)
1141   ret float %b
1144 ; negative test
1146 define float @maximum_x_y_maximum_z(float %x, float %y, float %z) {
1147 ; CHECK-LABEL: @maximum_x_y_maximum_z(
1148 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1149 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.maximum.f32(float [[A]], float [[Z:%.*]])
1150 ; CHECK-NEXT:    ret float [[B]]
1152   %a = call float @llvm.maximum.f32(float %x, float %y)
1153   %b = call float @llvm.maximum.f32(float %a, float %z)
1154   ret float %b
1157 ; maximum(X, INF) --> INF
1159 define <2 x double> @maximum_inf(<2 x double> %x) {
1160 ; CHECK-LABEL: @maximum_inf(
1161 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF0000000000000, double 0x7FF0000000000000>
1163   %val = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double><double 0x7FF0000000000000, double 0x7FF0000000000000>)
1164   ret <2 x double> %val
1167 define float @maximum_inf_commute(float %x) {
1168 ; CHECK-LABEL: @maximum_inf_commute(
1169 ; CHECK-NEXT:    ret float 0x7FF0000000000000
1171   %val = call float @llvm.maximum.f32(float 0x7FF0000000000000, float %x)
1172   ret float %val
1175 ; Y - (Y - X) --> X
1177 define float @fsub_fsub_common_op(float %x, float %y) {
1178 ; CHECK-LABEL: @fsub_fsub_common_op(
1179 ; CHECK-NEXT:    ret float [[X:%.*]]
1181   %s = fsub float %y, %x
1182   %r = fsub reassoc nsz float %y, %s
1183   ret float %r
1186 define <2 x float> @fsub_fsub_common_op_vec(<2 x float> %x, <2 x float> %y) {
1187 ; CHECK-LABEL: @fsub_fsub_common_op_vec(
1188 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
1190   %s = fsub <2 x float> %y, %x
1191   %r = fsub reassoc nsz <2 x float> %y, %s
1192   ret <2 x float> %r
1195 ; Negative test - fsub is not commutative.
1196 ; Y - (X - Y) --> (Y - X) + Y (canonicalized)
1198 define float @fsub_fsub_wrong_common_op(float %x, float %y) {
1199 ; CHECK-LABEL: @fsub_fsub_wrong_common_op(
1200 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1201 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[Y]], [[S]]
1202 ; CHECK-NEXT:    ret float [[R]]
1204   %s = fsub float %x, %y
1205   %r = fsub reassoc nsz float %y, %s
1206   ret float %r
1209 ; Negative test - negated operand needed.
1210 ; (Y - X) - Y --> -X
1212 define float @fsub_fsub_common_op_wrong_commute(float %x, float %y) {
1213 ; CHECK-LABEL: @fsub_fsub_common_op_wrong_commute(
1214 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
1215 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
1216 ; CHECK-NEXT:    ret float [[R]]
1218   %s = fsub float %y, %x
1219   %r = fsub reassoc nsz float %s, %y
1220   ret float %r
1223 ; Negative test - fsub is not commutative.
1224 ; (X - Y) - Y --> ?
1226 define float @fsub_fsub_wrong_common_op_wrong_commute(float %x, float %y) {
1227 ; CHECK-LABEL: @fsub_fsub_wrong_common_op_wrong_commute(
1228 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1229 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
1230 ; CHECK-NEXT:    ret float [[R]]
1232   %s = fsub float %x, %y
1233   %r = fsub reassoc nsz float %s, %y
1234   ret float %r
1237 ; (Y + X) - Y --> X
1239 define float @fadd_fsub_common_op(float %x, float %y) {
1240 ; CHECK-LABEL: @fadd_fsub_common_op(
1241 ; CHECK-NEXT:    ret float [[X:%.*]]
1243   %a = fadd float %y, %x
1244   %r = fsub reassoc nsz float %a, %y
1245   ret float %r
1248 ; (X + Y) - Y --> X
1250 define <2 x float> @fadd_fsub_common_op_commute_vec(<2 x float> %x, <2 x float> %y) {
1251 ; CHECK-LABEL: @fadd_fsub_common_op_commute_vec(
1252 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
1254   %a = fadd <2 x float> %x, %y
1255   %r = fsub reassoc nsz <2 x float> %a, %y
1256   ret <2 x float> %r
1259 ; Negative test - negated operand needed.
1260 ; Y - (Y + X) --> -X
1262 define float @fadd_fsub_common_op_wrong_commute(float %x, float %y) {
1263 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute(
1264 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[Y:%.*]], [[X:%.*]]
1265 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
1266 ; CHECK-NEXT:    ret float [[R]]
1268   %a = fadd float %y, %x
1269   %r = fsub reassoc nsz float %y, %a
1270   ret float %r
1273 ; Negative test - negated operand needed.
1274 ; Y - (X + Y) --> -X
1276 define float @fadd_fsub_common_op_wrong_commute_commute(float %x, float %y) {
1277 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute_commute(
1278 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], [[Y:%.*]]
1279 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
1280 ; CHECK-NEXT:    ret float [[R]]
1282   %a = fadd float %x, %y
1283   %r = fsub reassoc nsz float %y, %a
1284   ret float %r
1287 ; Y + (X - Y) --> X
1289 define <2 x float> @fsub_fadd_common_op_vec(<2 x float> %x, <2 x float> %y) {
1290 ; CHECK-LABEL: @fsub_fadd_common_op_vec(
1291 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
1293   %s = fsub <2 x float> %x, %y
1294   %r = fadd reassoc nsz <2 x float> %y, %s
1295   ret <2 x float> %r
1298 ; (X - Y) + Y --> X
1300 define float @fsub_fadd_common_op_commute(float %x, float %y) {
1301 ; CHECK-LABEL: @fsub_fadd_common_op_commute(
1302 ; CHECK-NEXT:    ret float [[X:%.*]]
1304   %s = fsub float %x, %y
1305   %r = fadd reassoc nsz float %s, %y
1306   ret float %r
1309 ; Negative test.
1310 ; Y + (Y - X) --> ?
1312 define float @fsub_fadd_common_op_wrong_commute(float %x, float %y) {
1313 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute(
1314 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
1315 ; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz float [[Y]], [[S]]
1316 ; CHECK-NEXT:    ret float [[R]]
1318   %s = fsub float %y, %x
1319   %r = fadd reassoc nsz float %y, %s
1320   ret float %r
1323 ; Negative test.
1324 ; (Y - X) + Y --> ?
1326 define float @fsub_fadd_common_op_wrong_commute_commute(float %x, float %y) {
1327 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute_commute(
1328 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
1329 ; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz float [[S]], [[Y]]
1330 ; CHECK-NEXT:    ret float [[R]]
1332   %s = fsub float %y, %x
1333   %r = fadd reassoc nsz float %s, %y
1334   ret float %r