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)
18 declare void @usebool(i1)
20 define float @replace_fabs_call_f32(float %x) {
21 ; CHECK-LABEL: @replace_fabs_call_f32(
22 ; CHECK-NEXT: [[FABSF:%.*]] = tail call float @llvm.fabs.f32(float [[X:%.*]])
23 ; CHECK-NEXT: ret float [[FABSF]]
25 %fabsf = tail call float @fabsf(float %x)
29 define double @replace_fabs_call_f64(double %x) {
30 ; CHECK-LABEL: @replace_fabs_call_f64(
31 ; CHECK-NEXT: [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
32 ; CHECK-NEXT: ret double [[FABS]]
34 %fabs = tail call double @fabs(double %x)
38 define fp128 @replace_fabs_call_f128(fp128 %x) {
39 ; CHECK-LABEL: @replace_fabs_call_f128(
40 ; CHECK-NEXT: [[FABSL:%.*]] = tail call fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
41 ; CHECK-NEXT: ret fp128 [[FABSL]]
43 %fabsl = tail call fp128 @fabsl(fp128 %x)
47 ; Make sure fast math flags are preserved when replacing the libcall.
48 define float @fmf_replace_fabs_call_f32(float %x) {
49 ; CHECK-LABEL: @fmf_replace_fabs_call_f32(
50 ; CHECK-NEXT: [[FABSF:%.*]] = tail call nnan float @llvm.fabs.f32(float [[X:%.*]])
51 ; CHECK-NEXT: ret float [[FABSF]]
53 %fabsf = tail call nnan float @fabsf(float %x)
57 ; Make sure all intrinsic calls are eliminated when the input is known
60 ; The fabs cannot be eliminated because %x may be a NaN
62 define float @square_fabs_intrinsic_f32(float %x) {
63 ; CHECK-LABEL: @square_fabs_intrinsic_f32(
64 ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], [[X]]
65 ; CHECK-NEXT: [[FABSF:%.*]] = tail call float @llvm.fabs.f32(float [[MUL]])
66 ; CHECK-NEXT: ret float [[FABSF]]
68 %mul = fmul float %x, %x
69 %fabsf = tail call float @llvm.fabs.f32(float %mul)
73 define double @square_fabs_intrinsic_f64(double %x) {
74 ; CHECK-LABEL: @square_fabs_intrinsic_f64(
75 ; CHECK-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], [[X]]
76 ; CHECK-NEXT: [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[MUL]])
77 ; CHECK-NEXT: ret double [[FABS]]
79 %mul = fmul double %x, %x
80 %fabs = tail call double @llvm.fabs.f64(double %mul)
84 define fp128 @square_fabs_intrinsic_f128(fp128 %x) {
85 ; CHECK-LABEL: @square_fabs_intrinsic_f128(
86 ; CHECK-NEXT: [[MUL:%.*]] = fmul fp128 [[X:%.*]], [[X]]
87 ; CHECK-NEXT: [[FABSL:%.*]] = tail call fp128 @llvm.fabs.f128(fp128 [[MUL]])
88 ; CHECK-NEXT: ret fp128 [[FABSL]]
90 %mul = fmul fp128 %x, %x
91 %fabsl = tail call fp128 @llvm.fabs.f128(fp128 %mul)
95 define float @square_nnan_fabs_intrinsic_f32(float %x) {
96 ; CHECK-LABEL: @square_nnan_fabs_intrinsic_f32(
97 ; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[X:%.*]], [[X]]
98 ; CHECK-NEXT: ret float [[MUL]]
100 %mul = fmul nnan float %x, %x
101 %fabsf = call float @llvm.fabs.f32(float %mul)
105 ; Shrinking a library call to a smaller type should not be inhibited by nor inhibit the square optimization.
107 define float @square_fabs_shrink_call1(float %x) {
108 ; CHECK-LABEL: @square_fabs_shrink_call1(
109 ; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[X:%.*]], [[X]]
110 ; CHECK-NEXT: [[TRUNC:%.*]] = call float @llvm.fabs.f32(float [[TMP1]])
111 ; CHECK-NEXT: ret float [[TRUNC]]
113 %ext = fpext float %x to double
114 %sq = fmul double %ext, %ext
115 %fabs = call double @fabs(double %sq)
116 %trunc = fptrunc double %fabs to float
120 define float @square_fabs_shrink_call2(float %x) {
121 ; CHECK-LABEL: @square_fabs_shrink_call2(
122 ; CHECK-NEXT: [[SQ:%.*]] = fmul float [[X:%.*]], [[X]]
123 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[SQ]])
124 ; CHECK-NEXT: ret float [[TMP1]]
126 %sq = fmul float %x, %x
127 %ext = fpext float %sq to double
128 %fabs = call double @fabs(double %ext)
129 %trunc = fptrunc double %fabs to float
133 define float @fabs_select_constant_negative_positive(i32 %c) {
134 ; CHECK-LABEL: @fabs_select_constant_negative_positive(
135 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
136 ; CHECK-NEXT: [[FABS:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
137 ; CHECK-NEXT: ret float [[FABS]]
139 %cmp = icmp eq i32 %c, 0
140 %select = select i1 %cmp, float -1.0, float 2.0
141 %fabs = call float @llvm.fabs.f32(float %select)
145 define float @fabs_select_constant_positive_negative(i32 %c) {
146 ; CHECK-LABEL: @fabs_select_constant_positive_negative(
147 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
148 ; CHECK-NEXT: [[FABS:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
149 ; CHECK-NEXT: ret float [[FABS]]
151 %cmp = icmp eq i32 %c, 0
152 %select = select i1 %cmp, float 1.0, float -2.0
153 %fabs = call float @llvm.fabs.f32(float %select)
157 define float @fabs_select_constant_negative_negative(i32 %c) {
158 ; CHECK-LABEL: @fabs_select_constant_negative_negative(
159 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
160 ; CHECK-NEXT: [[FABS:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
161 ; CHECK-NEXT: ret float [[FABS]]
163 %cmp = icmp eq i32 %c, 0
164 %select = select i1 %cmp, float -1.0, float -2.0
165 %fabs = call float @llvm.fabs.f32(float %select)
169 define float @fabs_select_constant_neg0(i32 %c) {
170 ; CHECK-LABEL: @fabs_select_constant_neg0(
171 ; CHECK-NEXT: ret float 0.000000e+00
173 %cmp = icmp eq i32 %c, 0
174 %select = select i1 %cmp, float -0.0, float 0.0
175 %fabs = call float @llvm.fabs.f32(float %select)
179 define float @fabs_select_var_constant_negative(i32 %c, float %x) {
180 ; CHECK-LABEL: @fabs_select_var_constant_negative(
181 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
182 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT:%.*]])
183 ; CHECK-NEXT: [[FABS1:%.*]] = select i1 [[CMP]], float [[FABS]], float 1.000000e+00
184 ; CHECK-NEXT: ret float [[FABS1]]
186 %cmp = icmp eq i32 %c, 0
187 %select = select i1 %cmp, float %x, float -1.0
188 %fabs = call float @llvm.fabs.f32(float %select)
192 ; The fabs cannot be eliminated because %x may be a NaN
194 define float @square_fma_fabs_intrinsic_f32(float %x) {
195 ; CHECK-LABEL: @square_fma_fabs_intrinsic_f32(
196 ; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[X]], float 1.000000e+00)
197 ; CHECK-NEXT: [[FABSF:%.*]] = call float @llvm.fabs.f32(float [[FMA]])
198 ; CHECK-NEXT: ret float [[FABSF]]
200 %fma = call float @llvm.fma.f32(float %x, float %x, float 1.0)
201 %fabsf = call float @llvm.fabs.f32(float %fma)
205 ; The fabs cannot be eliminated because %x may be a NaN
207 define float @square_nnan_fma_fabs_intrinsic_f32(float %x) {
208 ; CHECK-LABEL: @square_nnan_fma_fabs_intrinsic_f32(
209 ; CHECK-NEXT: [[FMA:%.*]] = call nnan float @llvm.fma.f32(float [[X:%.*]], float [[X]], float 1.000000e+00)
210 ; CHECK-NEXT: ret float [[FMA]]
212 %fma = call nnan float @llvm.fma.f32(float %x, float %x, float 1.0)
213 %fabsf = call float @llvm.fabs.f32(float %fma)
217 define float @square_fmuladd_fabs_intrinsic_f32(float %x) {
218 ; CHECK-LABEL: @square_fmuladd_fabs_intrinsic_f32(
219 ; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float 1.000000e+00)
220 ; CHECK-NEXT: [[FABSF:%.*]] = call float @llvm.fabs.f32(float [[FMULADD]])
221 ; CHECK-NEXT: ret float [[FABSF]]
223 %fmuladd = call float @llvm.fmuladd.f32(float %x, float %x, float 1.0)
224 %fabsf = call float @llvm.fabs.f32(float %fmuladd)
228 define float @square_nnan_fmuladd_fabs_intrinsic_f32(float %x) {
229 ; CHECK-LABEL: @square_nnan_fmuladd_fabs_intrinsic_f32(
230 ; CHECK-NEXT: [[FMULADD:%.*]] = call nnan float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float 1.000000e+00)
231 ; CHECK-NEXT: ret float [[FMULADD]]
233 %fmuladd = call nnan float @llvm.fmuladd.f32(float %x, float %x, float 1.0)
234 %fabsf = call float @llvm.fabs.f32(float %fmuladd)
238 ; Don't introduce a second fpext
240 define double @multi_use_fabs_fpext(float %x) {
241 ; CHECK-LABEL: @multi_use_fabs_fpext(
242 ; CHECK-NEXT: [[FPEXT:%.*]] = fpext float [[X:%.*]] to double
243 ; CHECK-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[FPEXT]])
244 ; CHECK-NEXT: store volatile double [[FPEXT]], ptr undef, align 8
245 ; CHECK-NEXT: ret double [[FABS]]
247 %fpext = fpext float %x to double
248 %fabs = call double @llvm.fabs.f64(double %fpext)
249 store volatile double %fpext, ptr undef
253 ; X <= 0.0 ? (0.0 - X) : X --> fabs(X)
255 define double @select_fcmp_ole_zero(double %x) {
256 ; CHECK-LABEL: @select_fcmp_ole_zero(
257 ; CHECK-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
258 ; CHECK-NEXT: ret double [[FABS]]
260 %lezero = fcmp ole double %x, 0.0
261 %negx = fsub double 0.0, %x
262 %fabs = select i1 %lezero, double %negx, double %x
266 define double @select_fcmp_nnan_ole_zero(double %x) {
267 ; CHECK-LABEL: @select_fcmp_nnan_ole_zero(
268 ; CHECK-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
269 ; CHECK-NEXT: ret double [[FABS]]
271 %lezero = fcmp ole double %x, 0.0
272 %negx = fsub nnan double 0.0, %x
273 %fabs = select i1 %lezero, double %negx, double %x
277 define double @select_nnan_fcmp_nnan_ole_zero(double %x) {
278 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ole_zero(
279 ; CHECK-NEXT: [[FABS:%.*]] = call nnan double @llvm.fabs.f64(double [[X:%.*]])
280 ; CHECK-NEXT: ret double [[FABS]]
282 %lezero = fcmp ole double %x, 0.0
283 %negx = fsub nnan double 0.0, %x
284 %fabs = select nnan i1 %lezero, double %negx, double %x
288 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
290 define double @select_fcmp_nnan_ule_zero(double %x) {
291 ; CHECK-LABEL: @select_fcmp_nnan_ule_zero(
292 ; CHECK-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
293 ; CHECK-NEXT: ret double [[FABS]]
295 %lezero = fcmp ule double %x, 0.0
296 %negx = fsub nnan double 0.0, %x
297 %fabs = select i1 %lezero, double %negx, double %x
301 ; Negative test - wrong predicate.
303 define double @select_fcmp_nnan_olt_zero(double %x) {
304 ; CHECK-LABEL: @select_fcmp_nnan_olt_zero(
305 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
306 ; CHECK-NEXT: [[NEGX:%.*]] = fsub nnan double 0.000000e+00, [[X]]
307 ; CHECK-NEXT: [[FABS:%.*]] = select i1 [[LEZERO]], double [[NEGX]], double [[X]]
308 ; CHECK-NEXT: ret double [[FABS]]
310 %lezero = fcmp olt double %x, 0.0
311 %negx = fsub nnan double 0.0, %x
312 %fabs = select i1 %lezero, double %negx, double %x
316 ; X <= -0.0 ? (0.0 - X) : X --> fabs(X)
318 define <2 x float> @select_fcmp_nnan_ole_negzero(<2 x float> %x) {
319 ; CHECK-LABEL: @select_fcmp_nnan_ole_negzero(
320 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
321 ; CHECK-NEXT: ret <2 x float> [[FABS]]
323 %lezero = fcmp ole <2 x float> %x, <float -0.0, float -0.0>
324 %negx = fsub nnan <2 x float> <float 0.0, float poison>, %x
325 %fabs = select <2 x i1> %lezero, <2 x float> %negx, <2 x float> %x
326 ret <2 x float> %fabs
329 define <2 x float> @select_nnan_fcmp_nnan_ole_negzero(<2 x float> %x) {
330 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ole_negzero(
331 ; CHECK-NEXT: [[FABS:%.*]] = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
332 ; CHECK-NEXT: ret <2 x float> [[FABS]]
334 %lezero = fcmp ole <2 x float> %x, <float -0.0, float -0.0>
335 %negx = fsub nnan <2 x float> <float 0.0, float poison>, %x
336 %fabs = select nnan <2 x i1> %lezero, <2 x float> %negx, <2 x float> %x
337 ret <2 x float> %fabs
340 ; X > 0.0 ? X : (0.0 - X) --> fabs(X)
342 define fp128 @select_fcmp_ogt_zero(fp128 %x) {
343 ; CHECK-LABEL: @select_fcmp_ogt_zero(
344 ; CHECK-NEXT: [[FABS:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
345 ; CHECK-NEXT: ret fp128 [[FABS]]
347 %gtzero = fcmp ogt fp128 %x, zeroinitializer
348 %negx = fsub fp128 zeroinitializer, %x
349 %fabs = select i1 %gtzero, fp128 %x, fp128 %negx
353 ; This is not fabs because that could produce a different signbit for a NAN input.
356 define float @select_nsz_fcmp_ogt_fneg(float %a) {
357 ; CHECK-LABEL: @select_nsz_fcmp_ogt_fneg(
358 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A:%.*]]
359 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A]], 0.000000e+00
360 ; CHECK-NEXT: [[R:%.*]] = select nsz i1 [[CMP]], float [[A]], float [[FNEG]]
361 ; CHECK-NEXT: ret float [[R]]
363 %fneg = fneg float %a
364 %cmp = fcmp ogt float %a, %fneg
365 %r = select nsz i1 %cmp, float %a, float %fneg
369 define float @select_nsz_nnan_fcmp_ogt_fneg(float %a) {
370 ; CHECK-LABEL: @select_nsz_nnan_fcmp_ogt_fneg(
371 ; CHECK-NEXT: [[R:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[A:%.*]])
372 ; CHECK-NEXT: ret float [[R]]
374 %fneg = fneg float %a
375 %cmp = fcmp ogt float %a, %fneg
376 %r = select nsz nnan i1 %cmp, float %a, float %fneg
380 define fp128 @select_fcmp_nnan_ogt_zero(fp128 %x) {
381 ; CHECK-LABEL: @select_fcmp_nnan_ogt_zero(
382 ; CHECK-NEXT: [[FABS:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
383 ; CHECK-NEXT: ret fp128 [[FABS]]
385 %gtzero = fcmp ogt fp128 %x, zeroinitializer
386 %negx = fsub nnan fp128 zeroinitializer, %x
387 %fabs = select i1 %gtzero, fp128 %x, fp128 %negx
391 define fp128 @select_nnan_fcmp_nnan_ogt_zero(fp128 %x) {
392 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ogt_zero(
393 ; CHECK-NEXT: [[FABS:%.*]] = call nnan fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
394 ; CHECK-NEXT: ret fp128 [[FABS]]
396 %gtzero = fcmp ogt fp128 %x, zeroinitializer
397 %negx = fsub nnan fp128 zeroinitializer, %x
398 %fabs = select nnan i1 %gtzero, fp128 %x, fp128 %negx
402 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
404 define half @select_fcmp_nnan_ogt_negzero(half %x) {
405 ; CHECK-LABEL: @select_fcmp_nnan_ogt_negzero(
406 ; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
407 ; CHECK-NEXT: ret half [[FABS]]
409 %gtzero = fcmp ogt half %x, -0.0
410 %negx = fsub nnan half 0.0, %x
411 %fabs = select i1 %gtzero, half %x, half %negx
415 define half @select_nnan_fcmp_nnan_ogt_negzero(half %x) {
416 ; CHECK-LABEL: @select_nnan_fcmp_nnan_ogt_negzero(
417 ; CHECK-NEXT: [[FABS:%.*]] = call nnan half @llvm.fabs.f16(half [[X:%.*]])
418 ; CHECK-NEXT: ret half [[FABS]]
420 %gtzero = fcmp ogt half %x, -0.0
421 %negx = fsub nnan half 0.0, %x
422 %fabs = select nnan i1 %gtzero, half %x, half %negx
426 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
428 define half @select_fcmp_nnan_ugt_negzero(half %x) {
429 ; CHECK-LABEL: @select_fcmp_nnan_ugt_negzero(
430 ; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
431 ; CHECK-NEXT: ret half [[FABS]]
433 %gtzero = fcmp ugt half %x, -0.0
434 %negx = fsub nnan half 0.0, %x
435 %fabs = select i1 %gtzero, half %x, half %negx
439 ; Negative test - wrong predicate.
441 define half @select_fcmp_nnan_oge_negzero(half %x) {
442 ; CHECK-LABEL: @select_fcmp_nnan_oge_negzero(
443 ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
444 ; CHECK-NEXT: [[NEGX:%.*]] = fsub nnan half 0xH0000, [[X]]
445 ; CHECK-NEXT: [[FABS:%.*]] = select i1 [[GTZERO]], half [[X]], half [[NEGX]]
446 ; CHECK-NEXT: ret half [[FABS]]
448 %gtzero = fcmp oge half %x, -0.0
449 %negx = fsub nnan half 0.0, %x
450 %fabs = select i1 %gtzero, half %x, half %negx
454 ; This is not fabs because that could produce a different signbit for a NAN input.
457 define double @select_nsz_fcmp_olt_zero_unary_fneg(double %x) {
458 ; CHECK-LABEL: @select_nsz_fcmp_olt_zero_unary_fneg(
459 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
460 ; CHECK-NEXT: [[NEGX:%.*]] = fneg double [[X]]
461 ; CHECK-NEXT: [[FABS:%.*]] = select nsz i1 [[LTZERO]], double [[NEGX]], double [[X]]
462 ; CHECK-NEXT: ret double [[FABS]]
464 %ltzero = fcmp olt double %x, 0.0
465 %negx = fneg double %x
466 %fabs = select nsz i1 %ltzero, double %negx, double %x
470 ; X < 0.0 ? -X : X --> fabs(X)
472 define double @select_nsz_nnan_fcmp_olt_zero_unary_fneg(double %x) {
473 ; CHECK-LABEL: @select_nsz_nnan_fcmp_olt_zero_unary_fneg(
474 ; CHECK-NEXT: [[FABS:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
475 ; CHECK-NEXT: ret double [[FABS]]
477 %ltzero = fcmp olt double %x, 0.0
478 %negx = fneg double %x
479 %fabs = select nsz nnan i1 %ltzero, double %negx, double %x
483 define double @select_fcmp_nnan_nsz_olt_zero(double %x) {
484 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero(
485 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
486 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz double [[X]]
487 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LTZERO]], double [[NEGX]], double [[X]]
488 ; CHECK-NEXT: ret double [[FABS]]
490 %ltzero = fcmp olt double %x, 0.0
491 %negx = fsub nnan nsz double -0.0, %x
492 %fabs = select i1 %ltzero, double %negx, double %x
496 define double @select_nnan_nsz_fcmp_nnan_nsz_olt_zero(double %x) {
497 ; CHECK-LABEL: @select_nnan_nsz_fcmp_nnan_nsz_olt_zero(
498 ; CHECK-NEXT: [[FABS:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
499 ; CHECK-NEXT: ret double [[FABS]]
501 %ltzero = fcmp olt double %x, 0.0
502 %negx = fsub nnan nsz double -0.0, %x
503 %fabs = select nnan nsz i1 %ltzero, double %negx, double %x
507 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
509 define double @select_fcmp_nnan_nsz_ult_zero(double %x) {
510 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_zero(
511 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
512 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz double [[X]]
513 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LTZERO]], double [[NEGX]], double [[X]]
514 ; CHECK-NEXT: ret double [[FABS]]
516 %ltzero = fcmp ult double %x, 0.0
517 %negx = fsub nnan nsz double -0.0, %x
518 %fabs = select i1 %ltzero, double %negx, double %x
522 define double @select_fcmp_nnan_nsz_olt_zero_unary_fneg(double %x) {
523 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero_unary_fneg(
524 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
525 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz double [[X]]
526 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LTZERO]], double [[NEGX]], double [[X]]
527 ; CHECK-NEXT: ret double [[FABS]]
529 %ltzero = fcmp olt double %x, 0.0
530 %negx = fneg nnan nsz double %x
531 %fabs = select i1 %ltzero, double %negx, double %x
535 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
537 define double @select_fcmp_nnan_nsz_ult_zero_unary_fneg(double %x) {
538 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_zero_unary_fneg(
539 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp ult double [[X:%.*]], 0.000000e+00
540 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz double [[X]]
541 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LTZERO]], double [[NEGX]], double [[X]]
542 ; CHECK-NEXT: ret double [[FABS]]
544 %ltzero = fcmp ult double %x, 0.0
545 %negx = fneg nnan nsz double %x
546 %fabs = select i1 %ltzero, double %negx, double %x
550 ; X < -0.0 ? -X : X --> fabs(X)
552 define float @select_fcmp_nnan_nsz_olt_negzero(float %x) {
553 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_negzero(
554 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
555 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
556 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LTZERO]], float [[NEGX]], float [[X]]
557 ; CHECK-NEXT: ret float [[FABS]]
559 %ltzero = fcmp olt float %x, -0.0
560 %negx = fsub nnan ninf nsz float -0.0, %x
561 %fabs = select i1 %ltzero, float %negx, float %x
565 define float @select_nnan_ninf_nsz_fcmp_nnan_nsz_olt_negzero(float %x) {
566 ; CHECK-LABEL: @select_nnan_ninf_nsz_fcmp_nnan_nsz_olt_negzero(
567 ; CHECK-NEXT: [[FABS:%.*]] = call nnan ninf nsz float @llvm.fabs.f32(float [[X:%.*]])
568 ; CHECK-NEXT: ret float [[FABS]]
570 %ltzero = fcmp olt float %x, -0.0
571 %negx = fsub nnan nsz float -0.0, %x
572 %fabs = select nnan ninf nsz i1 %ltzero, float %negx, float %x
576 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
578 define float @select_fcmp_nnan_nsz_ult_negzero(float %x) {
579 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_negzero(
580 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
581 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
582 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LTZERO]], float [[NEGX]], float [[X]]
583 ; CHECK-NEXT: ret float [[FABS]]
585 %ltzero = fcmp ult float %x, -0.0
586 %negx = fsub nnan ninf nsz float -0.0, %x
587 %fabs = select i1 %ltzero, float %negx, float %x
591 define float @select_fcmp_nnan_nsz_olt_negzero_unary_fneg(float %x) {
592 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_negzero_unary_fneg(
593 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
594 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
595 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LTZERO]], float [[NEGX]], float [[X]]
596 ; CHECK-NEXT: ret float [[FABS]]
598 %ltzero = fcmp olt float %x, -0.0
599 %negx = fneg nnan ninf nsz float %x
600 %fabs = select i1 %ltzero, float %negx, float %x
604 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
606 define float @select_fcmp_nnan_nsz_ult_negzero_unary_fneg(float %x) {
607 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ult_negzero_unary_fneg(
608 ; CHECK-NEXT: [[LTZERO:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
609 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan ninf nsz float [[X]]
610 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LTZERO]], float [[NEGX]], float [[X]]
611 ; CHECK-NEXT: ret float [[FABS]]
613 %ltzero = fcmp ult float %x, -0.0
614 %negx = fneg nnan ninf nsz float %x
615 %fabs = select i1 %ltzero, float %negx, float %x
619 ; X <= 0.0 ? -X : X --> fabs(X)
621 define double @select_fcmp_nnan_nsz_ole_zero(double %x) {
622 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_zero(
623 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
624 ; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
625 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LEZERO]], double [[NEGX]], double [[X]]
626 ; CHECK-NEXT: ret double [[FABS]]
628 %lezero = fcmp ole double %x, 0.0
629 %negx = fsub fast double -0.0, %x
630 %fabs = select i1 %lezero, double %negx, double %x
634 define double @select_fast_fcmp_nnan_nsz_ole_zero(double %x) {
635 ; CHECK-LABEL: @select_fast_fcmp_nnan_nsz_ole_zero(
636 ; CHECK-NEXT: [[FABS:%.*]] = call fast double @llvm.fabs.f64(double [[X:%.*]])
637 ; CHECK-NEXT: ret double [[FABS]]
639 %lezero = fcmp ole double %x, 0.0
640 %negx = fsub nnan nsz double -0.0, %x
641 %fabs = select fast i1 %lezero, double %negx, double %x
645 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
647 define double @select_fcmp_nnan_nsz_ule_zero(double %x) {
648 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_zero(
649 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
650 ; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
651 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LEZERO]], double [[NEGX]], double [[X]]
652 ; CHECK-NEXT: ret double [[FABS]]
654 %lezero = fcmp ule double %x, 0.0
655 %negx = fsub fast double -0.0, %x
656 %fabs = select i1 %lezero, double %negx, double %x
660 define double @select_fcmp_nnan_nsz_ole_zero_unary_fneg(double %x) {
661 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_zero_unary_fneg(
662 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ole double [[X:%.*]], 0.000000e+00
663 ; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
664 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LEZERO]], double [[NEGX]], double [[X]]
665 ; CHECK-NEXT: ret double [[FABS]]
667 %lezero = fcmp ole double %x, 0.0
668 %negx = fneg fast double %x
669 %fabs = select i1 %lezero, double %negx, double %x
673 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
675 define double @select_fcmp_nnan_nsz_ule_zero_unary_fneg(double %x) {
676 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_zero_unary_fneg(
677 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ule double [[X:%.*]], 0.000000e+00
678 ; CHECK-NEXT: [[NEGX:%.*]] = fneg fast double [[X]]
679 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[LEZERO]], double [[NEGX]], double [[X]]
680 ; CHECK-NEXT: ret double [[FABS]]
682 %lezero = fcmp ule double %x, 0.0
683 %negx = fneg fast double %x
684 %fabs = select i1 %lezero, double %negx, double %x
688 ; X <= -0.0 ? -X : X --> fabs(X)
690 define float @select_fcmp_nnan_nsz_ole_negzero(float %x) {
691 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_negzero(
692 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
693 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz float [[X]]
694 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LEZERO]], float [[NEGX]], float [[X]]
695 ; CHECK-NEXT: ret float [[FABS]]
697 %lezero = fcmp ole float %x, -0.0
698 %negx = fsub nnan nsz float -0.0, %x
699 %fabs = select i1 %lezero, float %negx, float %x
703 define float @select_nnan_nsz_fcmp_nnan_nsz_ole_negzero(float %x) {
704 ; CHECK-LABEL: @select_nnan_nsz_fcmp_nnan_nsz_ole_negzero(
705 ; CHECK-NEXT: [[FABS:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[X:%.*]])
706 ; CHECK-NEXT: ret float [[FABS]]
708 %lezero = fcmp ole float %x, -0.0
709 %negx = fsub nnan nsz float -0.0, %x
710 %fabs = select nnan nsz i1 %lezero, float %negx, float %x
714 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
716 define float @select_fcmp_nnan_nsz_ule_negzero(float %x) {
717 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_negzero(
718 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ule float [[X:%.*]], 0.000000e+00
719 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz float [[X]]
720 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LEZERO]], float [[NEGX]], float [[X]]
721 ; CHECK-NEXT: ret float [[FABS]]
723 %lezero = fcmp ule float %x, -0.0
724 %negx = fsub nnan nsz float -0.0, %x
725 %fabs = select i1 %lezero, float %negx, float %x
729 define float @select_fcmp_nnan_nsz_ole_negzero_unary_fneg(float %x) {
730 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ole_negzero_unary_fneg(
731 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
732 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz float [[X]]
733 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LEZERO]], float [[NEGX]], float [[X]]
734 ; CHECK-NEXT: ret float [[FABS]]
736 %lezero = fcmp ole float %x, -0.0
737 %negx = fneg nnan nsz float %x
738 %fabs = select i1 %lezero, float %negx, float %x
742 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
744 define float @select_fcmp_nnan_nsz_ule_negzero_unary_fneg(float %x) {
745 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ule_negzero_unary_fneg(
746 ; CHECK-NEXT: [[LEZERO:%.*]] = fcmp ule float [[X:%.*]], 0.000000e+00
747 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz float [[X]]
748 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[LEZERO]], float [[NEGX]], float [[X]]
749 ; CHECK-NEXT: ret float [[FABS]]
751 %lezero = fcmp ule float %x, -0.0
752 %negx = fneg nnan nsz float %x
753 %fabs = select i1 %lezero, float %negx, float %x
757 ; This is not fabs because that could produce a different signbit for a NAN input.
760 define <2 x float> @select_nsz_fcmp_ogt_zero_unary_fneg(<2 x float> %x) {
761 ; CHECK-LABEL: @select_nsz_fcmp_ogt_zero_unary_fneg(
762 ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer
763 ; CHECK-NEXT: [[NEGX:%.*]] = fneg <2 x float> [[X]]
764 ; CHECK-NEXT: [[FABS:%.*]] = select nsz <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
765 ; CHECK-NEXT: ret <2 x float> [[FABS]]
767 %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
768 %negx = fneg <2 x float> %x
769 %fabs = select nsz <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
770 ret <2 x float> %fabs
773 ; X > 0.0 ? X : (-X) --> fabs(X)
775 define <2 x float> @select_nsz_nnan_fcmp_ogt_zero_unary_fneg(<2 x float> %x) {
776 ; CHECK-LABEL: @select_nsz_nnan_fcmp_ogt_zero_unary_fneg(
777 ; CHECK-NEXT: [[FABS:%.*]] = call nnan nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
778 ; CHECK-NEXT: ret <2 x float> [[FABS]]
780 %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
781 %negx = fneg <2 x float> %x
782 %fabs = select nsz nnan <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
783 ret <2 x float> %fabs
786 define <2 x float> @select_fcmp_nnan_nsz_ogt_zero(<2 x float> %x) {
787 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_zero(
788 ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer
789 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
790 ; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
791 ; CHECK-NEXT: ret <2 x float> [[FABS]]
793 %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
794 %negx = fsub nnan nsz arcp <2 x float> <float -0.0, float -0.0>, %x
795 %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
796 ret <2 x float> %fabs
799 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
801 define <2 x float> @select_fcmp_nnan_nsz_ugt_zero(<2 x float> %x) {
802 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_zero(
803 ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ugt <2 x float> [[X:%.*]], zeroinitializer
804 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
805 ; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
806 ; CHECK-NEXT: ret <2 x float> [[FABS]]
808 %gtzero = fcmp ugt <2 x float> %x, zeroinitializer
809 %negx = fsub nnan nsz arcp <2 x float> <float -0.0, float -0.0>, %x
810 %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
811 ret <2 x float> %fabs
814 define <2 x float> @select_fcmp_nnan_nsz_ogt_zero_unary_fneg(<2 x float> %x) {
815 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_zero_unary_fneg(
816 ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer
817 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
818 ; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
819 ; CHECK-NEXT: ret <2 x float> [[FABS]]
821 %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
822 %negx = fneg nnan nsz arcp <2 x float> %x
823 %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
824 ret <2 x float> %fabs
827 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
829 define <2 x float> @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(<2 x float> %x) {
830 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(
831 ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ugt <2 x float> [[X:%.*]], zeroinitializer
832 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz arcp <2 x float> [[X]]
833 ; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GTZERO]], <2 x float> [[X]], <2 x float> [[NEGX]]
834 ; CHECK-NEXT: ret <2 x float> [[FABS]]
836 %gtzero = fcmp ugt <2 x float> %x, zeroinitializer
837 %negx = fneg nnan nsz arcp <2 x float> %x
838 %fabs = select <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
839 ret <2 x float> %fabs
842 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
844 define half @select_fcmp_nnan_nsz_ogt_negzero(half %x) {
845 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_negzero(
846 ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000
847 ; CHECK-NEXT: [[NEGX:%.*]] = fneg fast half [[X]]
848 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[GTZERO]], half [[X]], half [[NEGX]]
849 ; CHECK-NEXT: ret half [[FABS]]
851 %gtzero = fcmp ogt half %x, -0.0
852 %negx = fsub fast half 0.0, %x
853 %fabs = select i1 %gtzero, half %x, half %negx
857 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
859 define half @select_fcmp_nnan_nsz_ugt_negzero(half %x) {
860 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ugt_negzero(
861 ; CHECK-NEXT: [[GTZERO:%.*]] = fcmp ugt half [[X:%.*]], 0xH0000
862 ; CHECK-NEXT: [[NEGX:%.*]] = fneg fast half [[X]]
863 ; CHECK-NEXT: [[FABS:%.*]] = select nnan ninf i1 [[GTZERO]], half [[X]], half [[NEGX]]
864 ; CHECK-NEXT: ret half [[FABS]]
866 %gtzero = fcmp ugt half %x, -0.0
867 %negx = fsub fast half 0.0, %x
868 %fabs = select i1 %gtzero, half %x, half %negx
872 ; X > 0.0 ? X : (0.0 - X) --> fabs(X)
874 define <2 x double> @select_fcmp_nnan_nsz_oge_zero(<2 x double> %x) {
875 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_zero(
876 ; CHECK-NEXT: [[GEZERO:%.*]] = fcmp oge <2 x double> [[X:%.*]], zeroinitializer
877 ; CHECK-NEXT: [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
878 ; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
879 ; CHECK-NEXT: ret <2 x double> [[FABS]]
881 %gezero = fcmp oge <2 x double> %x, zeroinitializer
882 %negx = fsub nnan nsz reassoc <2 x double> <double -0.0, double -0.0>, %x
883 %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
884 ret <2 x double> %fabs
887 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
889 define <2 x double> @select_fcmp_nnan_nsz_uge_zero(<2 x double> %x) {
890 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_zero(
891 ; CHECK-NEXT: [[GEZERO:%.*]] = fcmp uge <2 x double> [[X:%.*]], zeroinitializer
892 ; CHECK-NEXT: [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
893 ; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
894 ; CHECK-NEXT: ret <2 x double> [[FABS]]
896 %gezero = fcmp uge <2 x double> %x, zeroinitializer
897 %negx = fsub nnan nsz reassoc <2 x double> <double -0.0, double -0.0>, %x
898 %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
899 ret <2 x double> %fabs
902 define <2 x double> @select_fcmp_nnan_nsz_oge_zero_unary_fneg(<2 x double> %x) {
903 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_zero_unary_fneg(
904 ; CHECK-NEXT: [[GEZERO:%.*]] = fcmp oge <2 x double> [[X:%.*]], zeroinitializer
905 ; CHECK-NEXT: [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
906 ; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
907 ; CHECK-NEXT: ret <2 x double> [[FABS]]
909 %gezero = fcmp oge <2 x double> %x, zeroinitializer
910 %negx = fneg nnan nsz reassoc <2 x double> %x
911 %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
912 ret <2 x double> %fabs
915 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
917 define <2 x double> @select_fcmp_nnan_nsz_uge_zero_unary_fneg(<2 x double> %x) {
918 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_zero_unary_fneg(
919 ; CHECK-NEXT: [[GEZERO:%.*]] = fcmp uge <2 x double> [[X:%.*]], zeroinitializer
920 ; CHECK-NEXT: [[NEGX:%.*]] = fneg reassoc nnan nsz <2 x double> [[X]]
921 ; CHECK-NEXT: [[FABS:%.*]] = select nnan <2 x i1> [[GEZERO]], <2 x double> [[X]], <2 x double> [[NEGX]]
922 ; CHECK-NEXT: ret <2 x double> [[FABS]]
924 %gezero = fcmp uge <2 x double> %x, zeroinitializer
925 %negx = fneg nnan nsz reassoc <2 x double> %x
926 %fabs = select <2 x i1> %gezero, <2 x double> %x, <2 x double> %negx
927 ret <2 x double> %fabs
930 ; X > -0.0 ? X : (0.0 - X) --> fabs(X)
932 define half @select_fcmp_nnan_nsz_oge_negzero(half %x) {
933 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_negzero(
934 ; CHECK-NEXT: [[GEZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
935 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz half [[X]]
936 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[GEZERO]], half [[X]], half [[NEGX]]
937 ; CHECK-NEXT: ret half [[FABS]]
939 %gezero = fcmp oge half %x, -0.0
940 %negx = fsub nnan nsz half -0.0, %x
941 %fabs = select i1 %gezero, half %x, half %negx
945 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
947 define half @select_fcmp_nnan_nsz_uge_negzero(half %x) {
948 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_negzero(
949 ; CHECK-NEXT: [[GEZERO:%.*]] = fcmp uge half [[X:%.*]], 0xH0000
950 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz half [[X]]
951 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[GEZERO]], half [[X]], half [[NEGX]]
952 ; CHECK-NEXT: ret half [[FABS]]
954 %gezero = fcmp uge half %x, -0.0
955 %negx = fsub nnan nsz half -0.0, %x
956 %fabs = select i1 %gezero, half %x, half %negx
960 define half @select_fcmp_nnan_nsz_oge_negzero_unary_fneg(half %x) {
961 ; CHECK-LABEL: @select_fcmp_nnan_nsz_oge_negzero_unary_fneg(
962 ; CHECK-NEXT: [[GEZERO:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
963 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz half [[X]]
964 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[GEZERO]], half [[X]], half [[NEGX]]
965 ; CHECK-NEXT: ret half [[FABS]]
967 %gezero = fcmp oge half %x, -0.0
968 %negx = fneg nnan nsz half %x
969 %fabs = select i1 %gezero, half %x, half %negx
973 ; Repeat with unordered predicate - nnan allows us to treat ordered/unordered identically.
975 define half @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(half %x) {
976 ; CHECK-LABEL: @select_fcmp_nnan_nsz_uge_negzero_unary_fneg(
977 ; CHECK-NEXT: [[GEZERO:%.*]] = fcmp uge half [[X:%.*]], 0xH0000
978 ; CHECK-NEXT: [[NEGX:%.*]] = fneg nnan nsz half [[X]]
979 ; CHECK-NEXT: [[FABS:%.*]] = select nnan i1 [[GEZERO]], half [[X]], half [[NEGX]]
980 ; CHECK-NEXT: ret half [[FABS]]
982 %gezero = fcmp uge half %x, -0.0
983 %negx = fneg nnan nsz half %x
984 %fabs = select i1 %gezero, half %x, half %negx
988 define float @select_fneg(i1 %c, float %x) {
989 ; CHECK-LABEL: @select_fneg(
990 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
991 ; CHECK-NEXT: ret float [[FABS]]
994 %s = select i1 %c, float %n, float %x
995 %fabs = call float @llvm.fabs.f32(float %s)
999 define float @select_fneg_use1(i1 %c, float %x) {
1000 ; CHECK-LABEL: @select_fneg_use1(
1001 ; CHECK-NEXT: [[N:%.*]] = fneg float [[X:%.*]]
1002 ; CHECK-NEXT: call void @use(float [[N]])
1003 ; CHECK-NEXT: [[FABS:%.*]] = call fast float @llvm.fabs.f32(float [[X]])
1004 ; CHECK-NEXT: ret float [[FABS]]
1007 call void @use(float %n)
1008 %s = select i1 %c, float %x, float %n
1009 %fabs = call fast float @llvm.fabs.f32(float %s)
1013 define float @select_fneg_use2(i1 %c, float %x) {
1014 ; CHECK-LABEL: @select_fneg_use2(
1015 ; CHECK-NEXT: [[N:%.*]] = fneg arcp float [[X:%.*]]
1016 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C:%.*]], float [[N]], float [[X]]
1017 ; CHECK-NEXT: call void @use(float [[S]])
1018 ; CHECK-NEXT: [[FABS:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[X]])
1019 ; CHECK-NEXT: ret float [[FABS]]
1021 %n = fneg arcp float %x
1022 %s = select i1 %c, float %n, float %x
1023 call void @use(float %s)
1024 %fabs = call nnan nsz float @llvm.fabs.f32(float %s)
1028 define <2 x float> @select_fneg_vec(<2 x i1> %c, <2 x float> %x) {
1029 ; CHECK-LABEL: @select_fneg_vec(
1030 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
1031 ; CHECK-NEXT: ret <2 x float> [[FABS]]
1033 %n = fneg <2 x float> %x
1034 %s = select fast <2 x i1> %c, <2 x float> %x, <2 x float> %n
1035 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %s)
1036 ret <2 x float> %fabs
1039 define float @test_select_neg_negx_x(float %value) {
1040 ; CHECK-LABEL: @test_select_neg_negx_x(
1041 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = call float @llvm.fabs.f32(float [[VALUE:%.*]])
1042 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1044 %a0 = bitcast float %value to i32
1045 %a1 = icmp slt i32 %a0, 0
1046 %fneg.i = fneg float %value
1047 %value.addr.0.i = select i1 %a1, float %fneg.i, float %value
1048 ret float %value.addr.0.i
1051 define float @test_select_nneg_negx_x(float %value) {
1052 ; CHECK-LABEL: @test_select_nneg_negx_x(
1053 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VALUE:%.*]])
1054 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = fneg float [[TMP1]]
1055 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1057 %a0 = bitcast float %value to i32
1058 %a1 = icmp sgt i32 %a0, -1
1059 %fneg.i = fneg float %value
1060 %value.addr.0.i = select i1 %a1, float %fneg.i, float %value
1061 ret float %value.addr.0.i
1064 define float @test_select_neg_x_negx(float %value) {
1065 ; CHECK-LABEL: @test_select_neg_x_negx(
1066 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VALUE:%.*]])
1067 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = fneg float [[TMP1]]
1068 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1070 %a0 = bitcast float %value to i32
1071 %a1 = icmp slt i32 %a0, 0
1072 %fneg.i = fneg float %value
1073 %value.addr.0.i = select i1 %a1, float %value, float %fneg.i
1074 ret float %value.addr.0.i
1077 define float @test_select_nneg_x_negx(float %value) {
1078 ; CHECK-LABEL: @test_select_nneg_x_negx(
1079 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = call float @llvm.fabs.f32(float [[VALUE:%.*]])
1080 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1082 %a0 = bitcast float %value to i32
1083 %a1 = icmp sgt i32 %a0, -1
1084 %fneg.i = fneg float %value
1085 %value.addr.0.i = select i1 %a1, float %value, float %fneg.i
1086 ret float %value.addr.0.i
1089 define float @test_select_neg_negx_x_multiuse1(float %value) {
1090 ; CHECK-LABEL: @test_select_neg_negx_x_multiuse1(
1091 ; CHECK-NEXT: [[A0:%.*]] = bitcast float [[VALUE:%.*]] to i32
1092 ; CHECK-NEXT: [[A1:%.*]] = icmp slt i32 [[A0]], 0
1093 ; CHECK-NEXT: call void @usebool(i1 [[A1]])
1094 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = call float @llvm.fabs.f32(float [[VALUE]])
1095 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1097 %a0 = bitcast float %value to i32
1098 %a1 = icmp slt i32 %a0, 0
1099 call void @usebool(i1 %a1)
1100 %fneg.i = fneg float %value
1101 %value.addr.0.i = select i1 %a1, float %fneg.i, float %value
1102 ret float %value.addr.0.i
1105 define float @test_select_neg_negx_x_multiuse2(float %value) {
1106 ; CHECK-LABEL: @test_select_neg_negx_x_multiuse2(
1107 ; CHECK-NEXT: [[FNEG_I:%.*]] = fneg float [[VALUE:%.*]]
1108 ; CHECK-NEXT: call void @use(float [[FNEG_I]])
1109 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = call float @llvm.fabs.f32(float [[VALUE]])
1110 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1112 %a0 = bitcast float %value to i32
1113 %a1 = icmp slt i32 %a0, 0
1114 %fneg.i = fneg float %value
1115 call void @use(float %fneg.i)
1116 %value.addr.0.i = select i1 %a1, float %fneg.i, float %value
1117 ret float %value.addr.0.i
1120 define float @test_select_neg_negx_x_multiuse3(float %value) {
1121 ; CHECK-LABEL: @test_select_neg_negx_x_multiuse3(
1122 ; CHECK-NEXT: [[A0:%.*]] = bitcast float [[VALUE:%.*]] to i32
1123 ; CHECK-NEXT: [[A1:%.*]] = icmp slt i32 [[A0]], 0
1124 ; CHECK-NEXT: call void @usebool(i1 [[A1]])
1125 ; CHECK-NEXT: [[FNEG_I:%.*]] = fneg float [[VALUE]]
1126 ; CHECK-NEXT: call void @use(float [[FNEG_I]])
1127 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = call float @llvm.fabs.f32(float [[VALUE]])
1128 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1130 %a0 = bitcast float %value to i32
1131 %a1 = icmp slt i32 %a0, 0
1132 call void @usebool(i1 %a1)
1133 %fneg.i = fneg float %value
1134 call void @use(float %fneg.i)
1135 %value.addr.0.i = select i1 %a1, float %fneg.i, float %value
1136 ret float %value.addr.0.i
1139 define float @test_select_neg_negx_x_fmf(float %value) {
1140 ; CHECK-LABEL: @test_select_neg_negx_x_fmf(
1141 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = call nnan ninf nsz float @llvm.fabs.f32(float [[VALUE:%.*]])
1142 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1144 %a0 = bitcast float %value to i32
1145 %a1 = icmp slt i32 %a0, 0
1146 %fneg.i = fneg float %value
1147 %value.addr.0.i = select nsz nnan ninf i1 %a1, float %fneg.i, float %value
1148 ret float %value.addr.0.i
1151 define float @test_select_nneg_negx_x_fmf(float %value) {
1152 ; CHECK-LABEL: @test_select_nneg_negx_x_fmf(
1153 ; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz float @llvm.fabs.f32(float [[VALUE:%.*]])
1154 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = fneg nnan ninf nsz float [[TMP1]]
1155 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1157 %a0 = bitcast float %value to i32
1158 %a1 = icmp sgt i32 %a0, -1
1159 %fneg.i = fneg float %value
1160 %value.addr.0.i = select nsz nnan ninf i1 %a1, float %fneg.i, float %value
1161 ret float %value.addr.0.i
1166 define float @test_select_nneg_negx_x_multiuse4(float %value) {
1167 ; CHECK-LABEL: @test_select_nneg_negx_x_multiuse4(
1168 ; CHECK-NEXT: [[A0:%.*]] = bitcast float [[VALUE:%.*]] to i32
1169 ; CHECK-NEXT: [[A1:%.*]] = icmp sgt i32 [[A0]], -1
1170 ; CHECK-NEXT: call void @usebool(i1 [[A1]])
1171 ; CHECK-NEXT: [[FNEG_I:%.*]] = fneg float [[VALUE]]
1172 ; CHECK-NEXT: call void @use(float [[FNEG_I]])
1173 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = select i1 [[A1]], float [[FNEG_I]], float [[VALUE]]
1174 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1176 %a0 = bitcast float %value to i32
1177 %a1 = icmp sgt i32 %a0, -1
1178 call void @usebool(i1 %a1)
1179 %fneg.i = fneg float %value
1180 call void @use(float %fneg.i)
1181 %value.addr.0.i = select i1 %a1, float %fneg.i, float %value
1182 ret float %value.addr.0.i
1185 define float @test_select_neg_negx_x_mismatched1(float %value, float %y) {
1186 ; CHECK-LABEL: @test_select_neg_negx_x_mismatched1(
1187 ; CHECK-NEXT: [[A0:%.*]] = bitcast float [[Y:%.*]] to i32
1188 ; CHECK-NEXT: [[A1:%.*]] = icmp slt i32 [[A0]], 0
1189 ; CHECK-NEXT: [[FNEG_I:%.*]] = fneg float [[VALUE:%.*]]
1190 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = select i1 [[A1]], float [[FNEG_I]], float [[VALUE]]
1191 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1193 %a0 = bitcast float %y to i32
1194 %a1 = icmp slt i32 %a0, 0
1195 %fneg.i = fneg float %value
1196 %value.addr.0.i = select i1 %a1, float %fneg.i, float %value
1197 ret float %value.addr.0.i
1200 define float @test_select_neg_negx_x_mismatched2(float %value, float %y) {
1201 ; CHECK-LABEL: @test_select_neg_negx_x_mismatched2(
1202 ; CHECK-NEXT: [[A0:%.*]] = bitcast float [[VALUE:%.*]] to i32
1203 ; CHECK-NEXT: [[A1:%.*]] = icmp slt i32 [[A0]], 0
1204 ; CHECK-NEXT: [[FNEG_I:%.*]] = fneg float [[Y:%.*]]
1205 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = select i1 [[A1]], float [[FNEG_I]], float [[VALUE]]
1206 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1208 %a0 = bitcast float %value to i32
1209 %a1 = icmp slt i32 %a0, 0
1210 %fneg.i = fneg float %y
1211 %value.addr.0.i = select i1 %a1, float %fneg.i, float %value
1212 ret float %value.addr.0.i
1215 define float @test_select_neg_negx_x_mismatched3(float %value, float %y) {
1216 ; CHECK-LABEL: @test_select_neg_negx_x_mismatched3(
1217 ; CHECK-NEXT: [[A0:%.*]] = bitcast float [[VALUE:%.*]] to i32
1218 ; CHECK-NEXT: [[A1:%.*]] = icmp slt i32 [[A0]], 0
1219 ; CHECK-NEXT: [[FNEG_I:%.*]] = fneg float [[VALUE]]
1220 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = select i1 [[A1]], float [[FNEG_I]], float [[Y:%.*]]
1221 ; CHECK-NEXT: ret float [[VALUE_ADDR_0_I]]
1223 %a0 = bitcast float %value to i32
1224 %a1 = icmp slt i32 %a0, 0
1225 %fneg.i = fneg float %value
1226 %value.addr.0.i = select i1 %a1, float %fneg.i, float %y
1227 ret float %value.addr.0.i
1230 define <2 x float> @test_select_neg_negx_x_wrong_type(<2 x float> %value) {
1231 ; CHECK-LABEL: @test_select_neg_negx_x_wrong_type(
1232 ; CHECK-NEXT: [[A0:%.*]] = bitcast <2 x float> [[VALUE:%.*]] to i64
1233 ; CHECK-NEXT: [[A1:%.*]] = icmp slt i64 [[A0]], 0
1234 ; CHECK-NEXT: [[FNEG_I:%.*]] = fneg <2 x float> [[VALUE]]
1235 ; CHECK-NEXT: [[VALUE_ADDR_0_I:%.*]] = select i1 [[A1]], <2 x float> [[FNEG_I]], <2 x float> [[VALUE]]
1236 ; CHECK-NEXT: ret <2 x float> [[VALUE_ADDR_0_I]]
1238 %a0 = bitcast <2 x float> %value to i64
1239 %a1 = icmp slt i64 %a0, 0
1240 %fneg.i = fneg <2 x float> %value
1241 %value.addr.0.i = select i1 %a1, <2 x float> %fneg.i, <2 x float> %value
1242 ret <2 x float> %value.addr.0.i