1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00

[InstCombine] simplify code for (X*Y) * X => (X*X) * Y ; NFCI

llvm-svn: 326444
This commit is contained in:
Sanjay Patel 2018-03-01 15:50:26 +00:00
parent cdc519913d
commit 458f1ce52a

View File

@ -669,42 +669,24 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
return replaceInstUsesWith(I, V);
// Handle symmetric situation in a 2-iteration loop
Value *Opnd0 = Op0;
Value *Opnd1 = Op1;
for (int i = 0; i < 2; i++) {
// (X*Y) * X => (X*X) * Y where Y != X
// The purpose is two-fold:
// 1) to form a power expression (of X).
// 2) potentially shorten the critical path: After transformation, the
// latency of the instruction Y is amortized by the expression of X*X,
// and therefore Y is in a "less critical" position compared to what it
// was before the transformation.
if (AllowReassociate) {
Value *Opnd0_0, *Opnd0_1;
if (Opnd0->hasOneUse() &&
match(Opnd0, m_FMul(m_Value(Opnd0_0), m_Value(Opnd0_1)))) {
Value *Y = nullptr;
if (Opnd0_0 == Opnd1 && Opnd0_1 != Opnd1)
Y = Opnd0_1;
else if (Opnd0_1 == Opnd1 && Opnd0_0 != Opnd1)
Y = Opnd0_0;
if (Y) {
BuilderTy::FastMathFlagGuard Guard(Builder);
Builder.setFastMathFlags(I.getFastMathFlags());
Value *T = Builder.CreateFMul(Opnd1, Opnd1);
Value *R = Builder.CreateFMul(T, Y);
R->takeName(&I);
return replaceInstUsesWith(I, R);
}
}
// (X*Y) * X => (X*X) * Y where Y != X
// The purpose is two-fold:
// 1) to form a power expression (of X).
// 2) potentially shorten the critical path: After transformation, the
// latency of the instruction Y is amortized by the expression of X*X,
// and therefore Y is in a "less critical" position compared to what it
// was before the transformation.
if (I.isFast()) {
if (match(Op0, m_OneUse(m_c_FMul(m_Specific(Op1), m_Value(Y)))) &&
Op1 != Y) {
Value *XX = Builder.CreateFMulFMF(Op1, Op1, &I);
return BinaryOperator::CreateFMulFMF(XX, Y, &I);
}
if (match(Op1, m_OneUse(m_c_FMul(m_Specific(Op0), m_Value(Y)))) &&
Op0 != Y) {
Value *XX = Builder.CreateFMulFMF(Op0, Op0, &I);
return BinaryOperator::CreateFMulFMF(XX, Y, &I);
}
if (!isa<Constant>(Op1))
std::swap(Opnd0, Opnd1);
else
break;
}
return Changed ? &I : nullptr;