diff options
author | Volkan Keles <vkeles@apple.com> | 2018-10-31 17:50:52 +0000 |
---|---|---|
committer | Volkan Keles <vkeles@apple.com> | 2018-10-31 17:50:52 +0000 |
commit | 3ca146d08315ca197686b9f251c131295b812139 (patch) | |
tree | df428b7226bb96035b513359fcef83ea7d2df82c /llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | |
parent | 9e64a4c152a0a0287b1d104bc175da33326da56c (diff) | |
download | bcm5719-llvm-3ca146d08315ca197686b9f251c131295b812139.tar.gz bcm5719-llvm-3ca146d08315ca197686b9f251c131295b812139.zip |
[InstCombine] Combine nested min/max intrinsics with constants
Reviewers: arsenm, spatel
Reviewed By: spatel
Subscribers: lebedev.ri, wdng, llvm-commits
Differential Revision: https://reviews.llvm.org/D53774
llvm-svn: 345751
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 116b11386f0..bdd9a43be27 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2032,6 +2032,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { return II; } + Intrinsic::ID IID = II->getIntrinsicID(); Value *X, *Y; if (match(Arg0, m_FNeg(m_Value(X))) && match(Arg1, m_FNeg(m_Value(Y))) && (Arg0->hasOneUse() || Arg1->hasOneUse())) { @@ -2039,7 +2040,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // min(-X, -Y) --> -(max(X, Y)) // max(-X, -Y) --> -(min(X, Y)) Intrinsic::ID NewIID; - switch (II->getIntrinsicID()) { + switch (IID) { case Intrinsic::maxnum: NewIID = Intrinsic::minnum; break; @@ -2060,6 +2061,39 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { FNeg->copyIRFlags(II); return FNeg; } + + // m(m(X, C2), C1) -> m(X, C) + const APFloat *C1, *C2; + if (auto *M = dyn_cast<IntrinsicInst>(Arg0)) { + if (M->getIntrinsicID() == IID && match(Arg1, m_APFloat(C1)) && + ((match(M->getArgOperand(0), m_Value(X)) && + match(M->getArgOperand(1), m_APFloat(C2))) || + (match(M->getArgOperand(1), m_Value(X)) && + match(M->getArgOperand(0), m_APFloat(C2))))) { + APFloat Res(0.0); + switch (IID) { + case Intrinsic::maxnum: + Res = maxnum(*C1, *C2); + break; + case Intrinsic::minnum: + Res = minnum(*C1, *C2); + break; + case Intrinsic::maximum: + Res = maximum(*C1, *C2); + break; + case Intrinsic::minimum: + Res = minimum(*C1, *C2); + break; + default: + llvm_unreachable("unexpected intrinsic ID"); + } + Instruction *NewCall = Builder.CreateBinaryIntrinsic( + IID, X, ConstantFP::get(Arg0->getType(), Res)); + NewCall->copyIRFlags(II); + return replaceInstUsesWith(*II, NewCall); + } + } + break; } case Intrinsic::fmuladd: { |