From 4c8c101b496431c468825518e9bd4375e8209ae9 Mon Sep 17 00:00:00 2001 From: Chenbing Zheng Date: Fri, 6 May 2022 10:45:10 +0800 Subject: [PATCH] [InstCombine] try to narrow more shifted bswap-of-zext Try to narrow more bswap, if the shift amount is less than the zext (bswap (zext X)) >> C --> (zext (bswap X)) << C' https://alive2.llvm.org/ce/z/i7ddjn Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D124598 --- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 18 ++++++++++++------ llvm/test/Transforms/InstCombine/lshr.ll | 10 ++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index a0a3514..e5b0e32 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -1232,19 +1232,25 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) { } } - // Try to narrow a bswap: - // (bswap (zext X)) >> C --> zext (bswap X >> C') + // Try to narrow bswap. // In the case where the shift amount equals the bitwidth difference, the // shift is eliminated. if (match(Op0, m_OneUse(m_Intrinsic( m_OneUse(m_ZExt(m_Value(X))))))) { - // TODO: If the shift amount is less than the zext, we could shift left. unsigned SrcWidth = X->getType()->getScalarSizeInBits(); unsigned WidthDiff = BitWidth - SrcWidth; - if (SrcWidth % 16 == 0 && ShAmtC >= WidthDiff) { + if (SrcWidth % 16 == 0) { Value *NarrowSwap = Builder.CreateUnaryIntrinsic(Intrinsic::bswap, X); - Value *NewShift = Builder.CreateLShr(NarrowSwap, ShAmtC - WidthDiff); - return new ZExtInst(NewShift, Ty); + if (ShAmtC >= WidthDiff) { + // (bswap (zext X)) >> C --> zext (bswap X >> C') + Value *NewShift = Builder.CreateLShr(NarrowSwap, ShAmtC - WidthDiff); + return new ZExtInst(NewShift, Ty); + } else { + // (bswap (zext X)) >> C --> (zext (bswap X)) << C' + Value *NewZExt = Builder.CreateZExt(NarrowSwap, Ty); + Constant *ShiftDiff = ConstantInt::get(Ty, WidthDiff - ShAmtC); + return BinaryOperator::CreateShl(NewZExt, ShiftDiff); + } } } diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll index e4e869b..2545b86 100644 --- a/llvm/test/Transforms/InstCombine/lshr.ll +++ b/llvm/test/Transforms/InstCombine/lshr.ll @@ -864,18 +864,16 @@ define i128 @narrow_bswap_extra_wide(i16 %x) { ret i128 %s } -; TODO: The bswap can be narrowed followed by shl. - define i32 @narrow_bswap_undershift(i16 %x) { ; CHECK-LABEL: @narrow_bswap_undershift( -; CHECK-NEXT: [[Z:%.*]] = zext i16 [[X:%.*]] to i32 -; CHECK-NEXT: [[B:%.*]] = call i32 @llvm.bswap.i32(i32 [[Z]]) -; CHECK-NEXT: [[S:%.*]] = lshr exact i32 [[B]], 8 +; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]]) +; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i32 +; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[TMP2]], 7 ; CHECK-NEXT: ret i32 [[S]] ; %z = zext i16 %x to i32 %b = call i32 @llvm.bswap.i32(i32 %z) - %s = lshr i32 %b, 8 + %s = lshr i32 %b, 9 ret i32 %s } -- 2.7.4