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)
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)
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)
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)
56 ; Make sure all intrinsic calls are eliminated when the input is known
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)
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)
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)
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)
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
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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]]
934 %s = select i1 %c, float %n, float %x
935 %fabs = call float @llvm.fabs.f32(float %s)
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]]
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)
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)
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