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)
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)
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)
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)
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 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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]]
945 %s = select i1 %c, float %n, float %x
946 %fabs = call float @llvm.fabs.f32(float %s)
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]]
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)
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)
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