[llvm] r248482 - [InstCombine] Recognize another bswap idiom.

Charlie Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 03:24:58 PDT 2015


Author: chatur01
Date: Thu Sep 24 05:24:58 2015
New Revision: 248482

URL: http://llvm.org/viewvc/llvm-project?rev=248482&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/trunk/test/Transforms/InstCombine/bswap.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=248482&r1=248481&r2=248482&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Thu Sep 24 05:24:58 2015
@@ -2220,14 +2220,18 @@ Instruction *InstCombiner::visitOr(Binar
   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() &&

Modified: llvm/trunk/test/Transforms/InstCombine/bswap.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/bswap.ll?rev=248482&r1=248481&r2=248482&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/bswap.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/bswap.ll Thu Sep 24 05:24:58 2015
@@ -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		; <i32> [#uses=1]
@@ -72,3 +72,15 @@ define i32 @test6(i32 %x) nounwind readn
 	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
+}




More information about the llvm-commits mailing list