Skip to content

Commit b039a91

Browse files
committed
Fixes logic and update tests
1 parent 0abb2b7 commit b039a91

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
@@ -2666,6 +2666,22 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
26662666
return TryToNarrowDeduceFlags();
26672667
}
26682668

2669+
static FastMathFlags getCorrectFMFForFNeg(FastMathFlags F1, FastMathFlags F2) {
2670+
2671+
FastMathFlags NF1 = F1 & F2;
2672+
FastMathFlags NF2 = F1 | F2;
2673+
if (NF2.noNaNs())
2674+
return F2;
2675+
2676+
if (NF1.any() || (F1.none() && F2.none()))
2677+
return NF1;
2678+
2679+
if (F1.all() || F2.all())
2680+
return F2;
2681+
2682+
return NF1;
2683+
}
2684+
26692685
/// This eliminates floating-point negation in either 'fneg(X)' or
26702686
/// 'fsub(-0.0, X)' form by combining into a constant operand.
26712687
static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {
@@ -2683,11 +2699,11 @@ static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {
26832699
// -(X * C) --> X * (-C)
26842700
if (match(FNegOp, m_FMul(m_Value(X), m_Constant(C))))
26852701
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL)) {
2686-
if (match(C, m_AnyZeroFP()) && I.getFastMathFlags().noInfs()) {
2687-
return BinaryOperator::CreateFMulFMF(
2702+
FastMathFlags FMF = cast<FPMathOperator>(I.getOperand(0))->getFastMathFlags();
2703+
if (I.getFastMathFlags().noInfs()) {
2704+
return BinaryOperator::CreateFMulFMF(
26882705
X, NegC,
2689-
I.getFastMathFlags() &
2690-
cast<FPMathOperator>(I.getOperand(0))->getFastMathFlags());
2706+
getCorrectFMFForFNeg(I.getFastMathFlags(), FMF));
26912707
}
26922708
return BinaryOperator::CreateFMulFMF(X, NegC, &I);
26932709
}

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)