forked from OSchip/llvm-project
[InstCombine] Avoid ConstantExpr::getFNeg() calls (NFCI)
Instead call the constant folding API, which can fail. For now, this should be NFC, as we still allow the creation of fneg constant expressions.
This commit is contained in:
parent
226086230c
commit
5eaeeed8cb
|
@ -2238,7 +2238,7 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
|
|||
|
||||
/// This eliminates floating-point negation in either 'fneg(X)' or
|
||||
/// 'fsub(-0.0, X)' form by combining into a constant operand.
|
||||
static Instruction *foldFNegIntoConstant(Instruction &I) {
|
||||
static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {
|
||||
// This is limited with one-use because fneg is assumed better for
|
||||
// reassociation and cheaper in codegen than fmul/fdiv.
|
||||
// TODO: Should the m_OneUse restriction be removed?
|
||||
|
@ -2252,28 +2252,31 @@ static Instruction *foldFNegIntoConstant(Instruction &I) {
|
|||
// Fold negation into constant operand.
|
||||
// -(X * C) --> X * (-C)
|
||||
if (match(FNegOp, m_FMul(m_Value(X), m_Constant(C))))
|
||||
return BinaryOperator::CreateFMulFMF(X, ConstantExpr::getFNeg(C), &I);
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
|
||||
return BinaryOperator::CreateFMulFMF(X, NegC, &I);
|
||||
// -(X / C) --> X / (-C)
|
||||
if (match(FNegOp, m_FDiv(m_Value(X), m_Constant(C))))
|
||||
return BinaryOperator::CreateFDivFMF(X, ConstantExpr::getFNeg(C), &I);
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
|
||||
return BinaryOperator::CreateFDivFMF(X, NegC, &I);
|
||||
// -(C / X) --> (-C) / X
|
||||
if (match(FNegOp, m_FDiv(m_Constant(C), m_Value(X)))) {
|
||||
Instruction *FDiv =
|
||||
BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I);
|
||||
if (match(FNegOp, m_FDiv(m_Constant(C), m_Value(X))))
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL)) {
|
||||
Instruction *FDiv = BinaryOperator::CreateFDivFMF(NegC, 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;
|
||||
}
|
||||
// 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 ]:
|
||||
// -(X + C) --> -X + -C --> -C - X
|
||||
if (I.hasNoSignedZeros() && match(FNegOp, m_FAdd(m_Value(X), m_Constant(C))))
|
||||
return BinaryOperator::CreateFSubFMF(ConstantExpr::getFNeg(C), X, &I);
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
|
||||
return BinaryOperator::CreateFSubFMF(NegC, X, &I);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2301,7 +2304,7 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
|
|||
getSimplifyQuery().getWithInstruction(&I)))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Instruction *X = foldFNegIntoConstant(I))
|
||||
if (Instruction *X = foldFNegIntoConstant(I, DL))
|
||||
return X;
|
||||
|
||||
Value *X, *Y;
|
||||
|
@ -2370,7 +2373,7 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
|
|||
if (match(&I, m_FNeg(m_Value(Op))))
|
||||
return UnaryOperator::CreateFNegFMF(Op, &I);
|
||||
|
||||
if (Instruction *X = foldFNegIntoConstant(I))
|
||||
if (Instruction *X = foldFNegIntoConstant(I, DL))
|
||||
return X;
|
||||
|
||||
if (Instruction *R = hoistFNegAboveFMulFDiv(I, Builder))
|
||||
|
@ -2409,7 +2412,8 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
|
|||
// But don't transform constant expressions because there's an inverse fold
|
||||
// for X + (-Y) --> X - Y.
|
||||
if (match(Op1, m_ImmConstant(C)))
|
||||
return BinaryOperator::CreateFAddFMF(Op0, ConstantExpr::getFNeg(C), &I);
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
|
||||
return BinaryOperator::CreateFAddFMF(Op0, NegC, &I);
|
||||
|
||||
// X - (-Y) --> X + Y
|
||||
if (match(Op1, m_FNeg(m_Value(Y))))
|
||||
|
|
|
@ -6866,10 +6866,9 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
|
|||
if (match(Op0, m_FNeg(m_Value(X)))) {
|
||||
// fcmp pred (fneg X), C --> fcmp swap(pred) X, -C
|
||||
Constant *C;
|
||||
if (match(Op1, m_Constant(C))) {
|
||||
Constant *NegC = ConstantExpr::getFNeg(C);
|
||||
return new FCmpInst(I.getSwappedPredicate(), X, NegC, "", &I);
|
||||
}
|
||||
if (match(Op1, m_Constant(C)))
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
|
||||
return new FCmpInst(I.getSwappedPredicate(), X, NegC, "", &I);
|
||||
}
|
||||
|
||||
if (match(Op0, m_FPExt(m_Value(X)))) {
|
||||
|
|
|
@ -492,7 +492,8 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
|
|||
Value *X, *Y;
|
||||
Constant *C;
|
||||
if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_Constant(C)))
|
||||
return BinaryOperator::CreateFMulFMF(X, ConstantExpr::getFNeg(C), &I);
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
|
||||
return BinaryOperator::CreateFMulFMF(X, NegC, &I);
|
||||
|
||||
// (select A, B, C) * (select A, D, E) --> select A, (B*D), (C*E)
|
||||
if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
|
||||
|
@ -1226,8 +1227,10 @@ static Instruction *foldFDivConstantDivisor(BinaryOperator &I) {
|
|||
|
||||
// -X / C --> X / -C
|
||||
Value *X;
|
||||
const DataLayout &DL = I.getModule()->getDataLayout();
|
||||
if (match(I.getOperand(0), m_FNeg(m_Value(X))))
|
||||
return BinaryOperator::CreateFDivFMF(X, ConstantExpr::getFNeg(C), &I);
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
|
||||
return BinaryOperator::CreateFDivFMF(X, NegC, &I);
|
||||
|
||||
// If the constant divisor has an exact inverse, this is always safe. If not,
|
||||
// then we can still create a reciprocal if fast-math-flags allow it and the
|
||||
|
@ -1239,7 +1242,6 @@ static Instruction *foldFDivConstantDivisor(BinaryOperator &I) {
|
|||
// on all targets.
|
||||
// TODO: Use Intrinsic::canonicalize or let function attributes tell us that
|
||||
// denorms are flushed?
|
||||
const DataLayout &DL = I.getModule()->getDataLayout();
|
||||
auto *RecipC = ConstantFoldBinaryOpOperands(
|
||||
Instruction::FDiv, ConstantFP::get(I.getType(), 1.0), C, DL);
|
||||
if (!RecipC || !RecipC->isNormalFP())
|
||||
|
@ -1257,15 +1259,16 @@ static Instruction *foldFDivConstantDividend(BinaryOperator &I) {
|
|||
|
||||
// C / -X --> -C / X
|
||||
Value *X;
|
||||
const DataLayout &DL = I.getModule()->getDataLayout();
|
||||
if (match(I.getOperand(1), m_FNeg(m_Value(X))))
|
||||
return BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I);
|
||||
if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
|
||||
return BinaryOperator::CreateFDivFMF(NegC, X, &I);
|
||||
|
||||
if (!I.hasAllowReassoc() || !I.hasAllowReciprocal())
|
||||
return nullptr;
|
||||
|
||||
// Try to reassociate C / X expressions where X includes another constant.
|
||||
Constant *C2, *NewC = nullptr;
|
||||
const DataLayout &DL = I.getModule()->getDataLayout();
|
||||
if (match(I.getOperand(1), m_FMul(m_Value(X), m_Constant(C2)))) {
|
||||
// C / (X * C2) --> (C / C2) / X
|
||||
NewC = ConstantFoldBinaryOpOperands(Instruction::FDiv, C, C2, DL);
|
||||
|
|
Loading…
Reference in New Issue