[PATCH] D132431: [InstCombine] recognize bitreverse disguised as shufflevector

Chenbing.Zheng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 24 19:43:17 PDT 2022


This revision was automatically updated to reflect the committed changes.
Closed by commit rGadf4519c0e46: [InstCombine] recognize bitreverse disguised as shufflevector (authored by Chenbing.Zheng).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132431

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


Index: llvm/test/Transforms/InstCombine/bitreverse.ll
===================================================================
--- llvm/test/Transforms/InstCombine/bitreverse.ll
+++ llvm/test/Transforms/InstCombine/bitreverse.ll
@@ -255,8 +255,8 @@
 
 define i4 @shuf_4bits(<4 x i1> %x) {
 ; CHECK-LABEL: @shuf_4bits(
-; CHECK-NEXT:    [[BITREVERSE:%.*]] = shufflevector <4 x i1> [[X:%.*]], <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
-; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i1> [[BITREVERSE]] to i4
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4
+; CHECK-NEXT:    [[CAST:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[TMP1]])
 ; CHECK-NEXT:    ret i4 [[CAST]]
 ;
   %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
@@ -266,9 +266,9 @@
 
 define i4 @shuf_load_4bits(<4 x i1> * %p) {
 ; CHECK-LABEL: @shuf_load_4bits(
-; CHECK-NEXT:    [[X:%.*]] = load <4 x i1>, <4 x i1>* [[P:%.*]], align 1
-; CHECK-NEXT:    [[BITREVERSE:%.*]] = shufflevector <4 x i1> [[X]], <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
-; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i1> [[BITREVERSE]] to i4
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i1>* [[P:%.*]] to i4*
+; CHECK-NEXT:    [[X1:%.*]] = load i4, i4* [[TMP1]], align 1
+; CHECK-NEXT:    [[CAST:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[X1]])
 ; CHECK-NEXT:    ret i4 [[CAST]]
 ;
   %x = load <4 x i1>, <4 x i1>* %p
@@ -279,9 +279,7 @@
 
 define i4 @shuf_bitcast_twice_4bits(i4 %x) {
 ; CHECK-LABEL: @shuf_bitcast_twice_4bits(
-; CHECK-NEXT:    [[CAST1:%.*]] = bitcast i4 [[X:%.*]] to <4 x i1>
-; CHECK-NEXT:    [[BITREVERSE:%.*]] = shufflevector <4 x i1> [[CAST1]], <4 x i1> undef, <4 x i32> <i32 undef, i32 2, i32 1, i32 0>
-; CHECK-NEXT:    [[CAST2:%.*]] = bitcast <4 x i1> [[BITREVERSE]] to i4
+; CHECK-NEXT:    [[CAST2:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[X:%.*]])
 ; CHECK-NEXT:    ret i4 [[CAST2]]
 ;
   %cast1 = bitcast i4 %x to <4 x i1>
Index: llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2864,21 +2864,27 @@
       }
     }
 
-    // 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 &&
-        ShufElts.getKnownMinValue() % 2 == 0 && Shuf->hasOneUse() &&
-        Shuf->isReverse()) {
-      assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask");
-      assert(match(ShufOp1, m_Undef()) && "Unexpected shuffle op");
-      Function *Bswap =
-          Intrinsic::getDeclaration(CI.getModule(), Intrinsic::bswap, DestTy);
-      Value *ScalarX = Builder.CreateBitCast(ShufOp0, DestTy);
-      return CallInst::Create(Bswap, { ScalarX });
+    // A bitcasted-to-scalar and byte/bit reversing shuffle is better recognized
+    // as a byte/bit swap:
+    // bitcast <N x i8> (shuf X, undef, <N, N-1,...0>) -> bswap (bitcast X)
+    // bitcast <N x i1> (shuf X, undef, <N, N-1,...0>) -> bitreverse (bitcast X)
+    if (DestTy->isIntegerTy() && ShufElts.getKnownMinValue() % 2 == 0 &&
+        Shuf->hasOneUse() && Shuf->isReverse()) {
+      unsigned IntrinsicNum = 0;
+      if (DL.isLegalInteger(DestTy->getScalarSizeInBits()) &&
+          SrcTy->getScalarSizeInBits() == 8) {
+        IntrinsicNum = Intrinsic::bswap;
+      } else if (SrcTy->getScalarSizeInBits() == 1) {
+        IntrinsicNum = Intrinsic::bitreverse;
+      }
+      if (IntrinsicNum != 0) {
+        assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask");
+        assert(match(ShufOp1, m_Undef()) && "Unexpected shuffle op");
+        Function *BswapOrBitreverse =
+            Intrinsic::getDeclaration(CI.getModule(), IntrinsicNum, DestTy);
+        Value *ScalarX = Builder.CreateBitCast(ShufOp0, DestTy);
+        return CallInst::Create(BswapOrBitreverse, {ScalarX});
+      }
     }
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D132431.455464.patch
Type: text/x-patch
Size: 4241 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220825/26a21b22/attachment.bin>


More information about the llvm-commits mailing list