diff options
author | Omer Paparo Bivas <omer.paparo.bivas@intel.com> | 2018-05-01 12:25:46 +0000 |
---|---|---|
committer | Omer Paparo Bivas <omer.paparo.bivas@intel.com> | 2018-05-01 12:25:46 +0000 |
commit | 82ef8e19ef1dc06e7dde6a07ed035bf42213af07 (patch) | |
tree | 17f87e08cfd6c3d82bb9d7762cb89b201b95f611 /llvm/lib | |
parent | 6f710a6440d45b1a5ab08a21ed7f93ac0a1f8a40 (diff) | |
download | llvm-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.cpp | 13 |
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; |