[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