[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstSimplify / floating-point-arithmetic.ll
blobb1dd69c19f8136db2495ced54078af481668e68c
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)
226 declare float @llvm.maxnum.f32(float, float)
228 define float @fabs_select_positive_constants(i32 %c) {
229 ; CHECK-LABEL: @fabs_select_positive_constants(
230 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
231 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
232 ; CHECK-NEXT:    ret float [[SELECT]]
234   %cmp = icmp eq i32 %c, 0
235   %select = select i1 %cmp, float 1.0, float 2.0
236   %fabs = call float @llvm.fabs.f32(float %select)
237   ret float %fabs
240 define <2 x float> @fabs_select_positive_constants_vector(i32 %c) {
241 ; CHECK-LABEL: @fabs_select_positive_constants_vector(
242 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
243 ; 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>
244 ; CHECK-NEXT:    ret <2 x float> [[SELECT]]
246   %cmp = icmp eq i32 %c, 0
247   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
248   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
249   ret <2 x float> %fabs
252 define float @fabs_select_constant_variable(i32 %c, float %x) {
253 ; CHECK-LABEL: @fabs_select_constant_variable(
254 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
255 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float [[X:%.*]]
256 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
257 ; CHECK-NEXT:    ret float [[FABS]]
259   %cmp = icmp eq i32 %c, 0
260   %select = select i1 %cmp, float 1.0, float %x
261   %fabs = call float @llvm.fabs.f32(float %select)
262   ret float %fabs
265 define <2 x float> @fabs_select_constant_variable_vector(i32 %c, <2 x float> %x) {
266 ; CHECK-LABEL: @fabs_select_constant_variable_vector(
267 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
268 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]]
269 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
270 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
272   %cmp = icmp eq i32 %c, 0
273   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> %x
274   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
275   ret <2 x float> %fabs
278 define float @fabs_select_neg0_pos0(i32 %c) {
279 ; CHECK-LABEL: @fabs_select_neg0_pos0(
280 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
281 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float 0.000000e+00
282 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
283 ; CHECK-NEXT:    ret float [[FABS]]
285   %cmp = icmp eq i32 %c, 0
286   %select = select i1 %cmp, float -0.0, float 0.0
287   %fabs = call float @llvm.fabs.f32(float %select)
288   ret float %fabs
291 define <2 x float> @fabs_select_neg0_pos0_vector(i32 %c) {
292 ; CHECK-LABEL: @fabs_select_neg0_pos0_vector(
293 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
294 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> zeroinitializer
295 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
296 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
298   %cmp = icmp eq i32 %c, 0
299   %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float 0.0, float 0.0>
300   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
301   ret <2 x float> %fabs
304 define float @fabs_select_neg0_neg1(i32 %c) {
305 ; CHECK-LABEL: @fabs_select_neg0_neg1(
306 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
307 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float -1.000000e+00
308 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
309 ; CHECK-NEXT:    ret float [[FABS]]
311   %cmp = icmp eq i32 %c, 0
312   %select = select i1 %cmp, float -0.0, float -1.0
313   %fabs = call float @llvm.fabs.f32(float %select)
314   ret float %fabs
317 define <2 x float> @fabs_select_neg0_neg1_vector(i32 %c) {
318 ; CHECK-LABEL: @fabs_select_neg0_neg1_vector(
319 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
320 ; 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>
321 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
322 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
324   %cmp = icmp eq i32 %c, 0
325   %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float -1.0, float -1.0>
326   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
327   ret <2 x float> %fabs
330 define float @fabs_select_nan_nan(i32 %c) {
331 ; CHECK-LABEL: @fabs_select_nan_nan(
332 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
333 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0x7FF8000000000000, float 0x7FF8000100000000
334 ; CHECK-NEXT:    ret float [[SELECT]]
336   %cmp = icmp eq i32 %c, 0
337   %select = select i1 %cmp, float 0x7FF8000000000000, float 0x7FF8000100000000
338   %fabs = call float @llvm.fabs.f32(float %select)
339   ret float %fabs
342 define <2 x float> @fabs_select_nan_nan_vector(i32 %c) {
343 ; CHECK-LABEL: @fabs_select_nan_nan_vector(
344 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
345 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
346 ; CHECK-NEXT:    ret <2 x float> [[SELECT]]
348   %cmp = icmp eq i32 %c, 0
349   %select = select i1 %cmp, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
350   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
351   ret <2 x float> %fabs
354 define float @fabs_select_negnan_nan(i32 %c) {
355 ; CHECK-LABEL: @fabs_select_negnan_nan(
356 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
357 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000000000000
358 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
359 ; CHECK-NEXT:    ret float [[FABS]]
361   %cmp = icmp eq i32 %c, 0
362   %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000000000000
363   %fabs = call float @llvm.fabs.f32(float %select)
364   ret float %fabs
367 define <2 x float> @fabs_select_negnan_nan_vector(i32 %c) {
368 ; CHECK-LABEL: @fabs_select_negnan_nan_vector(
369 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
370 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
371 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
372 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
374   %cmp = icmp eq i32 %c, 0
375   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
376   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
377   ret <2 x float> %fabs
380 define float @fabs_select_negnan_negnan(i32 %c) {
381 ; CHECK-LABEL: @fabs_select_negnan_negnan(
382 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
383 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000100000000
384 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
385 ; CHECK-NEXT:    ret float [[FABS]]
387   %cmp = icmp eq i32 %c, 0
388   %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000100000000
389   %fabs = call float @llvm.fabs.f32(float %select)
390   ret float %fabs
393 define <2 x float> @fabs_select_negnan_negnan_vector(i32 %c) {
394 ; CHECK-LABEL: @fabs_select_negnan_negnan_vector(
395 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
396 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
397 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
398 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
400   %cmp = icmp eq i32 %c, 0
401   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
402   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
403   ret <2 x float> %fabs
406 define float @fabs_select_negnan_negzero(i32 %c) {
407 ; CHECK-LABEL: @fabs_select_negnan_negzero(
408 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
409 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float -0.000000e+00
410 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
411 ; CHECK-NEXT:    ret float [[FABS]]
413   %cmp = icmp eq i32 %c, 0
414   %select = select i1 %cmp, float 0xFFF8000000000000, float -0.0
415   %fabs = call float @llvm.fabs.f32(float %select)
416   ret float %fabs
419 define <2 x float> @fabs_select_negnan_negzero_vector(i32 %c) {
420 ; CHECK-LABEL: @fabs_select_negnan_negzero_vector(
421 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
422 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.000000e+00, float -0.000000e+00>
423 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
424 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
426   %cmp = icmp eq i32 %c, 0
427   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.0, float -0.0>
428   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
429   ret <2 x float> %fabs
432 define float @fabs_select_negnan_zero(i32 %c) {
433 ; CHECK-LABEL: @fabs_select_negnan_zero(
434 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
435 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0.000000e+00
436 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
437 ; CHECK-NEXT:    ret float [[FABS]]
439   %cmp = icmp eq i32 %c, 0
440   %select = select i1 %cmp, float 0xFFF8000000000000, float 0.0
441   %fabs = call float @llvm.fabs.f32(float %select)
442   ret float %fabs
445 define <2 x float> @fabs_select_negnan_zero_vector(i32 %c) {
446 ; CHECK-LABEL: @fabs_select_negnan_zero_vector(
447 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
448 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> zeroinitializer
449 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
450 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
452   %cmp = icmp eq i32 %c, 0
453   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0.0, float 0.0>
454   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
455   ret <2 x float> %fabs
458 ; The fabs can't be eliminated because llvm.sqrt.f32 may return -0 or NaN with
459 ; an arbitrary sign bit.
460 define float @fabs_sqrt(float %a) {
461 ; CHECK-LABEL: @fabs_sqrt(
462 ; CHECK-NEXT:    [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
463 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
464 ; CHECK-NEXT:    ret float [[FABS]]
466   %sqrt = call float @llvm.sqrt.f32(float %a)
467   %fabs = call float @llvm.fabs.f32(float %sqrt)
468   ret float %fabs
471 ; The fabs can't be eliminated because the nnan sqrt may still return -0.
472 define float @fabs_sqrt_nnan(float %a) {
473 ; CHECK-LABEL: @fabs_sqrt_nnan(
474 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
475 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
476 ; CHECK-NEXT:    ret float [[FABS]]
478   %sqrt = call nnan float @llvm.sqrt.f32(float %a)
479   %fabs = call float @llvm.fabs.f32(float %sqrt)
480   ret float %fabs
483 ; The fabs can't be eliminated because the nsz sqrt may still return NaN.
484 define float @fabs_sqrt_nsz(float %a) {
485 ; CHECK-LABEL: @fabs_sqrt_nsz(
486 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz float @llvm.sqrt.f32(float [[A:%.*]])
487 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
488 ; CHECK-NEXT:    ret float [[FABS]]
490   %sqrt = call nsz float @llvm.sqrt.f32(float %a)
491   %fabs = call float @llvm.fabs.f32(float %sqrt)
492   ret float %fabs
495 ; The fabs can be eliminated because we're nsz and nnan.
496 define float @fabs_sqrt_nnan_nsz(float %a) {
497 ; CHECK-LABEL: @fabs_sqrt_nnan_nsz(
498 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan nsz float @llvm.sqrt.f32(float [[A:%.*]])
499 ; CHECK-NEXT:    ret float [[SQRT]]
501   %sqrt = call nnan nsz float @llvm.sqrt.f32(float %a)
502   %fabs = call float @llvm.fabs.f32(float %sqrt)
503   ret float %fabs
506 ; The second fabs can be eliminated because the operand to sqrt cannot be -0.
507 define float @fabs_sqrt_nnan_fabs(float %a) {
508 ; CHECK-LABEL: @fabs_sqrt_nnan_fabs(
509 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
510 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[B]])
511 ; CHECK-NEXT:    ret float [[SQRT]]
513   %b = call float @llvm.fabs.f32(float %a)
514   %sqrt = call nnan float @llvm.sqrt.f32(float %b)
515   %fabs = call float @llvm.fabs.f32(float %sqrt)
516   ret float %fabs
519 define float @fabs_select_positive_constants_vector_extract(i32 %c) {
520 ; CHECK-LABEL: @fabs_select_positive_constants_vector_extract(
521 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
522 ; 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>
523 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <2 x float> [[SELECT]], i32 0
524 ; CHECK-NEXT:    ret float [[EXTRACT]]
526   %cmp = icmp eq i32 %c, 0
527   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
528   %extract = extractelement <2 x float> %select, i32 0
529   %fabs = call float @llvm.fabs.f32(float %extract)
530   ret float %fabs
533 ; Y - (Y - X) --> X
535 define float @fsub_fsub_common_op(float %x, float %y) {
536 ; CHECK-LABEL: @fsub_fsub_common_op(
537 ; CHECK-NEXT:    ret float [[X:%.*]]
539   %s = fsub float %y, %x
540   %r = fsub reassoc nsz float %y, %s
541   ret float %r
544 define <2 x float> @fsub_fsub_common_op_vec(<2 x float> %x, <2 x float> %y) {
545 ; CHECK-LABEL: @fsub_fsub_common_op_vec(
546 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
548   %s = fsub <2 x float> %y, %x
549   %r = fsub reassoc nsz <2 x float> %y, %s
550   ret <2 x float> %r
553 ; Negative test - fsub is not commutative.
554 ; Y - (X - Y) --> (Y - X) + Y (canonicalized)
556 define float @fsub_fsub_wrong_common_op(float %x, float %y) {
557 ; CHECK-LABEL: @fsub_fsub_wrong_common_op(
558 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
559 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[Y]], [[S]]
560 ; CHECK-NEXT:    ret float [[R]]
562   %s = fsub float %x, %y
563   %r = fsub reassoc nsz float %y, %s
564   ret float %r
567 ; Negative test - negated operand needed.
568 ; (Y - X) - Y --> -X
570 define float @fsub_fsub_common_op_wrong_commute(float %x, float %y) {
571 ; CHECK-LABEL: @fsub_fsub_common_op_wrong_commute(
572 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
573 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
574 ; CHECK-NEXT:    ret float [[R]]
576   %s = fsub float %y, %x
577   %r = fsub reassoc nsz float %s, %y
578   ret float %r
581 ; Negative test - fsub is not commutative.
582 ; (X - Y) - Y --> ?
584 define float @fsub_fsub_wrong_common_op_wrong_commute(float %x, float %y) {
585 ; CHECK-LABEL: @fsub_fsub_wrong_common_op_wrong_commute(
586 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
587 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
588 ; CHECK-NEXT:    ret float [[R]]
590   %s = fsub float %x, %y
591   %r = fsub reassoc nsz float %s, %y
592   ret float %r
595 ; (Y + X) - Y --> X
597 define float @fadd_fsub_common_op(float %x, float %y) {
598 ; CHECK-LABEL: @fadd_fsub_common_op(
599 ; CHECK-NEXT:    ret float [[X:%.*]]
601   %a = fadd float %y, %x
602   %r = fsub reassoc nsz float %a, %y
603   ret float %r
606 ; (X + Y) - Y --> X
608 define <2 x float> @fadd_fsub_common_op_commute_vec(<2 x float> %x, <2 x float> %y) {
609 ; CHECK-LABEL: @fadd_fsub_common_op_commute_vec(
610 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
612   %a = fadd <2 x float> %x, %y
613   %r = fsub reassoc nsz <2 x float> %a, %y
614   ret <2 x float> %r
617 ; Negative test - negated operand needed.
618 ; Y - (Y + X) --> -X
620 define float @fadd_fsub_common_op_wrong_commute(float %x, float %y) {
621 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute(
622 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[Y:%.*]], [[X:%.*]]
623 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
624 ; CHECK-NEXT:    ret float [[R]]
626   %a = fadd float %y, %x
627   %r = fsub reassoc nsz float %y, %a
628   ret float %r
631 ; Negative test - negated operand needed.
632 ; Y - (X + Y) --> -X
634 define float @fadd_fsub_common_op_wrong_commute_commute(float %x, float %y) {
635 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute_commute(
636 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], [[Y:%.*]]
637 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
638 ; CHECK-NEXT:    ret float [[R]]
640   %a = fadd float %x, %y
641   %r = fsub reassoc nsz float %y, %a
642   ret float %r
645 ; Y + (X - Y) --> X
647 define <2 x float> @fsub_fadd_common_op_vec(<2 x float> %x, <2 x float> %y) {
648 ; CHECK-LABEL: @fsub_fadd_common_op_vec(
649 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
651   %s = fsub <2 x float> %x, %y
652   %r = fadd reassoc nsz <2 x float> %y, %s
653   ret <2 x float> %r
656 ; (X - Y) + Y --> X
658 define float @fsub_fadd_common_op_commute(float %x, float %y) {
659 ; CHECK-LABEL: @fsub_fadd_common_op_commute(
660 ; CHECK-NEXT:    ret float [[X:%.*]]
662   %s = fsub float %x, %y
663   %r = fadd reassoc nsz float %s, %y
664   ret float %r
667 ; Negative test.
668 ; Y + (Y - X) --> ?
670 define float @fsub_fadd_common_op_wrong_commute(float %x, float %y) {
671 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute(
672 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
673 ; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz float [[Y]], [[S]]
674 ; CHECK-NEXT:    ret float [[R]]
676   %s = fsub float %y, %x
677   %r = fadd reassoc nsz float %y, %s
678   ret float %r
681 ; Negative test.
682 ; (Y - X) + Y --> ?
684 define float @fsub_fadd_common_op_wrong_commute_commute(float %x, float %y) {
685 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute_commute(
686 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
687 ; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz float [[S]], [[Y]]
688 ; CHECK-NEXT:    ret float [[R]]
690   %s = fsub float %y, %x
691   %r = fadd reassoc nsz float %s, %y
692   ret float %r
695 ; PR46627 - https://bugs.llvm.org/show_bug.cgi?id=46627
697 define float @maxnum_with_poszero_op(float %a) {
698 ; CHECK-LABEL: @maxnum_with_poszero_op(
699 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[A:%.*]], float 0.000000e+00)
700 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
701 ; CHECK-NEXT:    ret float [[FABS]]
703   %max = call float @llvm.maxnum.f32(float %a, float 0.0)
704   %fabs = call float @llvm.fabs.f32(float %max)
705   ret float %fabs
708 define float @maxnum_with_poszero_op_commute(float %a) {
709 ; CHECK-LABEL: @maxnum_with_poszero_op_commute(
710 ; CHECK-NEXT:    [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
711 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float 0.000000e+00, float [[SQRT]])
712 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
713 ; CHECK-NEXT:    ret float [[FABS]]
715   %sqrt = call float @llvm.sqrt.f32(float %a)
716   %max = call float @llvm.maxnum.f32(float 0.0, float %sqrt)
717   %fabs = call float @llvm.fabs.f32(float %max)
718   ret float %fabs
721 define float @maxnum_with_negzero_op(float %a) {
722 ; CHECK-LABEL: @maxnum_with_negzero_op(
723 ; CHECK-NEXT:    [[NNAN:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
724 ; CHECK-NEXT:    [[FABSA:%.*]] = call float @llvm.fabs.f32(float [[NNAN]])
725 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float -0.000000e+00, float [[FABSA]])
726 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
727 ; CHECK-NEXT:    ret float [[FABS]]
729   %nnan = call nnan float @llvm.sqrt.f32(float %a)
730   %fabsa = call float @llvm.fabs.f32(float %nnan)
731   %max = call float @llvm.maxnum.f32(float -0.0, float %fabsa)
732   %fabs = call float @llvm.fabs.f32(float %max)
733   ret float %fabs
736 define float @maxnum_with_negzero_op_commute(float %a) {
737 ; CHECK-LABEL: @maxnum_with_negzero_op_commute(
738 ; CHECK-NEXT:    [[NNAN:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
739 ; CHECK-NEXT:    [[FABSA:%.*]] = call float @llvm.fabs.f32(float [[NNAN]])
740 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[FABSA]], float -0.000000e+00)
741 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
742 ; CHECK-NEXT:    ret float [[FABS]]
744   %nnan = call nnan float @llvm.sqrt.f32(float %a)
745   %fabsa = call float @llvm.fabs.f32(float %nnan)
746   %max = call float @llvm.maxnum.f32(float %fabsa, float -0.0)
747   %fabs = call float @llvm.fabs.f32(float %max)
748   ret float %fabs
751 ; If an operand is strictly greater than 0.0, we know the sign of the result of maxnum.
753 define float @maxnum_with_pos_one_op(float %a) {
754 ; CHECK-LABEL: @maxnum_with_pos_one_op(
755 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[A:%.*]], float 1.000000e+00)
756 ; CHECK-NEXT:    ret float [[MAX]]
758   %max = call float @llvm.maxnum.f32(float %a, float 1.0)
759   %fabs = call float @llvm.fabs.f32(float %max)
760   ret float %fabs