[llvm] adf4519 - [InstCombine] recognize bitreverse disguised as shufflevector

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


Author: Chenbing Zheng
Date: 2022-08-25T10:41:47+08:00
New Revision: adf4519c0e46c8812618f9f493d7c605b454a668

URL: https://github.com/llvm/llvm-project/commit/adf4519c0e46c8812618f9f493d7c605b454a668
DIFF: https://github.com/llvm/llvm-project/commit/adf4519c0e46c8812618f9f493d7c605b454a668.diff

LOG: [InstCombine] recognize bitreverse disguised as shufflevector

This patch complete TODO left in D66965, and achieve
related pattern for bitreverse.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D132431

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 1e6149220159..ecf9e3ebcff9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2864,21 +2864,27 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) {
       }
     }
 
-    // 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});
+      }
     }
   }
 

diff  --git a/llvm/test/Transforms/InstCombine/bitreverse.ll b/llvm/test/Transforms/InstCombine/bitreverse.ll
index dd3d48fd9abf..671bbd875688 100644
--- a/llvm/test/Transforms/InstCombine/bitreverse.ll
+++ b/llvm/test/Transforms/InstCombine/bitreverse.ll
@@ -255,8 +255,8 @@ define i8 @rev8_mul_and_lshr(i8 %0) {
 
 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_4bits(<4 x i1> %x) {
 
 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_load_4bits(<4 x i1> * %p) {
 
 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>


        


More information about the llvm-commits mailing list