diff options
author | Charlie Turner <charlie.turner@arm.com> | 2015-09-24 10:24:58 +0000 |
---|---|---|
committer | Charlie Turner <charlie.turner@arm.com> | 2015-09-24 10:24:58 +0000 |
commit | 2720593ab4518012af619c90b45f60ccc4ae4f29 (patch) | |
tree | 14d05e335eb725c957e3b3abf7fa362276ea4723 /llvm/lib | |
parent | e0395a7f7f3a0ba22080fe27016702a72de63ddb (diff) | |
download | bcm5719-llvm-2720593ab4518012af619c90b45f60ccc4ae4f29.tar.gz bcm5719-llvm-2720593ab4518012af619c90b45f60ccc4ae4f29.zip |
[InstCombine] Recognize another bswap idiom.
Summary:
The byte-swap recognizer can now notice that this
```
uint32_t bswap(uint32_t x)
{
x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;
x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
return x;
}
```
is a bswap. Fixes PR23863.
Reviewers: nlewycky, hfinkel, hans, jmolloy, rengolin
Subscribers: majnemer, rengolin, llvm-commits
Differential Revision: http://reviews.llvm.org/D12637
llvm-svn: 248482
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 0a603c030d9..5459c8955a1 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2220,14 +2220,18 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { ConstantInt *C1 = nullptr, *C2 = nullptr; // (A | B) | C and A | (B | C) -> bswap if possible. + bool OrOfOrs = match(Op0, m_Or(m_Value(), m_Value())) || + match(Op1, m_Or(m_Value(), m_Value())); // (A >> B) | (C << D) and (A << B) | (B >> C) -> bswap if possible. - if (match(Op0, m_Or(m_Value(), m_Value())) || - match(Op1, m_Or(m_Value(), m_Value())) || - (match(Op0, m_LogicalShift(m_Value(), m_Value())) && - match(Op1, m_LogicalShift(m_Value(), m_Value())))) { + bool OrOfShifts = match(Op0, m_LogicalShift(m_Value(), m_Value())) && + match(Op1, m_LogicalShift(m_Value(), m_Value())); + // (A & B) | (C & D) -> bswap if possible. + bool OrOfAnds = match(Op0, m_And(m_Value(), m_Value())) && + match(Op1, m_And(m_Value(), m_Value())); + + if (OrOfOrs || OrOfShifts || OrOfAnds) if (Instruction *BSwap = MatchBSwap(I)) return BSwap; - } // (X^C)|Y -> (X|Y)^C iff Y&C == 0 if (Op0->hasOneUse() && |