diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-08-29 18:27:49 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-08-29 18:27:49 +0000 |
commit | 0f29e953b74f6526ef8f283bfe0f372196780b8a (patch) | |
tree | 4798e1031e9cc6c5560b384d0c3a2e619a51bac7 /llvm/lib/Transforms | |
parent | f5403d83e79a608d02d89ccd829dd6b2ca7248af (diff) | |
download | bcm5719-llvm-0f29e953b74f6526ef8f283bfe0f372196780b8a.tar.gz bcm5719-llvm-0f29e953b74f6526ef8f283bfe0f372196780b8a.zip |
[InstCombine] canonicalize fneg with llvm.sin
This is a follow-up to rL339604 which did the same transform
for a sin libcall. The handling of intrinsics vs. libcalls
is unfortunately scattered, so I'm just adding this next to
the existing transform for llvm.cos for now.
This should resolve PR38458:
https://bugs.llvm.org/show_bug.cgi?id=38458
If the call was already negated, the negates will cancel
each other out.
llvm-svn: 340952
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 2993f0095a6..4755e8509b3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2124,16 +2124,25 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { } case Intrinsic::cos: case Intrinsic::amdgcn_cos: { - Value *SrcSrc; + Value *X; Value *Src = II->getArgOperand(0); - if (match(Src, m_FNeg(m_Value(SrcSrc))) || - match(Src, m_FAbs(m_Value(SrcSrc)))) { + if (match(Src, m_FNeg(m_Value(X))) || match(Src, m_FAbs(m_Value(X)))) { // cos(-x) -> cos(x) // cos(fabs(x)) -> cos(x) - II->setArgOperand(0, SrcSrc); + II->setArgOperand(0, X); return II; } - + break; + } + case Intrinsic::sin: { + Value *X; + if (match(II->getArgOperand(0), m_OneUse(m_FNeg(m_Value(X))))) { + // sin(-x) --> -sin(x) + Value *NewSin = Builder.CreateIntrinsic(Intrinsic::sin, { X }, II); + Instruction *FNeg = BinaryOperator::CreateFNeg(NewSin); + FNeg->copyFastMathFlags(II); + return FNeg; + } break; } case Intrinsic::ppc_altivec_lvx: |