forked from OSchip/llvm-project
[InstCombine] intersect nsz and ninf fast-math-flags (FMF) for fneg(fdiv) fold
https://alive2.llvm.org/ce/z/3KPvih https://llvm.org/PR49654
This commit is contained in:
parent
519e98cd9a
commit
4675beaa21
|
@ -2143,9 +2143,19 @@ static Instruction *foldFNegIntoConstant(Instruction &I) {
|
||||||
if (match(FNegOp, m_FDiv(m_Value(X), m_Constant(C))))
|
if (match(FNegOp, m_FDiv(m_Value(X), m_Constant(C))))
|
||||||
return BinaryOperator::CreateFDivFMF(X, ConstantExpr::getFNeg(C), &I);
|
return BinaryOperator::CreateFDivFMF(X, ConstantExpr::getFNeg(C), &I);
|
||||||
// -(C / X) --> (-C) / X
|
// -(C / X) --> (-C) / X
|
||||||
if (match(FNegOp, m_FDiv(m_Constant(C), m_Value(X))))
|
if (match(FNegOp, m_FDiv(m_Constant(C), m_Value(X)))) {
|
||||||
return BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I);
|
Instruction *FDiv =
|
||||||
|
BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I);
|
||||||
|
|
||||||
|
// Intersect 'nsz' and 'ninf' because those special value exceptions may not
|
||||||
|
// apply to the fdiv. Everything else propagates from the fneg.
|
||||||
|
// TODO: We could propagate nsz/ninf from fdiv alone?
|
||||||
|
FastMathFlags FMF = I.getFastMathFlags();
|
||||||
|
FastMathFlags OpFMF = FNegOp->getFastMathFlags();
|
||||||
|
FDiv->setHasNoSignedZeros(FMF.noSignedZeros() & OpFMF.noSignedZeros());
|
||||||
|
FDiv->setHasNoInfs(FMF.noInfs() & OpFMF.noInfs());
|
||||||
|
return FDiv;
|
||||||
|
}
|
||||||
// With NSZ [ counter-example with -0.0: -(-0.0 + 0.0) != 0.0 + -0.0 ]:
|
// With NSZ [ counter-example with -0.0: -(-0.0 + 0.0) != 0.0 + -0.0 ]:
|
||||||
// -(X + C) --> -X + -C --> -C - X
|
// -(X + C) --> -X + -C --> -C - X
|
||||||
if (I.hasNoSignedZeros() && match(FNegOp, m_FAdd(m_Value(X), m_Constant(C))))
|
if (I.hasNoSignedZeros() && match(FNegOp, m_FAdd(m_Value(X), m_Constant(C))))
|
||||||
|
|
|
@ -237,7 +237,7 @@ define float @fdiv_op0_constant_fneg_fast_fast(float %x) {
|
||||||
|
|
||||||
define float @fdiv_op0_constant_fneg_fast(float %x) {
|
define float @fdiv_op0_constant_fneg_fast(float %x) {
|
||||||
; CHECK-LABEL: @fdiv_op0_constant_fneg_fast(
|
; CHECK-LABEL: @fdiv_op0_constant_fneg_fast(
|
||||||
; CHECK-NEXT: [[R:%.*]] = fdiv fast float -4.200000e+01, [[X:%.*]]
|
; CHECK-NEXT: [[R:%.*]] = fdiv reassoc nnan arcp contract afn float -4.200000e+01, [[X:%.*]]
|
||||||
; CHECK-NEXT: ret float [[R]]
|
; CHECK-NEXT: ret float [[R]]
|
||||||
;
|
;
|
||||||
%d = fdiv float 42.0, %x
|
%d = fdiv float 42.0, %x
|
||||||
|
@ -257,7 +257,7 @@ define float @fdiv_op0_constant_fneg_nsz_nsz(float %x) {
|
||||||
|
|
||||||
define float @fdiv_op0_constant_fneg_nsz(float %x) {
|
define float @fdiv_op0_constant_fneg_nsz(float %x) {
|
||||||
; CHECK-LABEL: @fdiv_op0_constant_fneg_nsz(
|
; CHECK-LABEL: @fdiv_op0_constant_fneg_nsz(
|
||||||
; CHECK-NEXT: [[R:%.*]] = fdiv nsz float -4.200000e+01, [[X:%.*]]
|
; CHECK-NEXT: [[R:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]
|
||||||
; CHECK-NEXT: ret float [[R]]
|
; CHECK-NEXT: ret float [[R]]
|
||||||
;
|
;
|
||||||
%d = fdiv float 42.0, %x
|
%d = fdiv float 42.0, %x
|
||||||
|
@ -277,7 +277,7 @@ define float @fdiv_op0_constant_fneg_ninf_ninf(float %x) {
|
||||||
|
|
||||||
define float @fdiv_op0_constant_fneg_ninf(float %x) {
|
define float @fdiv_op0_constant_fneg_ninf(float %x) {
|
||||||
; CHECK-LABEL: @fdiv_op0_constant_fneg_ninf(
|
; CHECK-LABEL: @fdiv_op0_constant_fneg_ninf(
|
||||||
; CHECK-NEXT: [[R:%.*]] = fdiv ninf float -4.200000e+01, [[X:%.*]]
|
; CHECK-NEXT: [[R:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]
|
||||||
; CHECK-NEXT: ret float [[R]]
|
; CHECK-NEXT: ret float [[R]]
|
||||||
;
|
;
|
||||||
%d = fdiv float 42.0, %x
|
%d = fdiv float 42.0, %x
|
||||||
|
|
Loading…
Reference in New Issue