[PATCH] D45731: [InstCombine] Adjusting bswap pattern matching to hold for And/Shift mixed case

Omer Paparo Bivas via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 17 11:44:14 PDT 2018


opaparo created this revision.
opaparo added reviewers: spatel, craig.topper, AndreiGrischenko, zvi, hfinkel.

Following a discussion that started in https://reviews.llvm.org/D41353, and tests from https://reviews.llvm.org/rL322206 to illustrate the missing pattern, I've modified the bswap pattern matching so that the "mixed" case of an 'or' of 'and' and a shift will also be considered a potential candidate for transforming to bswap.


Repository:
  rL LLVM

https://reviews.llvm.org/D45731

Files:
  lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  test/Transforms/InstCombine/bswap.ll


Index: test/Transforms/InstCombine/bswap.ll
===================================================================
--- test/Transforms/InstCombine/bswap.ll
+++ test/Transforms/InstCombine/bswap.ll
@@ -116,7 +116,7 @@
   ret i32 %bswap
 }
 
-; FIXME: Extra use should not prevent matching to bswap.
+; Extra use should not prevent matching to bswap.
 ; swaphalf = (x << 16 | x >> 16)
 ; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
 
@@ -126,10 +126,7 @@
 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 %x, 16
 ; CHECK-NEXT:    [[SWAPHALF:%.*]] = or i32 [[SHL]], [[SHR]]
 ; CHECK-NEXT:    [[T:%.*]] = and i32 [[SWAPHALF]], 16711935
-; CHECK-NEXT:    [[TSHL:%.*]] = shl nuw i32 [[T]], 8
-; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[SWAPHALF]], 8
-; CHECK-NEXT:    [[BAND:%.*]] = and i32 [[B]], 16711935
-; CHECK-NEXT:    [[BSWAP:%.*]] = or i32 [[TSHL]], [[BAND]]
+; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 %x)
 ; CHECK-NEXT:    call void @extra_use(i32 [[T]])
 ; CHECK-NEXT:    ret i32 [[BSWAP]]
 ;
Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1675,7 +1675,18 @@
   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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45731.142805.patch
Type: text/x-patch
Size: 2266 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180417/b59b891d/attachment.bin>


More information about the llvm-commits mailing list