summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp9
-rw-r--r--llvm/test/Transforms/InstCombine/cast.ll7
-rw-r--r--llvm/test/Transforms/InstCombine/shift-sra.ll20
3 files changed, 19 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 098079abdf7..a19cdf7ef6d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -803,6 +803,15 @@ Instruction *InstCombiner::visitAShr(BinaryOperator &I) {
return BinaryOperator::CreateAShr(X, ConstantInt::get(Ty, AmtSum));
}
+ if (match(Op0, m_OneUse(m_SExt(m_Value(X)))) &&
+ (Ty->isVectorTy() || shouldChangeType(Ty, X->getType()))) {
+ // ashr (sext X), C --> sext (ashr X, C')
+ Type *SrcTy = X->getType();
+ ShAmt = std::min(ShAmt, SrcTy->getScalarSizeInBits() - 1);
+ Value *NewSh = Builder.CreateAShr(X, ConstantInt::get(SrcTy, ShAmt));
+ return new SExtInst(NewSh, Ty);
+ }
+
// If the shifted-out value is known-zero, then this is an exact shift.
if (!I.isExact() &&
MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmt), 0, &I)) {
diff --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll
index d121f62a55a..bc50f92056d 100644
--- a/llvm/test/Transforms/InstCombine/cast.ll
+++ b/llvm/test/Transforms/InstCombine/cast.ll
@@ -1302,13 +1302,10 @@ define i16 @test87(i16 %v) {
ret i16 %t
}
-; Do not optimize to ashr i16 (shift by 18)
define i16 @test88(i16 %v) {
; CHECK-LABEL: @test88(
-; CHECK-NEXT: [[A:%.*]] = sext i16 %v to i32
-; CHECK-NEXT: [[S:%.*]] = ashr i32 [[A]], 18
-; CHECK-NEXT: [[T:%.*]] = trunc i32 [[S]] to i16
-; CHECK-NEXT: ret i16 [[T]]
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i16 %v, 15
+; CHECK-NEXT: ret i16 [[TMP1]]
;
%a = sext i16 %v to i32
%s = ashr i32 %a, 18
diff --git a/llvm/test/Transforms/InstCombine/shift-sra.ll b/llvm/test/Transforms/InstCombine/shift-sra.ll
index 8aaa1a5cb49..4c28e878bbe 100644
--- a/llvm/test/Transforms/InstCombine/shift-sra.ll
+++ b/llvm/test/Transforms/InstCombine/shift-sra.ll
@@ -163,13 +163,12 @@ define <2 x i32> @ashr_overshift_splat_vec(<2 x i32> %x) {
ret <2 x i32> %sh2
}
-; TODO: Prefer a narrow shift for better for bit-tracking.
; ashr (sext X), C --> sext (ashr X, C')
define i32 @hoist_ashr_ahead_of_sext_1(i8 %x) {
; CHECK-LABEL: @hoist_ashr_ahead_of_sext_1(
-; CHECK-NEXT: [[SEXT:%.*]] = sext i8 %x to i32
-; CHECK-NEXT: [[R:%.*]] = ashr i32 [[SEXT]], 3
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i8 %x, 3
+; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sext = sext i8 %x to i32
@@ -177,13 +176,12 @@ define i32 @hoist_ashr_ahead_of_sext_1(i8 %x) {
ret i32 %r
}
-; TODO: Prefer a narrow shift for better for bit-tracking.
; ashr (sext X), C --> sext (ashr X, C')
define <2 x i32> @hoist_ashr_ahead_of_sext_1_splat(<2 x i8> %x) {
; CHECK-LABEL: @hoist_ashr_ahead_of_sext_1_splat(
-; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i8> %x to <2 x i32>
-; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[SEXT]], <i32 3, i32 3>
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i8> %x, <i8 3, i8 3>
+; CHECK-NEXT: [[R:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i32>
; CHECK-NEXT: ret <2 x i32> [[R]]
;
%sext = sext <2 x i8> %x to <2 x i32>
@@ -191,13 +189,12 @@ define <2 x i32> @hoist_ashr_ahead_of_sext_1_splat(<2 x i8> %x) {
ret <2 x i32> %r
}
-; TODO: Prefer a narrow shift for better for bit-tracking.
; ashr (sext X), C --> sext (ashr X, C') -- the shift amount must be clamped
define i32 @hoist_ashr_ahead_of_sext_2(i8 %x) {
; CHECK-LABEL: @hoist_ashr_ahead_of_sext_2(
-; CHECK-NEXT: [[SEXT:%.*]] = sext i8 %x to i32
-; CHECK-NEXT: [[R:%.*]] = ashr i32 [[SEXT]], 8
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i8 %x, 7
+; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%sext = sext i8 %x to i32
@@ -205,13 +202,12 @@ define i32 @hoist_ashr_ahead_of_sext_2(i8 %x) {
ret i32 %r
}
-; TODO: Prefer a narrow shift for better for bit-tracking.
; ashr (sext X), C --> sext (ashr X, C') -- the shift amount must be clamped
define <2 x i32> @hoist_ashr_ahead_of_sext_2_splat(<2 x i8> %x) {
; CHECK-LABEL: @hoist_ashr_ahead_of_sext_2_splat(
-; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i8> %x to <2 x i32>
-; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[SEXT]], <i32 8, i32 8>
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i8> %x, <i8 7, i8 7>
+; CHECK-NEXT: [[R:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i32>
; CHECK-NEXT: ret <2 x i32> [[R]]
;
%sext = sext <2 x i8> %x to <2 x i32>
OpenPOWER on IntegriCloud