diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2017-02-01 16:34:55 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2017-02-01 16:34:55 +0000 |
commit | e0e5795f6b9d2b903e60d968a8c9dbcc7972d2f4 (patch) | |
tree | 7c9ad3b6312a5ba83234d9309a62b4d28657061c /llvm/lib/Transforms | |
parent | ca931efc21c5791f90e29eb8fa7690db6769fa67 (diff) | |
download | bcm5719-llvm-e0e5795f6b9d2b903e60d968a8c9dbcc7972d2f4.tar.gz bcm5719-llvm-e0e5795f6b9d2b903e60d968a8c9dbcc7972d2f4.zip |
[InstCombine] Allow InstCombine to merge adjacent guards
Summary:
If there are two adjacent guards with different conditions, we can
remove one of them and include its condition into the condition of
another one. This patch allows InstCombine to merge them by the
following pattern:
guard(a); guard(b) -> guard(a & b).
Reviewers: reames, apilipenko, igor-laevsky, anna, sanjoy
Reviewed By: sanjoy
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D29378
llvm-svn: 293778
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 56983dc6036..f088671c6d7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3255,16 +3255,24 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { } case Intrinsic::experimental_guard: { - Value *IIOperand = II->getArgOperand(0); + // Is this guard followed by another guard? + Instruction *NextInst = II->getNextNode(); + Value *NextCond = nullptr; + if (match(NextInst, + m_Intrinsic<Intrinsic::experimental_guard>(m_Value(NextCond)))) { + Value *CurrCond = II->getArgOperand(0); - // Remove a guard if it is immediately followed by an identical guard. - if (match(II->getNextNode(), - m_Intrinsic<Intrinsic::experimental_guard>(m_Specific(IIOperand)))) - return eraseInstFromFunction(*II); + // Remove a guard that it is immediately preceeded by an identical guard. + if (CurrCond == NextCond) + return eraseInstFromFunction(*NextInst); + + // Otherwise canonicalize guard(a); guard(b) -> guard(a & b). + II->setArgOperand(0, Builder->CreateAnd(CurrCond, NextCond)); + return eraseInstFromFunction(*NextInst); + } break; } } - return visitCallSite(II); } |