[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / fabs.ll
bloba26cc046673d857cdaf6e67049e99d08ed1a0e17
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -instcombine -S | FileCheck %s
4 ; Make sure libcalls are replaced with intrinsic calls.
6 declare float @llvm.fabs.f32(float)
7 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
8 declare double @llvm.fabs.f64(double)
9 declare fp128 @llvm.fabs.f128(fp128)
11 declare float @fabsf(float)
12 declare double @fabs(double)
13 declare fp128 @fabsl(fp128)
14 declare float @llvm.fma.f32(float, float, float)
15 declare float @llvm.fmuladd.f32(float, float, float)
17 declare void @use(float)
19 define float @replace_fabs_call_f32(float %x) {
20 ; CHECK-LABEL: @replace_fabs_call_f32(
21 ; CHECK-NEXT:    [[FABSF:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
22 ; CHECK-NEXT:    ret float [[FABSF]]
24   %fabsf = tail call float @fabsf(float %x)
25   ret float %fabsf
28 define double @replace_fabs_call_f64(double %x) {
29 ; CHECK-LABEL: @replace_fabs_call_f64(
30 ; CHECK-NEXT:    [[FABS:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
31 ; CHECK-NEXT:    ret double [[FABS]]
33   %fabs = tail call double @fabs(double %x)
34   ret double %fabs
37 define fp128 @replace_fabs_call_f128(fp128 %x) {
38 ; CHECK-LABEL: @replace_fabs_call_f128(
39 ; CHECK-NEXT:    [[FABSL:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
40 ; CHECK-NEXT:    ret fp128 [[FABSL]]
42   %fabsl = tail call fp128 @fabsl(fp128 %x)
43   ret fp128 %fabsl
46 ; Make sure fast math flags are preserved when replacing the libcall.
47 define float @fmf_replace_fabs_call_f32(float %x) {
48 ; CHECK-LABEL: @fmf_replace_fabs_call_f32(
49 ; CHECK-NEXT:    [[FABSF:%.*]] = call nnan float @llvm.fabs.f32(float [[X:%.*]])
50 ; CHECK-NEXT:    ret float [[FABSF]]
52   %fabsf = tail call nnan float @fabsf(float %x)
53   ret float %fabsf
56 ; Make sure all intrinsic calls are eliminated when the input is known
57 ; positive.
59 ; The fabs cannot be eliminated because %x may be a NaN
61 define float @square_fabs_intrinsic_f32(float %x) {
62 ; CHECK-LABEL: @square_fabs_intrinsic_f32(
63 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], [[X]]
64 ; CHECK-NEXT:    [[FABSF:%.*]] = tail call float @llvm.fabs.f32(float [[MUL]])
65 ; CHECK-NEXT:    ret float [[FABSF]]
67   %mul = fmul float %x, %x
68   %fabsf = tail call float @llvm.fabs.f32(float %mul)
69   ret float %fabsf
72 define double @square_fabs_intrinsic_f64(double %x) {
73 ; CHECK-LABEL: @square_fabs_intrinsic_f64(
74 ; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[X:%.*]], [[X]]
75 ; CHECK-NEXT:    [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[MUL]])
76 ; CHECK-NEXT:    ret double [[FABS]]
78   %mul = fmul double %x, %x
79   %fabs = tail call double @llvm.fabs.f64(double %mul)
80   ret double %fabs
83 define fp128 @square_fabs_intrinsic_f128(fp128 %x) {
84 ; CHECK-LABEL: @square_fabs_intrinsic_f128(
85 ; CHECK-NEXT:    [[MUL:%.*]] = fmul fp128 [[X:%.*]], [[X]]
86 ; CHECK-NEXT:    [[FABSL:%.*]] = tail call fp128 @llvm.fabs.f128(fp128 [[MUL]])
87 ; CHECK-NEXT:    ret fp128 [[FABSL]]
89   %mul = fmul fp128 %x, %x
90   %fabsl = tail call fp128 @llvm.fabs.f128(fp128 %mul)
91   ret fp128 %fabsl
94 define float @square_nnan_fabs_intrinsic_f32(float %x) {
95 ; CHECK-LABEL: @square_nnan_fabs_intrinsic_f32(
96 ; CHECK-NEXT:    [[MUL:%.*]] = fmul nnan float [[X:%.*]], [[X]]
97 ; CHECK-NEXT:    ret float [[MUL]]
99   %mul = fmul nnan float %x, %x
100   %fabsf = call float @llvm.fabs.f32(float %mul)
101   ret float %fabsf
104 ; Shrinking a library call to a smaller type should not be inhibited by nor inhibit the square optimization.
106 define float @square_fabs_shrink_call1(float %x) {
107 ; CHECK-LABEL: @square_fabs_shrink_call1(
108 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[X:%.*]], [[X]]
109 ; CHECK-NEXT:    [[TRUNC:%.*]] = call float @llvm.fabs.f32(float [[TMP1]])
110 ; CHECK-NEXT:    ret float [[TRUNC]]
112   %ext = fpext float %x to double
113   %sq = fmul double %ext, %ext
114   %fabs = call double @fabs(double %sq)
115   %trunc = fptrunc double %fabs to float
116   ret float %trunc
119 define float @square_fabs_shrink_call2(float %x) {
120 ; CHECK-LABEL: @square_fabs_shrink_call2(
121 ; CHECK-NEXT:    [[SQ:%.*]] = fmul float [[X:%.*]], [[X]]
122 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[SQ]])
123 ; CHECK-NEXT:    ret float [[TMP1]]
125   %sq = fmul float %x, %x
126   %ext = fpext float %sq to double
127   %fabs = call double @fabs(double %ext)
128   %trunc = fptrunc double %fabs to float
129   ret float %trunc
132 define float @fabs_select_constant_negative_positive(i32 %c) {
133 ; CHECK-LABEL: @fabs_select_constant_negative_positive(
134 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
135 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
136 ; CHECK-NEXT:    ret float [[FABS]]
138   %cmp = icmp eq i32 %c, 0
139   %select = select i1 %cmp, float -1.0, float 2.0
140   %fabs = call float @llvm.fabs.f32(float %select)
141   ret float %fabs
144 define float @fabs_select_constant_positive_negative(i32 %c) {
145 ; CHECK-LABEL: @fabs_select_constant_positive_negative(
146 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
147 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
148 ; CHECK-NEXT:    ret float [[FABS]]
150   %cmp = icmp eq i32 %c, 0
151   %select = select i1 %cmp, float 1.0, float -2.0
152   %fabs = call float @llvm.fabs.f32(float %select)
153   ret float %fabs
156 define float @fabs_select_constant_negative_negative(i32 %c) {
157 ; CHECK-LABEL: @fabs_select_constant_negative_negative(
158 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
159 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
160 ; CHECK-NEXT:    ret float [[FABS]]
162   %cmp = icmp eq i32 %c, 0
163   %select = select i1 %cmp, float -1.0, float -2.0
164   %fabs = call float @llvm.fabs.f32(float %select)
165   ret float %fabs
168 define float @fabs_select_constant_neg0(i32 %c) {
169 ; CHECK-LABEL: @fabs_select_constant_neg0(
170 ; CHECK-NEXT:    ret float 0.000000e+00
172   %cmp = icmp eq i32 %c, 0
173   %select = select i1 %cmp, float -0.0, float 0.0
174   %fabs = call float @llvm.fabs.f32(float %select)
175   ret float %fabs
178 define float @fabs_select_var_constant_negative(i32 %c, float %x) {
179 ; CHECK-LABEL: @fabs_select_var_constant_negative(
180 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
181 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float [[X:%.*]], float -1.000000e+00
182 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
183 ; CHECK-NEXT:    ret float [[FABS]]
185   %cmp = icmp eq i32 %c, 0
186   %select = select i1 %cmp, float %x, float -1.0
187   %fabs = call float @llvm.fabs.f32(float %select)
188   ret float %fabs
191 ; The fabs cannot be eliminated because %x may be a NaN
193 define float @square_fma_fabs_intrinsic_f32(float %x) {
194 ; CHECK-LABEL: @square_fma_fabs_intrinsic_f32(
195 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[X]], float 1.000000e+00)
196 ; CHECK-NEXT:    [[FABSF:%.*]] = call float @llvm.fabs.f32(float [[FMA]])
197 ; CHECK-NEXT:    ret float [[FABSF]]
199   %fma = call float @llvm.fma.f32(float %x, float %x, float 1.0)
200   %fabsf = call float @llvm.fabs.f32(float %fma)
201   ret float %fabsf
204 ; The fabs cannot be eliminated because %x may be a NaN
206 define float @square_nnan_fma_fabs_intrinsic_f32(float %x) {
207 ; CHECK-LABEL: @square_nnan_fma_fabs_intrinsic_f32(
208 ; CHECK-NEXT:    [[FMA:%.*]] = call nnan float @llvm.fma.f32(float [[X:%.*]], float [[X]], float 1.000000e+00)
209 ; CHECK-NEXT:    ret float [[FMA]]
211   %fma = call nnan float @llvm.fma.f32(float %x, float %x, float 1.0)
212   %fabsf = call float @llvm.fabs.f32(float %fma)
213   ret float %fabsf
216 define float @square_fmuladd_fabs_intrinsic_f32(float %x) {
217 ; CHECK-LABEL: @square_fmuladd_fabs_intrinsic_f32(
218 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float 1.000000e+00)
219 ; CHECK-NEXT:    [[FABSF:%.*]] = call float @llvm.fabs.f32(float [[FMULADD]])
220 ; CHECK-NEXT:    ret float [[FABSF]]
222   %fmuladd = call float @llvm.fmuladd.f32(float %x, float %x, float 1.0)
223   %fabsf = call float @llvm.fabs.f32(float %fmuladd)
224   ret float %fabsf
227 define float @square_nnan_fmuladd_fabs_intrinsic_f32(float %x) {
228 ; CHECK-LABEL: @square_nnan_fmuladd_fabs_intrinsic_f32(
229 ; CHECK-NEXT:    [[FMULADD:%.*]] = call nnan float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float 1.000000e+00)
230 ; CHECK-NEXT:    ret float [[FMULADD]]
232   %fmuladd = call nnan float @llvm.fmuladd.f32(float %x, float %x, float 1.0)
233   %fabsf = call float @llvm.fabs.f32(float %fmuladd)
234   ret float %fabsf
237 ; Don't introduce a second fpext
239 define double @multi_use_fabs_fpext(float %x) {
240 ; CHECK-LABEL: @multi_use_fabs_fpext(
241 ; CHECK-NEXT:    [[FPEXT:%.*]] = fpext float [[X:%.*]] to double
242 ; CHECK-NEXT:    [[FABS:%.*]] = call double @llvm.fabs.f64(double [[FPEXT]])
243 ; CHECK-NEXT:    store volatile double [[FPEXT]], double* undef, align 8
244 ; CHECK-NEXT:    ret double [[FABS]]
246   %fpext = fpext float %x to double
247   %fabs = call double @llvm.fabs.f64(double %fpext)
248   store volatile double %fpext, double* undef
249   ret double %fabs
252 ; X <= 0.0 ? (0.0 - X) : X --> fabs(X)
254 define double @select_fcmp_ole_zero(double %x) {
255 ; CHECK-LABEL: @select_fcmp_ole_zero(
256 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
257 ; CHECK-NEXT:    ret double [[TMP1]]
259   %lezero = fcmp ole double %x, 0.0
260   %negx = fsub double 0.0, %x
261   %fabs = select i1 %lezero, double %negx, double %x
262   ret double %fabs
265 define double @select_fcmp_nnan_ole_zero(double %x) {
266 ; CHECK-LABEL: @select_fcmp_nnan_ole_zero(
267 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
268 ; CHECK-NEXT:    ret double [[TMP1]]
270   %lezero = fcmp ole double %x, 0.0
271   %negx = fsub nnan double 0.0, %x
272   %fabs = select i1 %lezero, double %negx, double %x
273   ret double %fabs
276 define double @select_nnan_fcmp_nnan_ole_zero(double %x) {
277 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ole_zero(
278 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan double @llvm.fabs.f64(double [[X:%.*]])
279 ; CHECK-NEXT:    ret double [[TMP1]]
281   %lezero = fcmp ole double %x, 0.0
282   %negx = fsub nnan double 0.0, %x
283   %fabs = select nnan i1 %lezero, double %negx, double %x
284   ret double %fabs
287 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
289 define double @select_fcmp_nnan_ule_zero(double %x) {
290 ; CHECK-LABEL: @select_fcmp_nnan_ule_zero(
291 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
292 ; CHECK-NEXT:    ret double [[TMP1]]
294   %lezero = fcmp ule double %x, 0.0
295   %negx = fsub nnan double 0.0, %x
296   %fabs = select i1 %lezero, double %negx, double %x
297   ret double %fabs
300 ; Negative test - wrong predicate.
302 define double @select_fcmp_nnan_olt_zero(double %x) {
303 ; CHECK-LABEL: @select_fcmp_nnan_olt_zero(
304 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
305 ; CHECK-NEXT:    [[NEGX:%.*]] = fsub nnan double 0.000000e+00, [[X]]
306 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
307 ; CHECK-NEXT:    ret double [[FABS]]
309   %lezero = fcmp olt double %x, 0.0
310   %negx = fsub nnan double 0.0, %x
311   %fabs = select i1 %lezero, double %negx, double %x
312   ret double %fabs
315 ; X <= -0.0 ? (0.0 - X) : X --> fabs(X)
317 define <2 x float> @select_fcmp_nnan_ole_negzero(<2 x float> %x) {
318 ; CHECK-LABEL: @select_fcmp_nnan_ole_negzero(
319 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
320 ; CHECK-NEXT:    ret <2 x float> [[TMP1]]
322   %lezero = fcmp ole <2 x float> %x, <float -0.0, float -0.0>
323   %negx = fsub nnan <2 x float> <float 0.0, float undef>, %x
324   %fabs = select <2 x i1> %lezero, <2 x float> %negx, <2 x float> %x
325   ret <2 x float> %fabs
328 define <2 x float> @select_nnan_fcmp_nnan_ole_negzero(<2 x float> %x) {
329 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ole_negzero(
330 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
331 ; CHECK-NEXT:    ret <2 x float> [[TMP1]]
333   %lezero = fcmp ole <2 x float> %x, <float -0.0, float -0.0>
334   %negx = fsub nnan <2 x float> <float 0.0, float undef>, %x
335   %fabs = select nnan <2 x i1> %lezero, <2 x float> %negx, <2 x float> %x
336   ret <2 x float> %fabs
339 ; X > 0.0 ? X : (0.0 - X) --> fabs(X)
341 define fp128 @select_fcmp_ogt_zero(fp128 %x) {
342 ; CHECK-LABEL: @select_fcmp_ogt_zero(
343 ; CHECK-NEXT:    [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
344 ; CHECK-NEXT:    ret fp128 [[TMP1]]
346   %gtzero = fcmp ogt fp128 %x, zeroinitializer
347   %negx = fsub fp128 zeroinitializer, %x
348   %fabs = select i1 %gtzero, fp128 %x, fp128 %negx
349   ret fp128 %fabs
352 define fp128 @select_fcmp_nnan_ogt_zero(fp128 %x) {
353 ; CHECK-LABEL: @select_fcmp_nnan_ogt_zero(
354 ; CHECK-NEXT:    [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
355 ; CHECK-NEXT:    ret fp128 [[TMP1]]
357   %gtzero = fcmp ogt fp128 %x, zeroinitializer
358   %negx = fsub nnan fp128 zeroinitializer, %x
359   %fabs = select i1 %gtzero, fp128 %x, fp128 %negx
360   ret fp128 %fabs
363 define fp128 @select_nnan_fcmp_nnan_ogt_zero(fp128 %x) {
364 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ogt_zero(
365 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
366 ; CHECK-NEXT:    ret fp128 [[TMP1]]
368   %gtzero = fcmp ogt fp128 %x, zeroinitializer
369   %negx = fsub nnan fp128 zeroinitializer, %x
370   %fabs = select nnan i1 %gtzero, fp128 %x, fp128 %negx
371   ret fp128 %fabs
374 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
376 define half @select_fcmp_nnan_ogt_negzero(half %x) {
377 ; CHECK-LABEL: @select_fcmp_nnan_ogt_negzero(
378 ; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
379 ; CHECK-NEXT:    ret half [[TMP1]]
381   %gtzero = fcmp ogt half %x, -0.0
382   %negx = fsub nnan half 0.0, %x
383   %fabs = select i1 %gtzero, half %x, half %negx
384   ret half %fabs
387 define half @select_nnan_fcmp_nnan_ogt_negzero(half %x) {
388 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ogt_negzero(
389 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan half @llvm.fabs.f16(half [[X:%.*]])
390 ; CHECK-NEXT:    ret half [[TMP1]]
392   %gtzero = fcmp ogt half %x, -0.0
393   %negx = fsub nnan half 0.0, %x
394   %fabs = select nnan i1 %gtzero, half %x, half %negx
395   ret half %fabs
398 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
400 define half @select_fcmp_nnan_ugt_negzero(half %x) {
401 ; CHECK-LABEL: @select_fcmp_nnan_ugt_negzero(
402 ; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
403 ; CHECK-NEXT:    ret half [[TMP1]]
405   %gtzero = fcmp ugt half %x, -0.0
406   %negx = fsub nnan half 0.0, %x
407   %fabs = select i1 %gtzero, half %x, half %negx
408   ret half %fabs
411 ; Negative test - wrong predicate.
413 define half @select_fcmp_nnan_oge_negzero(half %x) {
414 ; CHECK-LABEL: @select_fcmp_nnan_oge_negzero(
415 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
416 ; CHECK-NEXT:    [[NEGX:%.*]] = fsub nnan half 0xH0000, [[X]]
417 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GTZERO]], half [[X]], half [[NEGX]]
418 ; CHECK-NEXT:    ret half [[FABS]]
420   %gtzero = fcmp oge half %x, -0.0
421   %negx = fsub nnan half 0.0, %x
422   %fabs = select i1 %gtzero, half %x, half %negx
423   ret half %fabs
426 ; X < 0.0 ? -X : X --> fabs(X)
428 define double @select_fcmp_olt_zero_unary_fneg(double %x) {
429 ; CHECK-LABEL: @select_fcmp_olt_zero_unary_fneg(
430 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
431 ; CHECK-NEXT:    ret double [[TMP1]]
433   %ltzero = fcmp olt double %x, 0.0
434   %negx = fneg double %x
435   %fabs = select nsz i1 %ltzero, double %negx, double %x
436   ret double %fabs
439 define double @select_fcmp_nnan_nsz_olt_zero(double %x) {
440 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero(
441 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
442 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz double [[X]]
443 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
444 ; CHECK-NEXT:    ret double [[FABS]]
446   %ltzero = fcmp olt double %x, 0.0
447   %negx = fsub nnan nsz double -0.0, %x
448   %fabs = select i1 %ltzero, double %negx, double %x
449   ret double %fabs
452 define double @select_nnan_nsz_fcmp_nnan_nsz_olt_zero(double %x) {
453 ; CHECK-LABEL: @select_nnan_nsz_fcmp_nnan_nsz_olt_zero(
454 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
455 ; CHECK-NEXT:    ret double [[TMP1]]
457   %ltzero = fcmp olt double %x, 0.0
458   %negx = fsub nnan nsz double -0.0, %x
459   %fabs = select nnan nsz i1 %ltzero, double %negx, double %x
460   ret double %fabs
463 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
465 define double @select_fcmp_nnan_nsz_ult_zero(double %x) {
466 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_zero(
467 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
468 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz double [[X]]
469 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
470 ; CHECK-NEXT:    ret double [[FABS]]
472   %ltzero = fcmp ult double %x, 0.0
473   %negx = fsub nnan nsz double -0.0, %x
474   %fabs = select i1 %ltzero, double %negx, double %x
475   ret double %fabs
478 define double @select_fcmp_nnan_nsz_olt_zero_unary_fneg(double %x) {
479 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero_unary_fneg(
480 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
481 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz double [[X]]
482 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
483 ; CHECK-NEXT:    ret double [[FABS]]
485   %ltzero = fcmp olt double %x, 0.0
486   %negx = fneg nnan nsz double %x
487   %fabs = select i1 %ltzero, double %negx, double %x
488   ret double %fabs
491 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
493 define double @select_fcmp_nnan_nsz_ult_zero_unary_fneg(double %x) {
494 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_zero_unary_fneg(
495 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
496 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz double [[X]]
497 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
498 ; CHECK-NEXT:    ret double [[FABS]]
500   %ltzero = fcmp ult double %x, 0.0
501   %negx = fneg nnan nsz double %x
502   %fabs = select i1 %ltzero, double %negx, double %x
503   ret double %fabs
506 ; X < -0.0 ? -X : X --> fabs(X)
508 define float @select_fcmp_nnan_nsz_olt_negzero(float %x) {
509 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_negzero(
510 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
511 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
512 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
513 ; CHECK-NEXT:    ret float [[FABS]]
515   %ltzero = fcmp olt float %x, -0.0
516   %negx = fsub nnan ninf nsz float -0.0, %x
517   %fabs = select i1 %ltzero, float %negx, float %x
518   ret float %fabs
521 define float @select_nnan_ninf_nsz_fcmp_nnan_nsz_olt_negzero(float %x) {
522 ; CHECK-LABEL: @select_nnan_ninf_nsz_fcmp_nnan_nsz_olt_negzero(
523 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf nsz float @llvm.fabs.f32(float [[X:%.*]])
524 ; CHECK-NEXT:    ret float [[TMP1]]
526   %ltzero = fcmp olt float %x, -0.0
527   %negx = fsub nnan nsz float -0.0, %x
528   %fabs = select nnan ninf nsz i1 %ltzero, float %negx, float %x
529   ret float %fabs
532 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
534 define float @select_fcmp_nnan_nsz_ult_negzero(float %x) {
535 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_negzero(
536 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
537 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
538 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
539 ; CHECK-NEXT:    ret float [[FABS]]
541   %ltzero = fcmp ult float %x, -0.0
542   %negx = fsub nnan ninf nsz float -0.0, %x
543   %fabs = select i1 %ltzero, float %negx, float %x
544   ret float %fabs
547 define float @select_fcmp_nnan_nsz_olt_negzero_unary_fneg(float %x) {
548 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_negzero_unary_fneg(
549 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
550 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
551 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
552 ; CHECK-NEXT:    ret float [[FABS]]
554   %ltzero = fcmp olt float %x, -0.0
555   %negx = fneg nnan ninf nsz float %x
556   %fabs = select i1 %ltzero, float %negx, float %x
557   ret float %fabs
560 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
562 define float @select_fcmp_nnan_nsz_ult_negzero_unary_fneg(float %x) {
563 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_negzero_unary_fneg(
564 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
565 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
566 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
567 ; CHECK-NEXT:    ret float [[FABS]]
569   %ltzero = fcmp ult float %x, -0.0
570   %negx = fneg nnan ninf nsz float %x
571   %fabs = select i1 %ltzero, float %negx, float %x
572   ret float %fabs
575 ; X <= 0.0 ? -X : X --> fabs(X)
577 define double @select_fcmp_nnan_nsz_ole_zero(double %x) {
578 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_zero(
579 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
580 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast double [[X]]
581 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
582 ; CHECK-NEXT:    ret double [[FABS]]
584   %lezero = fcmp ole double %x, 0.0
585   %negx = fsub fast double -0.0, %x
586   %fabs = select i1 %lezero, double %negx, double %x
587   ret double %fabs
590 define double @select_fast_fcmp_nnan_nsz_ole_zero(double %x) {
591 ; CHECK-LABEL: @select_fast_fcmp_nnan_nsz_ole_zero(
592 ; CHECK-NEXT:    [[TMP1:%.*]] = call fast double @llvm.fabs.f64(double [[X:%.*]])
593 ; CHECK-NEXT:    ret double [[TMP1]]
595   %lezero = fcmp ole double %x, 0.0
596   %negx = fsub nnan nsz double -0.0, %x
597   %fabs = select fast i1 %lezero, double %negx, double %x
598   ret double %fabs
601 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
603 define double @select_fcmp_nnan_nsz_ule_zero(double %x) {
604 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_zero(
605 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
606 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast double [[X]]
607 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
608 ; CHECK-NEXT:    ret double [[FABS]]
610   %lezero = fcmp ule double %x, 0.0
611   %negx = fsub fast double -0.0, %x
612   %fabs = select i1 %lezero, double %negx, double %x
613   ret double %fabs
616 define double @select_fcmp_nnan_nsz_ole_zero_unary_fneg(double %x) {
617 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_zero_unary_fneg(
618 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
619 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast double [[X]]
620 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
621 ; CHECK-NEXT:    ret double [[FABS]]
623   %lezero = fcmp ole double %x, 0.0
624   %negx = fneg fast double %x
625   %fabs = select i1 %lezero, double %negx, double %x
626   ret double %fabs
629 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
631 define double @select_fcmp_nnan_nsz_ule_zero_unary_fneg(double %x) {
632 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_zero_unary_fneg(
633 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
634 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast double [[X]]
635 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
636 ; CHECK-NEXT:    ret double [[FABS]]
638   %lezero = fcmp ule double %x, 0.0
639   %negx = fneg fast double %x
640   %fabs = select i1 %lezero, double %negx, double %x
641   ret double %fabs
644 ; X <= -0.0 ? -X : X --> fabs(X)
646 define float @select_fcmp_nnan_nsz_ole_negzero(float %x) {
647 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_negzero(
648 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
649 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz float [[X]]
650 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
651 ; CHECK-NEXT:    ret float [[FABS]]
653   %lezero = fcmp ole float %x, -0.0
654   %negx = fsub nnan nsz float -0.0, %x
655   %fabs = select i1 %lezero, float %negx, float %x
656   ret float %fabs
659 define float @select_nnan_nsz_fcmp_nnan_nsz_ole_negzero(float %x) {
660 ; CHECK-LABEL: @select_nnan_nsz_fcmp_nnan_nsz_ole_negzero(
661 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[X:%.*]])
662 ; CHECK-NEXT:    ret float [[TMP1]]
664   %lezero = fcmp ole float %x, -0.0
665   %negx = fsub nnan nsz float -0.0, %x
666   %fabs = select nnan nsz i1 %lezero, float %negx, float %x
667   ret float %fabs
670 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
672 define float @select_fcmp_nnan_nsz_ule_negzero(float %x) {
673 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_negzero(
674 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ule float [[X:%.*]], 0.000000e+00
675 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz float [[X]]
676 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
677 ; CHECK-NEXT:    ret float [[FABS]]
679   %lezero = fcmp ule float %x, -0.0
680   %negx = fsub nnan nsz float -0.0, %x
681   %fabs = select i1 %lezero, float %negx, float %x
682   ret float %fabs
685 define float @select_fcmp_nnan_nsz_ole_negzero_unary_fneg(float %x) {
686 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_negzero_unary_fneg(
687 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
688 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz float [[X]]
689 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
690 ; CHECK-NEXT:    ret float [[FABS]]
692   %lezero = fcmp ole float %x, -0.0
693   %negx = fneg nnan nsz float %x
694   %fabs = select i1 %lezero, float %negx, float %x
695   ret float %fabs
698 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
700 define float @select_fcmp_nnan_nsz_ule_negzero_unary_fneg(float %x) {
701 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_negzero_unary_fneg(
702 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ule float [[X:%.*]], 0.000000e+00
703 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz float [[X]]
704 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
705 ; CHECK-NEXT:    ret float [[FABS]]
707   %lezero = fcmp ule float %x, -0.0
708   %negx = fneg nnan nsz float %x
709   %fabs = select i1 %lezero, float %negx, float %x
710   ret float %fabs
713 ; X > 0.0 ? X : (0.0 - X) --> fabs(X)
715 define <2 x float> @select_fcmp_ogt_zero_unary_fneg(<2 x float> %x) {
716 ; CHECK-LABEL: @select_fcmp_ogt_zero_unary_fneg(
717 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
718 ; CHECK-NEXT:    ret <2 x float> [[TMP1]]
720   %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
721   %negx = fneg <2 x float> %x
722   %fabs = select nsz <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
723   ret <2 x float> %fabs
726 define <2 x float> @select_fcmp_nnan_nsz_ogt_zero(<2 x float> %x) {
727 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_zero(
728 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer
729 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
730 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
731 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
733   %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
734   %negx = fsub nnan nsz arcp <2 x float> <float -0.0, float -0.0>, %x
735   %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
736   ret <2 x float> %fabs
739 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
741 define <2 x float> @select_fcmp_nnan_nsz_ugt_zero(<2 x float> %x) {
742 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_zero(
743 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ugt <2 x float> [[X:%.*]], zeroinitializer
744 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
745 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
746 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
748   %gtzero = fcmp ugt <2 x float> %x, zeroinitializer
749   %negx = fsub nnan nsz arcp <2 x float> <float -0.0, float -0.0>, %x
750   %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
751   ret <2 x float> %fabs
754 define <2 x float> @select_fcmp_nnan_nsz_ogt_zero_unary_fneg(<2 x float> %x) {
755 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_zero_unary_fneg(
756 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer
757 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
758 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
759 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
761   %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
762   %negx = fneg nnan nsz arcp <2 x float> %x
763   %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
764   ret <2 x float> %fabs
767 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
769 define <2 x float> @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(<2 x float> %x) {
770 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(
771 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ugt <2 x float> [[X:%.*]], zeroinitializer
772 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
773 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
774 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
776   %gtzero = fcmp ugt <2 x float> %x, zeroinitializer
777   %negx = fneg nnan nsz arcp <2 x float> %x
778   %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
779   ret <2 x float> %fabs
782 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
784 define half @select_fcmp_nnan_nsz_ogt_negzero(half %x) {
785 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_negzero(
786 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000
787 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast half [[X]]
788 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GTZERO]], half [[X]], half [[NEGX]]
789 ; CHECK-NEXT:    ret half [[FABS]]
791   %gtzero = fcmp ogt half %x, -0.0
792   %negx = fsub fast half 0.0, %x
793   %fabs = select i1 %gtzero, half %x, half %negx
794   ret half %fabs
797 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
799 define half @select_fcmp_nnan_nsz_ugt_negzero(half %x) {
800 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_negzero(
801 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ugt half [[X:%.*]], 0xH0000
802 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast half [[X]]
803 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GTZERO]], half [[X]], half [[NEGX]]
804 ; CHECK-NEXT:    ret half [[FABS]]
806   %gtzero = fcmp ugt half %x, -0.0
807   %negx = fsub fast half 0.0, %x
808   %fabs = select i1 %gtzero, half %x, half %negx
809   ret half %fabs
812 ; X > 0.0 ? X : (0.0 - X) --> fabs(X)
814 define <2 x double> @select_fcmp_nnan_nsz_oge_zero(<2 x double> %x) {
815 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_zero(
816 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp oge <2 x double> [[X:%.*]], zeroinitializer
817 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
818 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
819 ; CHECK-NEXT:    ret <2 x double> [[FABS]]
821   %gezero = fcmp oge <2 x double> %x, zeroinitializer
822   %negx = fsub nnan nsz reassoc <2 x double> <double -0.0, double -0.0>, %x
823   %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
824   ret <2 x double> %fabs
827 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
829 define <2 x double> @select_fcmp_nnan_nsz_uge_zero(<2 x double> %x) {
830 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_zero(
831 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp uge <2 x double> [[X:%.*]], zeroinitializer
832 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
833 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
834 ; CHECK-NEXT:    ret <2 x double> [[FABS]]
836   %gezero = fcmp uge <2 x double> %x, zeroinitializer
837   %negx = fsub nnan nsz reassoc <2 x double> <double -0.0, double -0.0>, %x
838   %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
839   ret <2 x double> %fabs
842 define <2 x double> @select_fcmp_nnan_nsz_oge_zero_unary_fneg(<2 x double> %x) {
843 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_zero_unary_fneg(
844 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp oge <2 x double> [[X:%.*]], zeroinitializer
845 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
846 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
847 ; CHECK-NEXT:    ret <2 x double> [[FABS]]
849   %gezero = fcmp oge <2 x double> %x, zeroinitializer
850   %negx = fneg nnan nsz reassoc <2 x double> %x
851   %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
852   ret <2 x double> %fabs
855 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
857 define <2 x double> @select_fcmp_nnan_nsz_uge_zero_unary_fneg(<2 x double> %x) {
858 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_zero_unary_fneg(
859 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp uge <2 x double> [[X:%.*]], zeroinitializer
860 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
861 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
862 ; CHECK-NEXT:    ret <2 x double> [[FABS]]
864   %gezero = fcmp uge <2 x double> %x, zeroinitializer
865   %negx = fneg nnan nsz reassoc <2 x double> %x
866   %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
867   ret <2 x double> %fabs
870 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
872 define half @select_fcmp_nnan_nsz_oge_negzero(half %x) {
873 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_negzero(
874 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
875 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz half [[X]]
876 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
877 ; CHECK-NEXT:    ret half [[FABS]]
879   %gezero = fcmp oge half %x, -0.0
880   %negx = fsub nnan nsz half -0.0, %x
881   %fabs = select i1 %gezero, half %x, half %negx
882   ret half %fabs
885 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
887 define half @select_fcmp_nnan_nsz_uge_negzero(half %x) {
888 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_negzero(
889 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp uge half [[X:%.*]], 0xH0000
890 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz half [[X]]
891 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
892 ; CHECK-NEXT:    ret half [[FABS]]
894   %gezero = fcmp uge half %x, -0.0
895   %negx = fsub nnan nsz half -0.0, %x
896   %fabs = select i1 %gezero, half %x, half %negx
897   ret half %fabs
900 define half @select_fcmp_nnan_nsz_oge_negzero_unary_fneg(half %x) {
901 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_negzero_unary_fneg(
902 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
903 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz half [[X]]
904 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
905 ; CHECK-NEXT:    ret half [[FABS]]
907   %gezero = fcmp oge half %x, -0.0
908   %negx = fneg nnan nsz half %x
909   %fabs = select i1 %gezero, half %x, half %negx
910   ret half %fabs
913 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
915 define half @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(half %x) {
916 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(
917 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp uge half [[X:%.*]], 0xH0000
918 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz half [[X]]
919 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
920 ; CHECK-NEXT:    ret half [[FABS]]
922   %gezero = fcmp uge half %x, -0.0
923   %negx = fneg nnan nsz half %x
924   %fabs = select i1 %gezero, half %x, half %negx
925   ret half %fabs
928 define float @select_fneg(i1 %c, float %x) {
929 ; CHECK-LABEL: @select_fneg(
930 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
931 ; CHECK-NEXT:    ret float [[FABS]]
933   %n = fneg float %x
934   %s = select i1 %c, float %n, float %x
935   %fabs = call float @llvm.fabs.f32(float %s)
936   ret float %fabs
939 define float @select_fneg_use1(i1 %c, float %x) {
940 ; CHECK-LABEL: @select_fneg_use1(
941 ; CHECK-NEXT:    [[N:%.*]] = fneg float [[X:%.*]]
942 ; CHECK-NEXT:    call void @use(float [[N]])
943 ; CHECK-NEXT:    [[FABS:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
944 ; CHECK-NEXT:    ret float [[FABS]]
946   %n = fneg float %x
947   call void @use(float %n)
948   %s = select i1 %c, float %x, float %n
949   %fabs = call fast float @llvm.fabs.f32(float %s)
950   ret float %fabs
953 define float @select_fneg_use2(i1 %c, float %x) {
954 ; CHECK-LABEL: @select_fneg_use2(
955 ; CHECK-NEXT:    [[N:%.*]] = fneg arcp float [[X:%.*]]
956 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], float [[N]], float [[X]]
957 ; CHECK-NEXT:    call void @use(float [[S]])
958 ; CHECK-NEXT:    [[FABS:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[X]])
959 ; CHECK-NEXT:    ret float [[FABS]]
961   %n = fneg arcp float %x
962   %s = select i1 %c, float %n, float %x
963   call void @use(float %s)
964   %fabs = call nnan nsz float @llvm.fabs.f32(float %s)
965   ret float %fabs
968 define <2 x float> @select_fneg_vec(<2 x i1> %c, <2 x float> %x) {
969 ; CHECK-LABEL: @select_fneg_vec(
970 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
971 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
973   %n = fneg <2 x float> %x
974   %s = select fast <2 x i1> %c, <2 x float> %x, <2 x float> %n
975   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %s)
976   ret <2 x float> %fabs