[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / InstCombine / fabs.ll
blob725b906f92bb94855206e79011bbbf4c58097441
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -passes=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:%.*]] = tail 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:%.*]] = tail 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:%.*]] = tail 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:%.*]] = tail 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 float @select_fcmp_ogt_fneg(float %a) {
353 ; CHECK-LABEL: @select_fcmp_ogt_fneg(
354 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz float @llvm.fabs.f32(float [[A:%.*]])
355 ; CHECK-NEXT:    ret float [[TMP1]]
357   %fneg = fneg float %a
358   %cmp = fcmp ogt float %a, %fneg
359   %r = select nsz i1 %cmp, float %a, float %fneg
360   ret float %r
363 define fp128 @select_fcmp_nnan_ogt_zero(fp128 %x) {
364 ; CHECK-LABEL: @select_fcmp_nnan_ogt_zero(
365 ; CHECK-NEXT:    [[TMP1:%.*]] = call 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 i1 %gtzero, fp128 %x, fp128 %negx
371   ret fp128 %fabs
374 define fp128 @select_nnan_fcmp_nnan_ogt_zero(fp128 %x) {
375 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ogt_zero(
376 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
377 ; CHECK-NEXT:    ret fp128 [[TMP1]]
379   %gtzero = fcmp ogt fp128 %x, zeroinitializer
380   %negx = fsub nnan fp128 zeroinitializer, %x
381   %fabs = select nnan i1 %gtzero, fp128 %x, fp128 %negx
382   ret fp128 %fabs
385 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
387 define half @select_fcmp_nnan_ogt_negzero(half %x) {
388 ; CHECK-LABEL: @select_fcmp_nnan_ogt_negzero(
389 ; CHECK-NEXT:    [[TMP1:%.*]] = call 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 i1 %gtzero, half %x, half %negx
395   ret half %fabs
398 define half @select_nnan_fcmp_nnan_ogt_negzero(half %x) {
399 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ogt_negzero(
400 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan half @llvm.fabs.f16(half [[X:%.*]])
401 ; CHECK-NEXT:    ret half [[TMP1]]
403   %gtzero = fcmp ogt half %x, -0.0
404   %negx = fsub nnan half 0.0, %x
405   %fabs = select nnan i1 %gtzero, half %x, half %negx
406   ret half %fabs
409 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
411 define half @select_fcmp_nnan_ugt_negzero(half %x) {
412 ; CHECK-LABEL: @select_fcmp_nnan_ugt_negzero(
413 ; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
414 ; CHECK-NEXT:    ret half [[TMP1]]
416   %gtzero = fcmp ugt half %x, -0.0
417   %negx = fsub nnan half 0.0, %x
418   %fabs = select i1 %gtzero, half %x, half %negx
419   ret half %fabs
422 ; Negative test - wrong predicate.
424 define half @select_fcmp_nnan_oge_negzero(half %x) {
425 ; CHECK-LABEL: @select_fcmp_nnan_oge_negzero(
426 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
427 ; CHECK-NEXT:    [[NEGX:%.*]] = fsub nnan half 0xH0000, [[X]]
428 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GTZERO]], half [[X]], half [[NEGX]]
429 ; CHECK-NEXT:    ret half [[FABS]]
431   %gtzero = fcmp oge half %x, -0.0
432   %negx = fsub nnan half 0.0, %x
433   %fabs = select i1 %gtzero, half %x, half %negx
434   ret half %fabs
437 ; X < 0.0 ? -X : X --> fabs(X)
439 define double @select_fcmp_olt_zero_unary_fneg(double %x) {
440 ; CHECK-LABEL: @select_fcmp_olt_zero_unary_fneg(
441 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
442 ; CHECK-NEXT:    ret double [[TMP1]]
444   %ltzero = fcmp olt double %x, 0.0
445   %negx = fneg double %x
446   %fabs = select nsz i1 %ltzero, double %negx, double %x
447   ret double %fabs
450 define double @select_fcmp_nnan_nsz_olt_zero(double %x) {
451 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero(
452 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
453 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz double [[X]]
454 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
455 ; CHECK-NEXT:    ret double [[FABS]]
457   %ltzero = fcmp olt double %x, 0.0
458   %negx = fsub nnan nsz double -0.0, %x
459   %fabs = select i1 %ltzero, double %negx, double %x
460   ret double %fabs
463 define double @select_nnan_nsz_fcmp_nnan_nsz_olt_zero(double %x) {
464 ; CHECK-LABEL: @select_nnan_nsz_fcmp_nnan_nsz_olt_zero(
465 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
466 ; CHECK-NEXT:    ret double [[TMP1]]
468   %ltzero = fcmp olt double %x, 0.0
469   %negx = fsub nnan nsz double -0.0, %x
470   %fabs = select nnan nsz i1 %ltzero, double %negx, double %x
471   ret double %fabs
474 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
476 define double @select_fcmp_nnan_nsz_ult_zero(double %x) {
477 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_zero(
478 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
479 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz double [[X]]
480 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
481 ; CHECK-NEXT:    ret double [[FABS]]
483   %ltzero = fcmp ult double %x, 0.0
484   %negx = fsub nnan nsz double -0.0, %x
485   %fabs = select i1 %ltzero, double %negx, double %x
486   ret double %fabs
489 define double @select_fcmp_nnan_nsz_olt_zero_unary_fneg(double %x) {
490 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero_unary_fneg(
491 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
492 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz double [[X]]
493 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
494 ; CHECK-NEXT:    ret double [[FABS]]
496   %ltzero = fcmp olt double %x, 0.0
497   %negx = fneg nnan nsz double %x
498   %fabs = select i1 %ltzero, double %negx, double %x
499   ret double %fabs
502 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
504 define double @select_fcmp_nnan_nsz_ult_zero_unary_fneg(double %x) {
505 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_zero_unary_fneg(
506 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
507 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz double [[X]]
508 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], double [[NEGX]], double [[X]]
509 ; CHECK-NEXT:    ret double [[FABS]]
511   %ltzero = fcmp ult double %x, 0.0
512   %negx = fneg nnan nsz double %x
513   %fabs = select i1 %ltzero, double %negx, double %x
514   ret double %fabs
517 ; X < -0.0 ? -X : X --> fabs(X)
519 define float @select_fcmp_nnan_nsz_olt_negzero(float %x) {
520 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_negzero(
521 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
522 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
523 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
524 ; CHECK-NEXT:    ret float [[FABS]]
526   %ltzero = fcmp olt float %x, -0.0
527   %negx = fsub nnan ninf nsz float -0.0, %x
528   %fabs = select i1 %ltzero, float %negx, float %x
529   ret float %fabs
532 define float @select_nnan_ninf_nsz_fcmp_nnan_nsz_olt_negzero(float %x) {
533 ; CHECK-LABEL: @select_nnan_ninf_nsz_fcmp_nnan_nsz_olt_negzero(
534 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan ninf nsz float @llvm.fabs.f32(float [[X:%.*]])
535 ; CHECK-NEXT:    ret float [[TMP1]]
537   %ltzero = fcmp olt float %x, -0.0
538   %negx = fsub nnan nsz float -0.0, %x
539   %fabs = select nnan ninf nsz i1 %ltzero, float %negx, float %x
540   ret float %fabs
543 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
545 define float @select_fcmp_nnan_nsz_ult_negzero(float %x) {
546 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_negzero(
547 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
548 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
549 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
550 ; CHECK-NEXT:    ret float [[FABS]]
552   %ltzero = fcmp ult float %x, -0.0
553   %negx = fsub nnan ninf nsz float -0.0, %x
554   %fabs = select i1 %ltzero, float %negx, float %x
555   ret float %fabs
558 define float @select_fcmp_nnan_nsz_olt_negzero_unary_fneg(float %x) {
559 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_negzero_unary_fneg(
560 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
561 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
562 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
563 ; CHECK-NEXT:    ret float [[FABS]]
565   %ltzero = fcmp olt float %x, -0.0
566   %negx = fneg nnan ninf nsz float %x
567   %fabs = select i1 %ltzero, float %negx, float %x
568   ret float %fabs
571 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
573 define float @select_fcmp_nnan_nsz_ult_negzero_unary_fneg(float %x) {
574 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_negzero_unary_fneg(
575 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
576 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
577 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LTZERO]], float [[NEGX]], float [[X]]
578 ; CHECK-NEXT:    ret float [[FABS]]
580   %ltzero = fcmp ult float %x, -0.0
581   %negx = fneg nnan ninf nsz float %x
582   %fabs = select i1 %ltzero, float %negx, float %x
583   ret float %fabs
586 ; X <= 0.0 ? -X : X --> fabs(X)
588 define double @select_fcmp_nnan_nsz_ole_zero(double %x) {
589 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_zero(
590 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
591 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast double [[X]]
592 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
593 ; CHECK-NEXT:    ret double [[FABS]]
595   %lezero = fcmp ole double %x, 0.0
596   %negx = fsub fast double -0.0, %x
597   %fabs = select i1 %lezero, double %negx, double %x
598   ret double %fabs
601 define double @select_fast_fcmp_nnan_nsz_ole_zero(double %x) {
602 ; CHECK-LABEL: @select_fast_fcmp_nnan_nsz_ole_zero(
603 ; CHECK-NEXT:    [[TMP1:%.*]] = call fast double @llvm.fabs.f64(double [[X:%.*]])
604 ; CHECK-NEXT:    ret double [[TMP1]]
606   %lezero = fcmp ole double %x, 0.0
607   %negx = fsub nnan nsz double -0.0, %x
608   %fabs = select fast i1 %lezero, double %negx, double %x
609   ret double %fabs
612 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
614 define double @select_fcmp_nnan_nsz_ule_zero(double %x) {
615 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_zero(
616 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
617 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast double [[X]]
618 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
619 ; CHECK-NEXT:    ret double [[FABS]]
621   %lezero = fcmp ule double %x, 0.0
622   %negx = fsub fast double -0.0, %x
623   %fabs = select i1 %lezero, double %negx, double %x
624   ret double %fabs
627 define double @select_fcmp_nnan_nsz_ole_zero_unary_fneg(double %x) {
628 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_zero_unary_fneg(
629 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
630 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast double [[X]]
631 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
632 ; CHECK-NEXT:    ret double [[FABS]]
634   %lezero = fcmp ole double %x, 0.0
635   %negx = fneg fast double %x
636   %fabs = select i1 %lezero, double %negx, double %x
637   ret double %fabs
640 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
642 define double @select_fcmp_nnan_nsz_ule_zero_unary_fneg(double %x) {
643 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_zero_unary_fneg(
644 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
645 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast double [[X]]
646 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
647 ; CHECK-NEXT:    ret double [[FABS]]
649   %lezero = fcmp ule double %x, 0.0
650   %negx = fneg fast double %x
651   %fabs = select i1 %lezero, double %negx, double %x
652   ret double %fabs
655 ; X <= -0.0 ? -X : X --> fabs(X)
657 define float @select_fcmp_nnan_nsz_ole_negzero(float %x) {
658 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_negzero(
659 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
660 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz float [[X]]
661 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
662 ; CHECK-NEXT:    ret float [[FABS]]
664   %lezero = fcmp ole float %x, -0.0
665   %negx = fsub nnan nsz float -0.0, %x
666   %fabs = select i1 %lezero, float %negx, float %x
667   ret float %fabs
670 define float @select_nnan_nsz_fcmp_nnan_nsz_ole_negzero(float %x) {
671 ; CHECK-LABEL: @select_nnan_nsz_fcmp_nnan_nsz_ole_negzero(
672 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[X:%.*]])
673 ; CHECK-NEXT:    ret float [[TMP1]]
675   %lezero = fcmp ole float %x, -0.0
676   %negx = fsub nnan nsz float -0.0, %x
677   %fabs = select nnan nsz i1 %lezero, float %negx, float %x
678   ret float %fabs
681 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
683 define float @select_fcmp_nnan_nsz_ule_negzero(float %x) {
684 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_negzero(
685 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ule float [[X:%.*]], 0.000000e+00
686 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz float [[X]]
687 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
688 ; CHECK-NEXT:    ret float [[FABS]]
690   %lezero = fcmp ule float %x, -0.0
691   %negx = fsub nnan nsz float -0.0, %x
692   %fabs = select i1 %lezero, float %negx, float %x
693   ret float %fabs
696 define float @select_fcmp_nnan_nsz_ole_negzero_unary_fneg(float %x) {
697 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_negzero_unary_fneg(
698 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
699 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz float [[X]]
700 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
701 ; CHECK-NEXT:    ret float [[FABS]]
703   %lezero = fcmp ole float %x, -0.0
704   %negx = fneg nnan nsz float %x
705   %fabs = select i1 %lezero, float %negx, float %x
706   ret float %fabs
709 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
711 define float @select_fcmp_nnan_nsz_ule_negzero_unary_fneg(float %x) {
712 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_negzero_unary_fneg(
713 ; CHECK-NEXT:    [[LEZERO:%.*]] = fcmp ule float [[X:%.*]], 0.000000e+00
714 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz float [[X]]
715 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[LEZERO]], float [[NEGX]], float [[X]]
716 ; CHECK-NEXT:    ret float [[FABS]]
718   %lezero = fcmp ule float %x, -0.0
719   %negx = fneg nnan nsz float %x
720   %fabs = select i1 %lezero, float %negx, float %x
721   ret float %fabs
724 ; X > 0.0 ? X : (0.0 - X) --> fabs(X)
726 define <2 x float> @select_fcmp_ogt_zero_unary_fneg(<2 x float> %x) {
727 ; CHECK-LABEL: @select_fcmp_ogt_zero_unary_fneg(
728 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
729 ; CHECK-NEXT:    ret <2 x float> [[TMP1]]
731   %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
732   %negx = fneg <2 x float> %x
733   %fabs = select nsz <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
734   ret <2 x float> %fabs
737 define <2 x float> @select_fcmp_nnan_nsz_ogt_zero(<2 x float> %x) {
738 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_zero(
739 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer
740 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
741 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
742 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
744   %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
745   %negx = fsub nnan nsz arcp <2 x float> <float -0.0, float -0.0>, %x
746   %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
747   ret <2 x float> %fabs
750 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
752 define <2 x float> @select_fcmp_nnan_nsz_ugt_zero(<2 x float> %x) {
753 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_zero(
754 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ugt <2 x float> [[X:%.*]], zeroinitializer
755 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
756 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
757 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
759   %gtzero = fcmp ugt <2 x float> %x, zeroinitializer
760   %negx = fsub nnan nsz arcp <2 x float> <float -0.0, float -0.0>, %x
761   %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
762   ret <2 x float> %fabs
765 define <2 x float> @select_fcmp_nnan_nsz_ogt_zero_unary_fneg(<2 x float> %x) {
766 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_zero_unary_fneg(
767 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer
768 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
769 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
770 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
772   %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
773   %negx = fneg nnan nsz arcp <2 x float> %x
774   %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
775   ret <2 x float> %fabs
778 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
780 define <2 x float> @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(<2 x float> %x) {
781 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(
782 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ugt <2 x float> [[X:%.*]], zeroinitializer
783 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
784 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
785 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
787   %gtzero = fcmp ugt <2 x float> %x, zeroinitializer
788   %negx = fneg nnan nsz arcp <2 x float> %x
789   %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
790   ret <2 x float> %fabs
793 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
795 define half @select_fcmp_nnan_nsz_ogt_negzero(half %x) {
796 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_negzero(
797 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000
798 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast half [[X]]
799 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GTZERO]], half [[X]], half [[NEGX]]
800 ; CHECK-NEXT:    ret half [[FABS]]
802   %gtzero = fcmp ogt half %x, -0.0
803   %negx = fsub fast half 0.0, %x
804   %fabs = select i1 %gtzero, half %x, half %negx
805   ret half %fabs
808 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
810 define half @select_fcmp_nnan_nsz_ugt_negzero(half %x) {
811 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_negzero(
812 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ugt half [[X:%.*]], 0xH0000
813 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg fast half [[X]]
814 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GTZERO]], half [[X]], half [[NEGX]]
815 ; CHECK-NEXT:    ret half [[FABS]]
817   %gtzero = fcmp ugt half %x, -0.0
818   %negx = fsub fast half 0.0, %x
819   %fabs = select i1 %gtzero, half %x, half %negx
820   ret half %fabs
823 ; X > 0.0 ? X : (0.0 - X) --> fabs(X)
825 define <2 x double> @select_fcmp_nnan_nsz_oge_zero(<2 x double> %x) {
826 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_zero(
827 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp oge <2 x double> [[X:%.*]], zeroinitializer
828 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
829 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
830 ; CHECK-NEXT:    ret <2 x double> [[FABS]]
832   %gezero = fcmp oge <2 x double> %x, zeroinitializer
833   %negx = fsub nnan nsz reassoc <2 x double> <double -0.0, double -0.0>, %x
834   %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
835   ret <2 x double> %fabs
838 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
840 define <2 x double> @select_fcmp_nnan_nsz_uge_zero(<2 x double> %x) {
841 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_zero(
842 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp uge <2 x double> [[X:%.*]], zeroinitializer
843 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
844 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
845 ; CHECK-NEXT:    ret <2 x double> [[FABS]]
847   %gezero = fcmp uge <2 x double> %x, zeroinitializer
848   %negx = fsub nnan nsz reassoc <2 x double> <double -0.0, double -0.0>, %x
849   %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
850   ret <2 x double> %fabs
853 define <2 x double> @select_fcmp_nnan_nsz_oge_zero_unary_fneg(<2 x double> %x) {
854 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_zero_unary_fneg(
855 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp oge <2 x double> [[X:%.*]], zeroinitializer
856 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
857 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
858 ; CHECK-NEXT:    ret <2 x double> [[FABS]]
860   %gezero = fcmp oge <2 x double> %x, zeroinitializer
861   %negx = fneg nnan nsz reassoc <2 x double> %x
862   %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
863   ret <2 x double> %fabs
866 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
868 define <2 x double> @select_fcmp_nnan_nsz_uge_zero_unary_fneg(<2 x double> %x) {
869 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_zero_unary_fneg(
870 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp uge <2 x double> [[X:%.*]], zeroinitializer
871 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
872 ; CHECK-NEXT:    [[FABS:%.*]] = select <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
873 ; CHECK-NEXT:    ret <2 x double> [[FABS]]
875   %gezero = fcmp uge <2 x double> %x, zeroinitializer
876   %negx = fneg nnan nsz reassoc <2 x double> %x
877   %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
878   ret <2 x double> %fabs
881 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
883 define half @select_fcmp_nnan_nsz_oge_negzero(half %x) {
884 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_negzero(
885 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
886 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz half [[X]]
887 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
888 ; CHECK-NEXT:    ret half [[FABS]]
890   %gezero = fcmp oge half %x, -0.0
891   %negx = fsub nnan nsz half -0.0, %x
892   %fabs = select i1 %gezero, half %x, half %negx
893   ret half %fabs
896 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
898 define half @select_fcmp_nnan_nsz_uge_negzero(half %x) {
899 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_negzero(
900 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp uge half [[X:%.*]], 0xH0000
901 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz half [[X]]
902 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
903 ; CHECK-NEXT:    ret half [[FABS]]
905   %gezero = fcmp uge half %x, -0.0
906   %negx = fsub nnan nsz half -0.0, %x
907   %fabs = select i1 %gezero, half %x, half %negx
908   ret half %fabs
911 define half @select_fcmp_nnan_nsz_oge_negzero_unary_fneg(half %x) {
912 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_negzero_unary_fneg(
913 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
914 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz half [[X]]
915 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
916 ; CHECK-NEXT:    ret half [[FABS]]
918   %gezero = fcmp oge half %x, -0.0
919   %negx = fneg nnan nsz half %x
920   %fabs = select i1 %gezero, half %x, half %negx
921   ret half %fabs
924 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
926 define half @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(half %x) {
927 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(
928 ; CHECK-NEXT:    [[GEZERO:%.*]] = fcmp uge half [[X:%.*]], 0xH0000
929 ; CHECK-NEXT:    [[NEGX:%.*]] = fneg nnan nsz half [[X]]
930 ; CHECK-NEXT:    [[FABS:%.*]] = select i1 [[GEZERO]], half [[X]], half [[NEGX]]
931 ; CHECK-NEXT:    ret half [[FABS]]
933   %gezero = fcmp uge half %x, -0.0
934   %negx = fneg nnan nsz half %x
935   %fabs = select i1 %gezero, half %x, half %negx
936   ret half %fabs
939 define float @select_fneg(i1 %c, float %x) {
940 ; CHECK-LABEL: @select_fneg(
941 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
942 ; CHECK-NEXT:    ret float [[FABS]]
944   %n = fneg float %x
945   %s = select i1 %c, float %n, float %x
946   %fabs = call float @llvm.fabs.f32(float %s)
947   ret float %fabs
950 define float @select_fneg_use1(i1 %c, float %x) {
951 ; CHECK-LABEL: @select_fneg_use1(
952 ; CHECK-NEXT:    [[N:%.*]] = fneg float [[X:%.*]]
953 ; CHECK-NEXT:    call void @use(float [[N]])
954 ; CHECK-NEXT:    [[FABS:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
955 ; CHECK-NEXT:    ret float [[FABS]]
957   %n = fneg float %x
958   call void @use(float %n)
959   %s = select i1 %c, float %x, float %n
960   %fabs = call fast float @llvm.fabs.f32(float %s)
961   ret float %fabs
964 define float @select_fneg_use2(i1 %c, float %x) {
965 ; CHECK-LABEL: @select_fneg_use2(
966 ; CHECK-NEXT:    [[N:%.*]] = fneg arcp float [[X:%.*]]
967 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], float [[N]], float [[X]]
968 ; CHECK-NEXT:    call void @use(float [[S]])
969 ; CHECK-NEXT:    [[FABS:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[X]])
970 ; CHECK-NEXT:    ret float [[FABS]]
972   %n = fneg arcp float %x
973   %s = select i1 %c, float %n, float %x
974   call void @use(float %s)
975   %fabs = call nnan nsz float @llvm.fabs.f32(float %s)
976   ret float %fabs
979 define <2 x float> @select_fneg_vec(<2 x i1> %c, <2 x float> %x) {
980 ; CHECK-LABEL: @select_fneg_vec(
981 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
982 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
984   %n = fneg <2 x float> %x
985   %s = select fast <2 x i1> %c, <2 x float> %x, <2 x float> %n
986   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %s)
987   ret <2 x float> %fabs