diff options
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/BuildLibCalls.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 15 |
3 files changed, 48 insertions, 15 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; diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp index b60dfb4f354..d4cf03c326d 100644 --- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -709,6 +709,19 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { } } +bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, + LibFunc DoubleFn, LibFunc FloatFn, + LibFunc LongDoubleFn) { + switch (Ty->getTypeID()) { + case Type::FloatTyID: + return TLI->has(FloatFn); + case Type::DoubleTyID: + return TLI->has(DoubleFn); + default: + return TLI->has(LongDoubleFn); + } +} + //- Emit LibCalls ------------------------------------------------------------// Value *llvm::castToCStr(Value *V, IRBuilder<> &B) { diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 03a1d55ddc3..dcdff3e96b3 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -104,21 +104,6 @@ static bool callHasFloatingPointArgument(const CallInst *CI) { }); } -/// \brief Check whether the overloaded unary floating point function -/// corresponding to \a Ty is available. -static bool hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, - LibFunc DoubleFn, LibFunc FloatFn, - LibFunc LongDoubleFn) { - switch (Ty->getTypeID()) { - case Type::FloatTyID: - return TLI->has(FloatFn); - case Type::DoubleTyID: - return TLI->has(DoubleFn); - default: - return TLI->has(LongDoubleFn); - } -} - //===----------------------------------------------------------------------===// // String and Memory Library Call Optimizations //===----------------------------------------------------------------------===// |