Skip to content

Commit 0bf11f0

Browse files
committed
Fixes logic and update tests
1 parent 9a1e5b0 commit 0bf11f0

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,6 +2741,22 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
27412741
return TryToNarrowDeduceFlags();
27422742
}
27432743

2744+
static FastMathFlags getCorrectFMFForFNeg(FastMathFlags F1, FastMathFlags F2) {
2745+
2746+
FastMathFlags NF1 = F1 & F2;
2747+
FastMathFlags NF2 = F1 | F2;
2748+
if (NF2.noNaNs())
2749+
return F2;
2750+
2751+
if (NF1.any() || (F1.none() && F2.none()))
2752+
return NF1;
2753+
2754+
if (F1.all() || F2.all())
2755+
return F2;
2756+
2757+
return NF1;
2758+
}
2759+
27442760
/// This eliminates floating-point negation in either 'fneg(X)' or
27452761
/// 'fsub(-0.0, X)' form by combining into a constant operand.
27462762
static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {
@@ -2758,11 +2774,11 @@ static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {
27582774
// -(X * C) --> X * (-C)
27592775
if (match(FNegOp, m_FMul(m_Value(X), m_Constant(C))))
27602776
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL)) {
2761-
if (match(C, m_AnyZeroFP()) && I.getFastMathFlags().noInfs()) {
2762-
return BinaryOperator::CreateFMulFMF(
2777+
FastMathFlags FMF = cast<FPMathOperator>(I.getOperand(0))->getFastMathFlags();
2778+
if (I.getFastMathFlags().noInfs()) {
2779+
return BinaryOperator::CreateFMulFMF(
27632780
X, NegC,
2764-
I.getFastMathFlags() &
2765-
cast<FPMathOperator>(I.getOperand(0))->getFastMathFlags());
2781+
getCorrectFMFForFNeg(I.getFastMathFlags(), FMF));
27662782
}
27672783
return BinaryOperator::CreateFMulFMF(X, NegC, &I);
27682784
}

llvm/test/Transforms/InstCombine/fneg.ll

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,4 +1150,46 @@ define float @test_fneg_nsz_mul_with_anyzero(float %a) {
11501150
ret float %f2
11511151
}
11521152

1153+
define float @test_fneg_ninf_mul_nnan_with_const(float %a) {
1154+
; CHECK-LABEL: @test_fneg_ninf_mul_nnan_with_const(
1155+
; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[A:%.*]]
1156+
; CHECK-NEXT: [[F2:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]])
1157+
; CHECK-NEXT: ret float [[F2]]
1158+
;
1159+
%f1 = fmul nnan float %a, 0.000000
1160+
%f2 = fneg ninf float %f1
1161+
ret float %f2
1162+
}
1163+
1164+
define float @test_fneg_ninf_mul_nsz_with_const(float %a) {
1165+
; CHECK-LABEL: @test_fneg_ninf_mul_nsz_with_const(
1166+
; CHECK-NEXT: [[F2:%.*]] = fmul float [[A:%.*]], -0.000000e+00
1167+
; CHECK-NEXT: ret float [[F2]]
1168+
;
1169+
%f1 = fmul nsz float %a, 0.000000
1170+
%f2 = fneg ninf float %f1
1171+
ret float %f2
1172+
}
1173+
1174+
define <2 x float> @test_fneg_ninf_mul_nnan_with_vec_const(<2 x float> %a) {
1175+
; CHECK-LABEL: @test_fneg_ninf_mul_nnan_with_vec_const(
1176+
; CHECK-NEXT: [[F2:%.*]] = fmul nnan <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>
1177+
; CHECK-NEXT: ret <2 x float> [[F2]]
1178+
;
1179+
%f1 = fmul nnan <2 x float> %a, <float 0.000000, float -0.000000>
1180+
%f2 = fneg ninf <2 x float> %f1
1181+
ret <2 x float> %f2
1182+
}
1183+
1184+
define <2 x float> @test_fneg_ninf_mul_nsz_with_vec_const(<2 x float> %a) {
1185+
; CHECK-LABEL: @test_fneg_ninf_mul_nsz_with_vec_const(
1186+
; CHECK-NEXT: [[F2:%.*]] = fmul <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>
1187+
; CHECK-NEXT: ret <2 x float> [[F2]]
1188+
;
1189+
%f1 = fmul nsz <2 x float> %a, <float 0.000000, float -0.000000>
1190+
%f2 = fneg ninf <2 x float> %f1
1191+
ret <2 x float> %f2
1192+
}
1193+
1194+
11531195
!0 = !{}

0 commit comments

Comments
 (0)