diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 20 | 
1 files changed, 20 insertions, 0 deletions
| diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index ba15b023f2a..891370e2c76 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1308,6 +1308,22 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {    return Changed ? &I : nullptr;  } +/// Eliminate an op from a linear interpolation (lerp) pattern. +static Instruction *factorizeLerp(BinaryOperator &I, +                                  InstCombiner::BuilderTy &Builder) { +  Value *X, *Y, *Z; +  if (!match(&I, m_c_FAdd(m_OneUse(m_c_FMul(m_Value(Y), +                                            m_OneUse(m_FSub(m_FPOne(), +                                                            m_Value(Z))))), +                          m_OneUse(m_c_FMul(m_Value(X), m_Deferred(Z)))))) +    return nullptr; + +  // (Y * (1.0 - Z)) + (X * Z) --> Y + Z * (X - Y) [8 commuted variants] +  Value *XY = Builder.CreateFSubFMF(X, Y, &I); +  Value *MulZ = Builder.CreateFMulFMF(Z, XY, &I); +  return BinaryOperator::CreateFAddFMF(Y, MulZ, &I); +} +  /// Factor a common operand out of fadd/fsub of fmul/fdiv.  static Instruction *factorizeFAddFSub(BinaryOperator &I,                                        InstCombiner::BuilderTy &Builder) { @@ -1315,6 +1331,10 @@ static Instruction *factorizeFAddFSub(BinaryOperator &I,            I.getOpcode() == Instruction::FSub) && "Expecting fadd/fsub");    assert(I.hasAllowReassoc() && I.hasNoSignedZeros() &&           "FP factorization requires FMF"); + +  if (Instruction *Lerp = factorizeLerp(I, Builder)) +    return Lerp; +    Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);    Value *X, *Y, *Z;    bool IsFMul; | 

