diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 38604830b88..8abed5c14cb 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -33,6 +33,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/KnownBits.h" #include "llvm/Transforms/InstCombine/InstCombineWorklist.h" +#include "llvm/Transforms/Utils/BuildLibCalls.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -1468,6 +1469,40 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { } } + if (AllowReassociate && + Op0->hasOneUse() && Op1->hasOneUse()) { + Value *A; + // sin(a) / cos(a) -> tan(a) + if (match(Op0, m_Intrinsic<Intrinsic::sin>(m_Value(A))) && + match(Op1, m_Intrinsic<Intrinsic::cos>(m_Specific(A)))) { + if (hasUnaryFloatFn(&TLI, I.getType(), LibFunc_tan, + LibFunc_tanf, LibFunc_tanl)) { + IRBuilder<> B(&I); + IRBuilder<>::FastMathFlagGuard Guard(B); + B.setFastMathFlags(I.getFastMathFlags()); + Value *Tan = emitUnaryFloatFnCall(A, TLI.getName(LibFunc_tan), + B, I.getFunction()->getAttributes()); + return replaceInstUsesWith(I, Tan); + } + } + + // cos(a) / sin(a) -> 1/tan(a) + if (match(Op0, m_Intrinsic<Intrinsic::cos>(m_Value(A))) && + match(Op1, m_Intrinsic<Intrinsic::sin>(m_Specific(A)))) { + if (hasUnaryFloatFn(&TLI, I.getType(), LibFunc_tan, + LibFunc_tanf, LibFunc_tanl)) { + IRBuilder<> B(&I); + IRBuilder<>::FastMathFlagGuard Guard(B); + B.setFastMathFlags(I.getFastMathFlags()); + Value *Tan = emitUnaryFloatFnCall(A, TLI.getName(LibFunc_tan), + B, I.getFunction()->getAttributes()); + Value *One = ConstantFP::get(Tan->getType(), 1.0); + Value *Div = B.CreateFDiv(One, Tan); + return replaceInstUsesWith(I, Div); + } + } + } + Value *LHS; Value *RHS; |