-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[ValueTracking] Add support for non-splat vecs in computeConstantRange #72365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-llvm-analysis Author: Yingwei Zheng (dtcxzyw) ChangesRelated patch: #68331 Full diff: https://github.com/llvm/llvm-project/pull/72365.diff 4 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index dc3c90ba9db1664..5f5d7e07cac1e46 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8871,9 +8871,17 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
const APInt *C;
if (match(V, m_APInt(C)))
return ConstantRange(*C);
+ unsigned BitWidth = V->getType()->getScalarSizeInBits();
+
+ if (auto *VC = dyn_cast<ConstantDataVector>(V)) {
+ ConstantRange CR = ConstantRange::getEmpty(BitWidth);
+ for (unsigned ElemIdx = 0, NElem = VC->getNumElements(); ElemIdx < NElem;
+ ++ElemIdx)
+ CR = CR.unionWith(VC->getElementAsAPInt(ElemIdx));
+ return CR;
+ }
InstrInfoQuery IIQ(UseInstrInfo);
- unsigned BitWidth = V->getType()->getScalarSizeInBits();
ConstantRange CR = ConstantRange::getFull(BitWidth);
if (auto *BO = dyn_cast<BinaryOperator>(V)) {
APInt Lower = APInt(BitWidth, 0);
diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 1079f4fab1cd8e1..2ae0181974bf8a6 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -440,11 +440,9 @@ define <2 x i8> @test18vec_nsw(<2 x i8> %A) {
ret <2 x i8> %C
}
-; TODO: fix ValueTracking overflow check for non-splat vector, could be attached nsw
-; this shouldn't overflow.
define <2 x i8> @test18vec_nsw_false(<2 x i8> %A) {
; CHECK-LABEL: @test18vec_nsw_false(
-; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> <i8 -125, i8 -126>, [[A:%.*]]
+; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> <i8 -125, i8 -126>, [[A:%.*]]
; CHECK-NEXT: ret <2 x i8> [[C]]
;
%B = xor <2 x i8> %A, <i8 -1, i8 -1>
diff --git a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
index 83a45e697e59e16..3dbd80c773d141d 100644
--- a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
+++ b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
@@ -207,7 +207,7 @@ define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov1(<2 x i8> %arg
; TODO: We can add nsw on sub, current Value Tracking use [max element,min element] constant range, to check overflow for vector?
define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2(<2 x i8> %arg) {
; CHECK-LABEL: @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2(
-; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> <i8 -126, i8 -128>, [[ARG:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = sub nsw <2 x i8> <i8 -126, i8 -128>, [[ARG:%.*]]
; CHECK-NEXT: ret <2 x i8> [[T1]]
;
%t0 = add nsw <2 x i8> %arg, <i8 1, i8 2>
@@ -218,7 +218,7 @@ define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2(<2 x i8> %arg
; TODO: We can add nsw on sub, curret Value Tracking can't decide this is not overflowed?
define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov3(<2 x i8> %arg) {
; CHECK-LABEL: @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov3(
-; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> <i8 -120, i8 -127>, [[ARG:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = sub nsw <2 x i8> <i8 -120, i8 -127>, [[ARG:%.*]]
; CHECK-NEXT: ret <2 x i8> [[T1]]
;
%t0 = add nsw <2 x i8> %arg, <i8 0, i8 1>
diff --git a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
index 612c5bf77462d4b..c1bb6941d456836 100644
--- a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
@@ -1052,11 +1052,9 @@ define <2 x i8> @test_vector_usub_add_nuw_no_ov(<2 x i8> %a) {
ret <2 x i8> %r
}
-; Can be optimized if the usub.sat RHS constant range handles non-splat vectors.
define <2 x i8> @test_vector_usub_add_nuw_no_ov_nonsplat1(<2 x i8> %a) {
; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov_nonsplat1(
-; CHECK-NEXT: [[B:%.*]] = add nuw <2 x i8> [[A:%.*]], <i8 10, i8 10>
-; CHECK-NEXT: [[R:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[B]], <2 x i8> <i8 10, i8 9>)
+; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[A:%.*]], <i8 0, i8 1>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%b = add nuw <2 x i8> %a, <i8 10, i8 10>
|
|
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesRelated patch: #68331 Full diff: https://github.com/llvm/llvm-project/pull/72365.diff 4 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index dc3c90ba9db1664..5f5d7e07cac1e46 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8871,9 +8871,17 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
const APInt *C;
if (match(V, m_APInt(C)))
return ConstantRange(*C);
+ unsigned BitWidth = V->getType()->getScalarSizeInBits();
+
+ if (auto *VC = dyn_cast<ConstantDataVector>(V)) {
+ ConstantRange CR = ConstantRange::getEmpty(BitWidth);
+ for (unsigned ElemIdx = 0, NElem = VC->getNumElements(); ElemIdx < NElem;
+ ++ElemIdx)
+ CR = CR.unionWith(VC->getElementAsAPInt(ElemIdx));
+ return CR;
+ }
InstrInfoQuery IIQ(UseInstrInfo);
- unsigned BitWidth = V->getType()->getScalarSizeInBits();
ConstantRange CR = ConstantRange::getFull(BitWidth);
if (auto *BO = dyn_cast<BinaryOperator>(V)) {
APInt Lower = APInt(BitWidth, 0);
diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 1079f4fab1cd8e1..2ae0181974bf8a6 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -440,11 +440,9 @@ define <2 x i8> @test18vec_nsw(<2 x i8> %A) {
ret <2 x i8> %C
}
-; TODO: fix ValueTracking overflow check for non-splat vector, could be attached nsw
-; this shouldn't overflow.
define <2 x i8> @test18vec_nsw_false(<2 x i8> %A) {
; CHECK-LABEL: @test18vec_nsw_false(
-; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> <i8 -125, i8 -126>, [[A:%.*]]
+; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> <i8 -125, i8 -126>, [[A:%.*]]
; CHECK-NEXT: ret <2 x i8> [[C]]
;
%B = xor <2 x i8> %A, <i8 -1, i8 -1>
diff --git a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
index 83a45e697e59e16..3dbd80c773d141d 100644
--- a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
+++ b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
@@ -207,7 +207,7 @@ define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov1(<2 x i8> %arg
; TODO: We can add nsw on sub, current Value Tracking use [max element,min element] constant range, to check overflow for vector?
define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2(<2 x i8> %arg) {
; CHECK-LABEL: @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2(
-; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> <i8 -126, i8 -128>, [[ARG:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = sub nsw <2 x i8> <i8 -126, i8 -128>, [[ARG:%.*]]
; CHECK-NEXT: ret <2 x i8> [[T1]]
;
%t0 = add nsw <2 x i8> %arg, <i8 1, i8 2>
@@ -218,7 +218,7 @@ define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2(<2 x i8> %arg
; TODO: We can add nsw on sub, curret Value Tracking can't decide this is not overflowed?
define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov3(<2 x i8> %arg) {
; CHECK-LABEL: @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov3(
-; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> <i8 -120, i8 -127>, [[ARG:%.*]]
+; CHECK-NEXT: [[T1:%.*]] = sub nsw <2 x i8> <i8 -120, i8 -127>, [[ARG:%.*]]
; CHECK-NEXT: ret <2 x i8> [[T1]]
;
%t0 = add nsw <2 x i8> %arg, <i8 0, i8 1>
diff --git a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
index 612c5bf77462d4b..c1bb6941d456836 100644
--- a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
@@ -1052,11 +1052,9 @@ define <2 x i8> @test_vector_usub_add_nuw_no_ov(<2 x i8> %a) {
ret <2 x i8> %r
}
-; Can be optimized if the usub.sat RHS constant range handles non-splat vectors.
define <2 x i8> @test_vector_usub_add_nuw_no_ov_nonsplat1(<2 x i8> %a) {
; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov_nonsplat1(
-; CHECK-NEXT: [[B:%.*]] = add nuw <2 x i8> [[A:%.*]], <i8 10, i8 10>
-; CHECK-NEXT: [[R:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[B]], <2 x i8> <i8 10, i8 9>)
+; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[A:%.*]], <i8 0, i8 1>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%b = add nuw <2 x i8> %a, <i8 10, i8 10>
|
nikic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
llvm#72365) Related patch: llvm#68331 This missed optimization is discovered with the help of AliveToolkit/alive2#962.
Related patch: #68331
This missed optimization is discovered with the help of AliveToolkit/alive2#962.