Skip to content

Commit 0ade2ab

Browse files
committed
[InstCombine] fneg(X + C) --> -C - X
This is 1 of the potential folds uncovered by extending D72521. We don't seem to do this in the backend either (unless I'm not seeing some target-specific transform). icc and gcc (appears to be target-specific) do this transform. Differential Revision: https://reviews.llvm.org/D73057
1 parent dc69265 commit 0ade2ab

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,6 +2132,12 @@ static Instruction *foldFNegIntoConstant(Instruction &I) {
21322132
if (match(&I, m_FNeg(m_OneUse(m_FDiv(m_Constant(C), m_Value(X))))))
21332133
return BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I);
21342134

2135+
// With NSZ [ counter-example with -0.0: -(-0.0 + 0.0) != 0.0 + -0.0 ]:
2136+
// -(X + C) --> -X + -C --> -C - X
2137+
if (I.hasNoSignedZeros() &&
2138+
match(&I, m_FNeg(m_OneUse(m_FAdd(m_Value(X), m_Constant(C))))))
2139+
return BinaryOperator::CreateFSubFMF(ConstantExpr::getFNeg(C), X, &I);
2140+
21352141
return nullptr;
21362142
}
21372143

llvm/test/Transforms/InstCombine/fneg.ll

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ define float @fneg_fneg_sel_extra_use3(float %x, float %y, i1 %cond) {
378378
ret float %sel
379379
}
380380

381+
; Negative test
382+
381383
define float @fneg_fadd_constant(float %x) {
382384
; CHECK-LABEL: @fneg_fadd_constant(
383385
; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01
@@ -389,6 +391,8 @@ define float @fneg_fadd_constant(float %x) {
389391
ret float %r
390392
}
391393

394+
; Negative test
395+
392396
define float @fake_nsz_fadd_constant(float %x) {
393397
; CHECK-LABEL: @fake_nsz_fadd_constant(
394398
; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01
@@ -400,32 +404,32 @@ define float @fake_nsz_fadd_constant(float %x) {
400404
ret float %r
401405
}
402406

403-
; TODO: -(X + C) --> -C - X
407+
; -(X + C) --> -C - X
404408

405409
define float @fneg_nsz_fadd_constant(float %x) {
406410
; CHECK-LABEL: @fneg_nsz_fadd_constant(
407-
; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01
408-
; CHECK-NEXT: [[R:%.*]] = fneg nsz float [[A]]
411+
; CHECK-NEXT: [[R:%.*]] = fsub nsz float -4.200000e+01, [[X:%.*]]
409412
; CHECK-NEXT: ret float [[R]]
410413
;
411414
%a = fadd float %x, 42.0
412415
%r = fneg nsz float %a
413416
ret float %r
414417
}
415418

416-
; TODO: -(X + C) --> -C - X
419+
; -(X + C) --> -C - X
417420

418421
define float @fake_fneg_nsz_fadd_constant(float %x) {
419422
; CHECK-LABEL: @fake_fneg_nsz_fadd_constant(
420-
; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01
421-
; CHECK-NEXT: [[R:%.*]] = fsub fast float -0.000000e+00, [[A]]
423+
; CHECK-NEXT: [[R:%.*]] = fsub fast float -4.200000e+01, [[X:%.*]]
422424
; CHECK-NEXT: ret float [[R]]
423425
;
424426
%a = fadd float %x, 42.0
425427
%r = fsub fast float -0.0, %a
426428
ret float %r
427429
}
428430

431+
; Negative test
432+
429433
define float @fneg_nsz_fadd_constant_extra_use(float %x) {
430434
; CHECK-LABEL: @fneg_nsz_fadd_constant_extra_use(
431435
; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01
@@ -439,6 +443,8 @@ define float @fneg_nsz_fadd_constant_extra_use(float %x) {
439443
ret float %r
440444
}
441445

446+
; Negative test
447+
442448
define float @fake_fneg_nsz_fadd_constant_extra_use(float %x) {
443449
; CHECK-LABEL: @fake_fneg_nsz_fadd_constant_extra_use(
444450
; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01
@@ -452,28 +458,48 @@ define float @fake_fneg_nsz_fadd_constant_extra_use(float %x) {
452458
ret float %r
453459
}
454460

455-
; TODO: -(X + C) --> -C - X
461+
; -(X + C) --> -C - X
456462

457463
define <2 x float> @fneg_nsz_fadd_constant_vec(<2 x float> %x) {
458464
; CHECK-LABEL: @fneg_nsz_fadd_constant_vec(
459-
; CHECK-NEXT: [[A:%.*]] = fadd <2 x float> [[X:%.*]], <float 4.200000e+01, float 4.300000e+01>
460-
; CHECK-NEXT: [[R:%.*]] = fneg reassoc nnan nsz <2 x float> [[A]]
465+
; CHECK-NEXT: [[R:%.*]] = fsub reassoc nnan nsz <2 x float> <float -4.200000e+01, float -4.300000e+01>, [[X:%.*]]
461466
; CHECK-NEXT: ret <2 x float> [[R]]
462467
;
463468
%a = fadd <2 x float> %x, <float 42.0, float 43.0>
464469
%r = fneg nsz nnan reassoc <2 x float> %a
465470
ret <2 x float> %r
466471
}
467472

468-
; TODO: -(X + C) --> -C - X
473+
; -(X + C) --> -C - X
469474

470475
define <2 x float> @fake_fneg_nsz_fadd_constant_vec(<2 x float> %x) {
471476
; CHECK-LABEL: @fake_fneg_nsz_fadd_constant_vec(
472-
; CHECK-NEXT: [[A:%.*]] = fadd <2 x float> [[X:%.*]], <float 4.200000e+01, float undef>
473-
; CHECK-NEXT: [[R:%.*]] = fsub nsz <2 x float> <float undef, float -0.000000e+00>, [[A]]
477+
; CHECK-NEXT: [[R:%.*]] = fsub nsz <2 x float> <float -4.200000e+01, float undef>, [[X:%.*]]
474478
; CHECK-NEXT: ret <2 x float> [[R]]
475479
;
476480
%a = fadd <2 x float> %x, <float 42.0, float undef>
477481
%r = fsub nsz <2 x float> <float undef, float -0.0>, %a
478482
ret <2 x float> %r
479483
}
484+
485+
@g = external global i16, align 1
486+
487+
define float @fneg_nsz_fadd_constant_expr(float %x) {
488+
; CHECK-LABEL: @fneg_nsz_fadd_constant_expr(
489+
; CHECK-NEXT: [[R:%.*]] = fsub nsz float fneg (float bitcast (i32 ptrtoint (i16* @g to i32) to float)), [[X:%.*]]
490+
; CHECK-NEXT: ret float [[R]]
491+
;
492+
%a = fadd float %x, bitcast (i32 ptrtoint (i16* @g to i32) to float)
493+
%r = fneg nsz float %a
494+
ret float %r
495+
}
496+
497+
define float @fake_fneg_nsz_fadd_constant_expr(float %x) {
498+
; CHECK-LABEL: @fake_fneg_nsz_fadd_constant_expr(
499+
; CHECK-NEXT: [[R:%.*]] = fsub nsz float fneg (float bitcast (i32 ptrtoint (i16* @g to i32) to float)), [[X:%.*]]
500+
; CHECK-NEXT: ret float [[R]]
501+
;
502+
%a = fadd float %x, bitcast (i32 ptrtoint (i16* @g to i32) to float)
503+
%r = fsub nsz float -0.0, %a
504+
ret float %r
505+
}

0 commit comments

Comments
 (0)