From: Charlie Turner Date: Thu, 24 Sep 2015 10:24:58 +0000 (+0000) Subject: [InstCombine] Recognize another bswap idiom. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=424da5488131bab44c887a2d8a5680e1ad689de4;p=oota-llvm.git [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248482 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 0a603c030d9..5459c8955a1 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/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() && diff --git a/test/Transforms/InstCombine/bswap.ll b/test/Transforms/InstCombine/bswap.ll index ba7df3125f4..b48b2a57c8c 100644 --- a/test/Transforms/InstCombine/bswap.ll +++ b/test/Transforms/InstCombine/bswap.ll @@ -1,7 +1,7 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" ; RUN: opt < %s -instcombine -S | \ -; RUN: grep "call.*llvm.bswap" | count 6 +; RUN: grep "call.*llvm.bswap" | count 7 define i32 @test1(i32 %i) { %tmp1 = lshr i32 %i, 24 ; [#uses=1] @@ -72,3 +72,15 @@ define i32 @test6(i32 %x) nounwind readnone { ret i32 %tmp7 } +; PR23863 +define i32 @test7(i32 %x) { + %shl = shl i32 %x, 16 + %shr = lshr i32 %x, 16 + %or = or i32 %shl, %shr + %and2 = shl i32 %or, 8 + %shl3 = and i32 %and2, -16711936 + %and4 = lshr i32 %or, 8 + %shr5 = and i32 %and4, 16711935 + %or6 = or i32 %shl3, %shr5 + ret i32 %or6 +}