[llvm] 7b07c01 - [InstCombine] Support arbitrary const shift amount for `lshr (sext i1 ...)`
Anton Afanasyev via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 15 03:51:47 PDT 2021
Author: Anton Afanasyev
Date: 2021-10-15T13:39:13+03:00
New Revision: 7b07c01351407095d9822592e04b0d8233185584
URL: https://github.com/llvm/llvm-project/commit/7b07c01351407095d9822592e04b0d8233185584
DIFF: https://github.com/llvm/llvm-project/commit/7b07c01351407095d9822592e04b0d8233185584.diff
LOG: [InstCombine] Support arbitrary const shift amount for `lshr (sext i1 ...)`
Add lshr (sext i1 X to iN), C --> select (X, -1 >> C, 0) case. This expands
C == N-1 case to arbitrary C.
Fixes PR52078.
Reviewed By: spatel, RKSimon, lebedev.ri
Differential Revision: https://reviews.llvm.org/D111330
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
llvm/test/Transforms/InstCombine/lshr.ll
llvm/test/Transforms/PhaseOrdering/X86/pr52078.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 0f83be53b8750..6f303b645544e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1067,28 +1067,31 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
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?
+ if (match(Op0, m_SExt(m_Value(X)))) {
unsigned SrcTyBitWidth = X->getType()->getScalarSizeInBits();
- if (ShAmtC == BitWidth - 1) {
- // lshr (sext i1 X to iN), N-1 --> zext X to iN
- if (SrcTyBitWidth == 1)
- return new ZExtInst(X, Ty);
+ // lshr (sext i1 X to iN), C --> select (X, -1 >> C, 0)
+ if (SrcTyBitWidth == 1) {
+ auto *NewC = ConstantInt::get(
+ Ty, APInt::getLowBitsSet(BitWidth, BitWidth - ShAmtC));
+ return SelectInst::Create(X, NewC, ConstantInt::getNullValue(Ty));
+ }
- // lshr (sext iM X to iN), N-1 --> zext (lshr X, M-1) to iN
- if (Op0->hasOneUse()) {
+ if ((!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType())) &&
+ Op0->hasOneUse()) {
+ // Are we moving the sign bit to the low bit and widening with high
+ // zeros? lshr (sext iM X to iN), N-1 --> zext (lshr X, M-1) to iN
+ if (ShAmtC == BitWidth - 1) {
Value *NewLShr = Builder.CreateLShr(X, SrcTyBitWidth - 1);
return new ZExtInst(NewLShr, Ty);
}
- }
- // lshr (sext iM X to iN), N-M --> zext (ashr X, min(N-M, M-1)) to iN
- if (ShAmtC == BitWidth - SrcTyBitWidth && Op0->hasOneUse()) {
- // The new shift amount can't be more than the narrow source type.
- unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
- Value *AShr = Builder.CreateAShr(X, NewShAmt);
- return new ZExtInst(AShr, Ty);
+ // lshr (sext iM X to iN), N-M --> zext (ashr X, min(N-M, M-1)) to iN
+ if (ShAmtC == BitWidth - SrcTyBitWidth) {
+ // The new shift amount can't be more than the narrow source type.
+ unsigned NewShAmt = std::min(ShAmtC, SrcTyBitWidth - 1);
+ Value *AShr = Builder.CreateAShr(X, NewShAmt);
+ return new ZExtInst(AShr, Ty);
+ }
}
}
diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll
index 89f36e5409260..d524bdb93ea2d 100644
--- a/llvm/test/Transforms/InstCombine/lshr.ll
+++ b/llvm/test/Transforms/InstCombine/lshr.ll
@@ -620,8 +620,7 @@ define i12 @trunc_sandwich_big_sum_shift2_use1(i32 %x) {
define i16 @lshr_sext_i1_to_i16(i1 %a) {
; CHECK-LABEL: @lshr_sext_i1_to_i16(
-; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i16
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[SEXT]], 4
+; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 4095, i16 0
; CHECK-NEXT: ret i16 [[LSHR]]
;
%sext = sext i1 %a to i16
@@ -631,8 +630,7 @@ define i16 @lshr_sext_i1_to_i16(i1 %a) {
define i128 @lshr_sext_i1_to_i128(i1 %a) {
; CHECK-LABEL: @lshr_sext_i1_to_i128(
-; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i128
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i128 [[SEXT]], 42
+; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i128 77371252455336267181195263, i128 0
; CHECK-NEXT: ret i128 [[LSHR]]
;
%sext = sext i1 %a to i128
@@ -644,7 +642,7 @@ define i32 @lshr_sext_i1_to_i32_use(i1 %a) {
; CHECK-LABEL: @lshr_sext_i1_to_i32_use(
; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i32
; CHECK-NEXT: call void @use(i32 [[SEXT]])
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[SEXT]], 14
+; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A]], i32 262143, i32 0
; CHECK-NEXT: ret i32 [[LSHR]]
;
%sext = sext i1 %a to i32
@@ -657,7 +655,7 @@ define <3 x i14> @lshr_sext_i1_to_i14_splat_vec_use1(<3 x i1> %a) {
; CHECK-LABEL: @lshr_sext_i1_to_i14_splat_vec_use1(
; CHECK-NEXT: [[SEXT:%.*]] = sext <3 x i1> [[A:%.*]] to <3 x i14>
; CHECK-NEXT: call void @usevec(<3 x i14> [[SEXT]])
-; CHECK-NEXT: [[LSHR:%.*]] = lshr <3 x i14> [[SEXT]], <i14 4, i14 4, i14 4>
+; CHECK-NEXT: [[LSHR:%.*]] = select <3 x i1> [[A]], <3 x i14> <i14 1023, i14 1023, i14 1023>, <3 x i14> zeroinitializer
; CHECK-NEXT: ret <3 x i14> [[LSHR]]
;
%sext = sext <3 x i1> %a to <3 x i14>
diff --git a/llvm/test/Transforms/PhaseOrdering/X86/pr52078.ll b/llvm/test/Transforms/PhaseOrdering/X86/pr52078.ll
index 2fbfbca7ebe39..388d5718115d7 100644
--- a/llvm/test/Transforms/PhaseOrdering/X86/pr52078.ll
+++ b/llvm/test/Transforms/PhaseOrdering/X86/pr52078.ll
@@ -16,8 +16,7 @@ define i16 @foo(i1 %a) {
; IC-NEXT: ret i16 [[TRUNC]]
;
; AIC_AND_IC-LABEL: @foo(
-; AIC_AND_IC-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i16
-; AIC_AND_IC-NEXT: [[LSHR:%.*]] = lshr i16 [[SEXT]], 1
+; AIC_AND_IC-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0
; AIC_AND_IC-NEXT: ret i16 [[LSHR]]
;
%sext = sext i1 %a to i16
@@ -29,18 +28,15 @@ define i16 @foo(i1 %a) {
define i16 @foo2(i1 %a) {
; CHECK-LABEL: @foo2(
-; CHECK-NEXT: [[S:%.*]] = sext i1 [[A:%.*]] to i16
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[S]], 1
+; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0
; CHECK-NEXT: ret i16 [[LSHR]]
;
; IC-LABEL: @foo2(
-; IC-NEXT: [[S:%.*]] = sext i1 [[A:%.*]] to i16
-; IC-NEXT: [[LSHR:%.*]] = lshr i16 [[S]], 1
+; IC-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0
; IC-NEXT: ret i16 [[LSHR]]
;
; AIC_AND_IC-LABEL: @foo2(
-; AIC_AND_IC-NEXT: [[S:%.*]] = sext i1 [[A:%.*]] to i16
-; AIC_AND_IC-NEXT: [[LSHR:%.*]] = lshr i16 [[S]], 1
+; AIC_AND_IC-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0
; AIC_AND_IC-NEXT: ret i16 [[LSHR]]
;
%s = sext i1 %a to i16
More information about the llvm-commits
mailing list