Skip to content

Commit 0abb2b7

Browse files
committed
[InstCombine] Ensure Safe Handling of Flags in foldFNegIntoConstant
1 parent 4399f2a commit 0abb2b7

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2682,8 +2682,15 @@ static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {
26822682
// Fold negation into constant operand.
26832683
// -(X * C) --> X * (-C)
26842684
if (match(FNegOp, m_FMul(m_Value(X), m_Constant(C))))
2685-
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
2685+
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL)) {
2686+
if (match(C, m_AnyZeroFP()) && I.getFastMathFlags().noInfs()) {
2687+
return BinaryOperator::CreateFMulFMF(
2688+
X, NegC,
2689+
I.getFastMathFlags() &
2690+
cast<FPMathOperator>(I.getOperand(0))->getFastMathFlags());
2691+
}
26862692
return BinaryOperator::CreateFMulFMF(X, NegC, &I);
2693+
}
26872694
// -(X / C) --> X / (-C)
26882695
if (match(FNegOp, m_FDiv(m_Value(X), m_Constant(C))))
26892696
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))

llvm/test/Transforms/InstCombine/fneg.ll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,4 +1109,45 @@ define float @test_fneg_select_maxnum(float %x) {
11091109
ret float %neg
11101110
}
11111111

1112+
define float @test_fneg_ninf_mul_with_anyzero(float %a) {
1113+
; CHECK-LABEL: @test_fneg_ninf_mul_with_anyzero(
1114+
; CHECK-NEXT: [[F:%.*]] = fmul float [[A:%.*]], -0.000000e+00
1115+
; CHECK-NEXT: ret float [[F]]
1116+
;
1117+
%mul = fmul float %a, 0.0
1118+
%f = fneg ninf float %mul
1119+
ret float %f
1120+
}
1121+
1122+
define float @test_fsub_ninf_mul_with_anyzero(float %a) {
1123+
; CHECK-LABEL: @test_fsub_ninf_mul_with_anyzero(
1124+
; CHECK-NEXT: [[F2:%.*]] = fmul float [[A:%.*]], -0.000000e+00
1125+
; CHECK-NEXT: ret float [[F2]]
1126+
;
1127+
%f1 = fmul float %a, 0.000000
1128+
%f2 = fsub ninf float -0.000000, %f1
1129+
ret float %f2
1130+
}
1131+
1132+
define float @test_fneg_nnan_mul_with_anyzero(float %a) {
1133+
; CHECK-LABEL: @test_fneg_nnan_mul_with_anyzero(
1134+
; CHECK-NEXT: [[TMP1:%.*]] = fneg nnan float [[A:%.*]]
1135+
; CHECK-NEXT: [[F2:%.*]] = call nnan float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]])
1136+
; CHECK-NEXT: ret float [[F2]]
1137+
;
1138+
%f1 = fmul float %a, 0.000000
1139+
%f2 = fneg nnan float %f1
1140+
ret float %f2
1141+
}
1142+
1143+
define float @test_fneg_nsz_mul_with_anyzero(float %a) {
1144+
; CHECK-LABEL: @test_fneg_nsz_mul_with_anyzero(
1145+
; CHECK-NEXT: [[F2:%.*]] = fmul nsz float [[A:%.*]], -0.000000e+00
1146+
; CHECK-NEXT: ret float [[F2]]
1147+
;
1148+
%f1 = fmul float %a, 0.000000
1149+
%f2 = fneg nsz float %f1
1150+
ret float %f2
1151+
}
1152+
11121153
!0 = !{}

0 commit comments

Comments
 (0)