From 4e29225d159ad62fed5f0b7f8e11843b53e573fd Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 4 Aug 2017 15:42:47 +0000 Subject: [PATCH] [InstCombine] narrow lshr with constant Name: narrow_shift Pre: C1 < 8 %zx = zext i8 %x to i32 %l = lshr i32 %zx, C1 => %narrowC = trunc i32 C1 to i8 %ns = lshr i8 %x, %narrowC %l = zext i8 %ns to i32 http://rise4fun.com/Alive/jIV This isn't directly applicable to PR34046 as written, but we need to have more narrowing folds like this to be sure that rotate patterns are recognized. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310060 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineShifts.cpp | 9 +++++++++ test/Transforms/InstCombine/cast.ll | 6 +++--- test/Transforms/InstCombine/lshr.ll | 13 +++++++++++++ test/Transforms/InstCombine/select-with-bitwise-ops.ll | 8 ++++---- test/Transforms/InstCombine/trunc.ll | 6 +++--- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp index 7ed141c7fd7..f4e2458fba2 100644 --- a/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -680,6 +680,15 @@ Instruction *InstCombiner::visitLShr(BinaryOperator &I) { return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, Mask)); } + if (match(Op0, m_OneUse(m_ZExt(m_Value(X)))) && + (!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType()))) { + unsigned SrcTyBitWidth = X->getType()->getScalarSizeInBits(); + assert(ShAmt < SrcTyBitWidth && "Big shift not simplified to zero?"); + // lshr (zext iM X to iN), C --> zext (lshr X, C) to iN + Value *NewLShr = Builder.CreateLShr(X, ShAmt); + return new ZExtInst(NewLShr, Ty); + } + if (match(Op0, m_SExt(m_Value(X))) && (!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType()))) { // Are we moving the sign bit to the low bit and widening with high zeros? diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index dedbd783d3f..1d3e2233298 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -761,9 +761,9 @@ define i64 @test59(i8 %A, i8 %B) nounwind { ; CHECK-NEXT: [[C:%.*]] = zext i8 %A to i64 ; CHECK-NEXT: [[D:%.*]] = shl nuw nsw i64 [[C]], 4 ; CHECK-NEXT: [[E:%.*]] = and i64 [[D]], 48 -; CHECK-NEXT: [[F:%.*]] = zext i8 %B to i64 -; CHECK-NEXT: [[G:%.*]] = lshr i64 [[F]], 4 -; CHECK-NEXT: [[H:%.*]] = or i64 [[G]], [[E]] +; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 %B, 4 +; CHECK-NEXT: [[G:%.*]] = zext i8 [[TMP1]] to i64 +; CHECK-NEXT: [[H:%.*]] = or i64 [[E]], [[G]] ; CHECK-NEXT: ret i64 [[H]] ; %C = zext i8 %A to i32 diff --git a/test/Transforms/InstCombine/lshr.ll b/test/Transforms/InstCombine/lshr.ll index 4cdcb98f730..8ab3ca88741 100644 --- a/test/Transforms/InstCombine/lshr.ll +++ b/test/Transforms/InstCombine/lshr.ll @@ -190,3 +190,16 @@ define <2 x i8> @fake_sext_splat(<2 x i3> %x) { ret <2 x i8> %sh } +; Use a narrow shift: lshr (zext iM X to iN), C --> zext (lshr X, C) to iN + +define <2 x i32> @narrow_lshr_constant(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @narrow_lshr_constant( +; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i8> %x, +; CHECK-NEXT: [[SH:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32> +; CHECK-NEXT: ret <2 x i32> [[SH]] +; + %zx = zext <2 x i8> %x to <2 x i32> + %sh = lshr <2 x i32> %zx, + ret <2 x i32> %sh +} + diff --git a/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/test/Transforms/InstCombine/select-with-bitwise-ops.ll index 437f09be2e7..f562c6ebafb 100644 --- a/test/Transforms/InstCombine/select-with-bitwise-ops.ll +++ b/test/Transforms/InstCombine/select-with-bitwise-ops.ll @@ -283,10 +283,10 @@ define i32 @test66(i64 %x) { define i32 @test67(i16 %x) { ; CHECK-LABEL: @test67( -; CHECK-NEXT: [[TMP1:%.*]] = and i16 %x, 4 -; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i32 -; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i32 [[TMP2]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = xor i32 [[TMP3]], 42 +; CHECK-NEXT: [[TMP1:%.*]] = lshr i16 %x, 1 +; CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 2 +; CHECK-NEXT: [[TMP3:%.*]] = xor i16 [[TMP2]], 42 +; CHECK-NEXT: [[TMP4:%.*]] = zext i16 [[TMP3]] to i32 ; CHECK-NEXT: ret i32 [[TMP4]] ; %1 = and i16 %x, 4 diff --git a/test/Transforms/InstCombine/trunc.ll b/test/Transforms/InstCombine/trunc.ll index dd86e5a907b..3ba0b866e47 100644 --- a/test/Transforms/InstCombine/trunc.ll +++ b/test/Transforms/InstCombine/trunc.ll @@ -91,9 +91,9 @@ define i32 @test6(i64 %A) { define i92 @test7(i64 %A) { ; CHECK-LABEL: @test7( -; CHECK-NEXT: [[B:%.*]] = zext i64 %A to i92 -; CHECK-NEXT: [[C:%.*]] = lshr i92 [[B]], 32 -; CHECK-NEXT: ret i92 [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 %A, 32 +; CHECK-NEXT: [[D:%.*]] = zext i64 [[TMP1]] to i92 +; CHECK-NEXT: ret i92 [[D]] ; %B = zext i64 %A to i128 %C = lshr i128 %B, 32 -- 2.11.0