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))
// (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
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);
}
// 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);
+ }
}
}
// 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)
// 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.