diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 22 | 
1 files changed, 22 insertions, 0 deletions
| diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 328c5021967..9c1c0c93480 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1900,6 +1900,22 @@ static Instruction *foldFNegIntoConstant(Instruction &I) {    return nullptr;  } +static Instruction *hoistFNegAboveFMulFDiv(Instruction &I, +                                           InstCombiner::BuilderTy &Builder) { +  Value *FNeg; +  if (!match(&I, m_FNeg(m_Value(FNeg)))) +    return nullptr; + +  Value *X, *Y; +  if (match(FNeg, m_OneUse(m_FMul(m_Value(X), m_Value(Y))))) +    return BinaryOperator::CreateFMulFMF(Builder.CreateFNegFMF(X, &I), Y, &I); + +  if (match(FNeg, m_OneUse(m_FDiv(m_Value(X), m_Value(Y))))) +    return BinaryOperator::CreateFDivFMF(Builder.CreateFNegFMF(X, &I), Y, &I); + +  return nullptr; +} +  Instruction *InstCombiner::visitFNeg(UnaryOperator &I) {    Value *Op = I.getOperand(0); @@ -1917,6 +1933,9 @@ Instruction *InstCombiner::visitFNeg(UnaryOperator &I) {        match(Op, m_OneUse(m_FSub(m_Value(X), m_Value(Y)))))      return BinaryOperator::CreateFSubFMF(Y, X, &I); +  if (Instruction *R = hoistFNegAboveFMulFDiv(I, Builder)) +    return R; +    return nullptr;  } @@ -1938,6 +1957,9 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) {    if (Instruction *X = foldFNegIntoConstant(I))      return X; +  if (Instruction *R = hoistFNegAboveFMulFDiv(I, Builder)) +    return R; +    Value *X, *Y;    Constant *C; | 

