[PATCH] D66965: [InstCombine] recognize bswap disguised as shufflevector

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 2 06:33:00 PDT 2019


This revision was automatically updated to reflect the committed changes.
Closed by commit rL370659: [InstCombine] recognize bswap disguised as shufflevector (authored by spatel, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D66965?vs=217969&id=218355#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66965/new/

https://reviews.llvm.org/D66965

Files:
  llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
  llvm/trunk/test/Transforms/InstCombine/bswap.ll


Index: llvm/trunk/test/Transforms/InstCombine/bswap.ll
===================================================================
--- llvm/trunk/test/Transforms/InstCombine/bswap.ll
+++ llvm/trunk/test/Transforms/InstCombine/bswap.ll
@@ -233,8 +233,8 @@
 
 define i32 @shuf_4bytes(<4 x i8> %x) {
 ; CHECK-LABEL: @shuf_4bytes(
-; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
-; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i8> [[X:%.*]] to i32
+; CHECK-NEXT:    [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[TMP1]])
 ; CHECK-NEXT:    ret i32 [[CAST]]
 ;
   %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
@@ -244,9 +244,9 @@
 
 define i32 @shuf_load_4bytes(<4 x i8>* %p) {
 ; CHECK-LABEL: @shuf_load_4bytes(
-; CHECK-NEXT:    [[X:%.*]] = load <4 x i8>, <4 x i8>* [[P:%.*]], align 4
-; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <4 x i8> [[X]], <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 undef, i32 0>
-; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i8>* [[P:%.*]] to i32*
+; CHECK-NEXT:    [[X1:%.*]] = load i32, i32* [[TMP1]], align 4
+; CHECK-NEXT:    [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[X1]])
 ; CHECK-NEXT:    ret i32 [[CAST]]
 ;
   %x = load <4 x i8>, <4 x i8>* %p
@@ -257,9 +257,7 @@
 
 define i32 @shuf_bitcast_twice_4bytes(i32 %x) {
 ; CHECK-LABEL: @shuf_bitcast_twice_4bytes(
-; CHECK-NEXT:    [[CAST1:%.*]] = bitcast i32 [[X:%.*]] to <4 x i8>
-; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <4 x i8> [[CAST1]], <4 x i8> undef, <4 x i32> <i32 undef, i32 2, i32 1, i32 0>
-; CHECK-NEXT:    [[CAST2:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
+; CHECK-NEXT:    [[CAST2:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
 ; CHECK-NEXT:    ret i32 [[CAST2]]
 ;
   %cast1 = bitcast i32 %x to <4 x i8>
@@ -268,6 +266,7 @@
   ret i32 %cast2
 }
 
+; Negative test - extra use
 declare void @use(<4 x i8>)
 
 define i32 @shuf_4bytes_extra_use(<4 x i8> %x) {
@@ -283,6 +282,8 @@
   ret i32 %cast
 }
 
+; Negative test - scalar type is not in the data layout
+
 define i128 @shuf_16bytes(<16 x i8> %x) {
 ; CHECK-LABEL: @shuf_16bytes(
 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <16 x i8> [[X:%.*]], <16 x i8> undef, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
@@ -294,6 +295,8 @@
   ret i128 %cast
 }
 
+; Negative test - don't touch widening shuffles (for now)
+
 define i32 @shuf_2bytes_widening(<2 x i8> %x) {
 ; CHECK-LABEL: @shuf_2bytes_widening(
 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2416,6 +2416,22 @@
         return new ShuffleVectorInst(LHS, RHS, Shuf->getOperand(2));
       }
     }
+
+    // A bitcasted-to-scalar and byte-reversing shuffle is better recognized as
+    // a byte-swap:
+    // bitcast <N x i8> (shuf X, undef, <N, N-1,...0>) --> bswap (bitcast X)
+    // TODO: We should match the related pattern for bitreverse.
+    if (DestTy->isIntegerTy() &&
+        DL.isLegalInteger(DestTy->getScalarSizeInBits()) &&
+        SrcTy->getScalarSizeInBits() == 8 && NumShufElts % 2 == 0 &&
+        Shuf->hasOneUse() && Shuf->isReverse()) {
+      assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask");
+      assert(isa<UndefValue>(ShufOp1) && "Unexpected shuffle op");
+      Function *Bswap =
+          Intrinsic::getDeclaration(CI.getModule(), Intrinsic::bswap, DestTy);
+      Value *ScalarX = Builder.CreateBitCast(ShufOp0, DestTy);
+      return IntrinsicInst::Create(Bswap, { ScalarX });
+    }
   }
 
   // Handle the A->B->A cast, and there is an intervening PHI node.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66965.218355.patch
Type: text/x-patch
Size: 4104 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190902/d57564a3/attachment.bin>


More information about the llvm-commits mailing list