aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-07-08 16:04:21 +0200
committerNikita Popov <npopov@redhat.com>2022-07-08 16:36:04 +0200
commitfc18a88231ccca7c5e93f7563e44fd636833ed2c (patch)
treed0eb41d251ea1d937263aca3860cb41b817d373f /llvm/lib
parent79bb915fb60b2cd220d89e3bb54f67abb8cdb7bd (diff)
downloadllvm-fc18a88231ccca7c5e93f7563e44fd636833ed2c.zip
llvm-fc18a88231ccca7c5e93f7563e44fd636833ed2c.tar.gz
llvm-fc18a88231ccca7c5e93f7563e44fd636833ed2c.tar.bz2
[InstCombine] Avoid creating float binop ConstantExprs
Replace ConstantExpr:getFAdd etc with call to ConstantFoldBinaryOpOperands(). I'm using the constant folding API rather than IRBuilder here to ensure that this does actually constant fold. These transforms don't use m_ImmConstant(), so this would not otherwise be guaranteed (and apparently, they can't use m_ImmConstant because they want to handle scalable vector splats). There is an opportunity here to further migrate these to the ConstantFoldFPInstOperands() API, which would respect the denormal mode. I've held off on doing so here, because some of this code explicitly checks for denormal results, and I don't want to touch it in a mostly NFC change.
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp15
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp42
2 files changed, 35 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 01821a7..535a773 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1660,8 +1660,9 @@ Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {
Constant *MulC;
if (match(&I, m_c_FAdd(m_FMul(m_Value(X), m_ImmConstant(MulC)),
m_Deferred(X)))) {
- MulC = ConstantExpr::getFAdd(MulC, ConstantFP::get(I.getType(), 1.0));
- return BinaryOperator::CreateFMulFMF(X, MulC, &I);
+ if (Constant *NewMulC = ConstantFoldBinaryOpOperands(
+ Instruction::FAdd, MulC, ConstantFP::get(I.getType(), 1.0), DL))
+ return BinaryOperator::CreateFMulFMF(X, NewMulC, &I);
}
if (Value *V = FAddCombine(Builder).simplify(&I))
@@ -2453,13 +2454,15 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
// (X * C) - X --> X * (C - 1.0)
if (match(Op0, m_FMul(m_Specific(Op1), m_Constant(C)))) {
- Constant *CSubOne = ConstantExpr::getFSub(C, ConstantFP::get(Ty, 1.0));
- return BinaryOperator::CreateFMulFMF(Op1, CSubOne, &I);
+ if (Constant *CSubOne = ConstantFoldBinaryOpOperands(
+ Instruction::FSub, C, ConstantFP::get(Ty, 1.0), DL))
+ return BinaryOperator::CreateFMulFMF(Op1, CSubOne, &I);
}
// X - (X * C) --> X * (1.0 - C)
if (match(Op1, m_FMul(m_Specific(Op0), m_Constant(C)))) {
- Constant *OneSubC = ConstantExpr::getFSub(ConstantFP::get(Ty, 1.0), C);
- return BinaryOperator::CreateFMulFMF(Op0, OneSubC, &I);
+ if (Constant *OneSubC = ConstantFoldBinaryOpOperands(
+ Instruction::FSub, ConstantFP::get(Ty, 1.0), C, DL))
+ return BinaryOperator::CreateFMulFMF(Op0, OneSubC, &I);
}
// Reassociate fsub/fadd sequences to create more fadd instructions and
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 2a34edb..8cb09cb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -505,20 +505,23 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
Constant *C1;
if (match(Op0, m_OneUse(m_FDiv(m_Constant(C1), m_Value(X))))) {
// (C1 / X) * C --> (C * C1) / X
- Constant *CC1 = ConstantExpr::getFMul(C, C1);
- if (CC1->isNormalFP())
+ Constant *CC1 =
+ ConstantFoldBinaryOpOperands(Instruction::FMul, C, C1, DL);
+ if (CC1 && CC1->isNormalFP())
return BinaryOperator::CreateFDivFMF(CC1, X, &I);
}
if (match(Op0, m_FDiv(m_Value(X), m_Constant(C1)))) {
// (X / C1) * C --> X * (C / C1)
- Constant *CDivC1 = ConstantExpr::getFDiv(C, C1);
- if (CDivC1->isNormalFP())
+ Constant *CDivC1 =
+ ConstantFoldBinaryOpOperands(Instruction::FDiv, C, C1, DL);
+ if (CDivC1 && CDivC1->isNormalFP())
return BinaryOperator::CreateFMulFMF(X, CDivC1, &I);
// If the constant was a denormal, try reassociating differently.
// (X / C1) * C --> X / (C1 / C)
- Constant *C1DivC = ConstantExpr::getFDiv(C1, C);
- if (Op0->hasOneUse() && C1DivC->isNormalFP())
+ Constant *C1DivC =
+ ConstantFoldBinaryOpOperands(Instruction::FDiv, C1, C, DL);
+ if (C1DivC && Op0->hasOneUse() && C1DivC->isNormalFP())
return BinaryOperator::CreateFDivFMF(X, C1DivC, &I);
}
@@ -527,15 +530,19 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
// further folds and (X * C) + C2 is 'fma'.
if (match(Op0, m_OneUse(m_FAdd(m_Value(X), m_Constant(C1))))) {
// (X + C1) * C --> (X * C) + (C * C1)
- Constant *CC1 = ConstantExpr::getFMul(C, C1);
- Value *XC = Builder.CreateFMulFMF(X, C, &I);
- return BinaryOperator::CreateFAddFMF(XC, CC1, &I);
+ if (Constant *CC1 = ConstantFoldBinaryOpOperands(
+ Instruction::FMul, C, C1, DL)) {
+ Value *XC = Builder.CreateFMulFMF(X, C, &I);
+ return BinaryOperator::CreateFAddFMF(XC, CC1, &I);
+ }
}
if (match(Op0, m_OneUse(m_FSub(m_Constant(C1), m_Value(X))))) {
// (C1 - X) * C --> (C * C1) - (X * C)
- Constant *CC1 = ConstantExpr::getFMul(C, C1);
- Value *XC = Builder.CreateFMulFMF(X, C, &I);
- return BinaryOperator::CreateFSubFMF(CC1, XC, &I);
+ if (Constant *CC1 = ConstantFoldBinaryOpOperands(
+ Instruction::FMul, C, C1, DL)) {
+ Value *XC = Builder.CreateFMulFMF(X, C, &I);
+ return BinaryOperator::CreateFSubFMF(CC1, XC, &I);
+ }
}
}
@@ -1232,8 +1239,10 @@ static Instruction *foldFDivConstantDivisor(BinaryOperator &I) {
// on all targets.
// TODO: Use Intrinsic::canonicalize or let function attributes tell us that
// denorms are flushed?
- auto *RecipC = ConstantExpr::getFDiv(ConstantFP::get(I.getType(), 1.0), C);
- if (!RecipC->isNormalFP())
+ const DataLayout &DL = I.getModule()->getDataLayout();
+ auto *RecipC = ConstantFoldBinaryOpOperands(
+ Instruction::FDiv, ConstantFP::get(I.getType(), 1.0), C, DL);
+ if (!RecipC || !RecipC->isNormalFP())
return nullptr;
// X / C --> X * (1 / C)
@@ -1256,12 +1265,13 @@ static Instruction *foldFDivConstantDividend(BinaryOperator &I) {
// 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 = ConstantExpr::getFDiv(C, C2);
+ NewC = ConstantFoldBinaryOpOperands(Instruction::FDiv, C, C2, DL);
} else if (match(I.getOperand(1), m_FDiv(m_Value(X), m_Constant(C2)))) {
// C / (X / C2) --> (C * C2) / X
- NewC = ConstantExpr::getFMul(C, C2);
+ NewC = ConstantFoldBinaryOpOperands(Instruction::FMul, C, C2, DL);
}
// Disallow denormal constants because we don't know what would happen
// on all targets.