[llvm-branch-commits] [llvm] fd67910 - [InstCombine] Optimize away the unnecessary multi-use sign-extend
Roman Lebedev via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 1 05:59:14 PST 2020
Author: Bhramar Vatsa
Date: 2020-12-01T16:54:00+03:00
New Revision: fd679107d670d8fd31b62245b433187b4d72a9d0
URL: https://github.com/llvm/llvm-project/commit/fd679107d670d8fd31b62245b433187b4d72a9d0
DIFF: https://github.com/llvm/llvm-project/commit/fd679107d670d8fd31b62245b433187b4d72a9d0.diff
LOG: [InstCombine] Optimize away the unnecessary multi-use sign-extend
C.f. https://bugs.llvm.org/show_bug.cgi?id=47765
Added a case for handling the sign-extend (Shl+AShr) for multiple uses,
to optimize it away for an individual use,
when the demanded bits aren't affected by sign-extend.
https://rise4fun.com/Alive/lgf
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D91343
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/test/Transforms/InstCombine/and.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3f2a6f8eb2ea..5b0a4857f33d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -899,6 +899,33 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
break;
}
+ case Instruction::AShr: {
+ // Compute the Known bits to simplify things downstream.
+ computeKnownBits(I, Known, Depth, CxtI);
+
+ // If this user is only demanding bits that we know, return the known
+ // constant.
+ if (DemandedMask.isSubsetOf(Known.Zero | Known.One))
+ return Constant::getIntegerValue(ITy, Known.One);
+
+ // If the right shift operand 0 is a result of a left shift by the same
+ // amount, this is probably a zero/sign extension, which may be unnecessary,
+ // if we do not demand any of the new sign bits. So, return the original
+ // operand instead.
+ const APInt *ShiftRC;
+ const APInt *ShiftLC;
+ Value *X;
+ unsigned BitWidth = DemandedMask.getBitWidth();
+ if (match(I,
+ m_AShr(m_Shl(m_Value(X), m_APInt(ShiftLC)), m_APInt(ShiftRC))) &&
+ ShiftLC == ShiftRC &&
+ DemandedMask.isSubsetOf(APInt::getLowBitsSet(
+ BitWidth, BitWidth - ShiftRC->getZExtValue()))) {
+ return X;
+ }
+
+ break;
+ }
default:
// Compute the Known bits to simplify things downstream.
computeKnownBits(I, Known, Depth, CxtI);
diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index ed50ae16350d..020dbc483d9d 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -979,7 +979,7 @@ define i32 @lowmask_sext_in_reg(i32 %x) {
; CHECK-NEXT: [[L:%.*]] = shl i32 [[X:%.*]], 20
; CHECK-NEXT: [[R:%.*]] = ashr exact i32 [[L]], 20
; CHECK-NEXT: call void @use32(i32 [[R]])
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[R]], 4095
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 4095
; CHECK-NEXT: ret i32 [[AND]]
;
%l = shl i32 %x, 20
@@ -989,6 +989,8 @@ define i32 @lowmask_sext_in_reg(i32 %x) {
ret i32 %and
}
+; Negative test - mismatched shift amounts
+
define i32 @lowmask_not_sext_in_reg(i32 %x) {
; CHECK-LABEL: @lowmask_not_sext_in_reg(
; CHECK-NEXT: [[L:%.*]] = shl i32 [[X:%.*]], 19
@@ -1004,6 +1006,8 @@ define i32 @lowmask_not_sext_in_reg(i32 %x) {
ret i32 %and
}
+; Negative test - too much shift for mask
+
define i32 @not_lowmask_sext_in_reg(i32 %x) {
; CHECK-LABEL: @not_lowmask_sext_in_reg(
; CHECK-NEXT: [[L:%.*]] = shl i32 [[X:%.*]], 20
@@ -1019,6 +1023,8 @@ define i32 @not_lowmask_sext_in_reg(i32 %x) {
ret i32 %and
}
+; Negative test - too much shift for mask
+
define i32 @not_lowmask_sext_in_reg2(i32 %x) {
; CHECK-LABEL: @not_lowmask_sext_in_reg2(
; CHECK-NEXT: [[L:%.*]] = shl i32 [[X:%.*]], 21
@@ -1039,7 +1045,7 @@ define <2 x i32> @lowmask_sext_in_reg_splat(<2 x i32> %x, <2 x i32>* %p) {
; CHECK-NEXT: [[L:%.*]] = shl <2 x i32> [[X:%.*]], <i32 20, i32 20>
; CHECK-NEXT: [[R:%.*]] = ashr exact <2 x i32> [[L]], <i32 20, i32 20>
; CHECK-NEXT: store <2 x i32> [[R]], <2 x i32>* [[P:%.*]], align 8
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[R]], <i32 4095, i32 4095>
+; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X]], <i32 4095, i32 4095>
; CHECK-NEXT: ret <2 x i32> [[AND]]
;
%l = shl <2 x i32> %x, <i32 20, i32 20>
More information about the llvm-branch-commits
mailing list