aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorOmer Paparo Bivas <omer.paparo.bivas@intel.com>2018-05-01 12:25:46 +0000
committerOmer Paparo Bivas <omer.paparo.bivas@intel.com>2018-05-01 12:25:46 +0000
commit82ef8e19ef1dc06e7dde6a07ed035bf42213af07 (patch)
tree17f87e08cfd6c3d82bb9d7762cb89b201b95f611 /llvm/lib
parent6f710a6440d45b1a5ab08a21ed7f93ac0a1f8a40 (diff)
downloadllvm-82ef8e19ef1dc06e7dde6a07ed035bf42213af07.zip
llvm-82ef8e19ef1dc06e7dde6a07ed035bf42213af07.tar.gz
llvm-82ef8e19ef1dc06e7dde6a07ed035bf42213af07.tar.bz2
[InstCombine] Adjusting bswap pattern matching to hold for And/Shift mixed case
Differential Revision: https://reviews.llvm.org/D45731 Change-Id: I85d4226504e954933c41598327c91b2d08192a9d llvm-svn: 331257
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index e389af2..9a5183c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1675,7 +1675,18 @@ Instruction *InstCombiner::MatchBSwap(BinaryOperator &I) {
bool OrOfAnds = match(Op0, m_And(m_Value(), m_Value())) &&
match(Op1, m_And(m_Value(), m_Value()));
- if (!OrOfOrs && !OrOfShifts && !OrOfAnds)
+ // (A << B) | (C & D) -> bswap if possible.
+ // The bigger pattern here is ((A & C1) << C2) | ((B >> C2) & C1), which is a
+ // part of the bswap idiom for specific values of C1, C2 (e.g. C1 = 16711935,
+ // C2 = 8 for i32).
+ // This pattern can occur when the operands of the 'or' are not canonicalized
+ // for some reason (not having only one use, for example).
+ bool OrOfAndAndSh = (match(Op0, m_LogicalShift(m_Value(), m_Value())) &&
+ match(Op1, m_And(m_Value(), m_Value()))) ||
+ (match(Op0, m_And(m_Value(), m_Value())) &&
+ match(Op1, m_LogicalShift(m_Value(), m_Value())));
+
+ if (!OrOfOrs && !OrOfShifts && !OrOfAnds && !OrOfAndAndSh)
return nullptr;
SmallVector<Instruction*, 4> Insts;