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:
parent
cdc519913d
commit
458f1ce52a
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user