From c0dd1f24f9a73b113101816ae78b520b7d1c9f59 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Wed, 15 Nov 2023 17:31:57 +0800 Subject: [PATCH 1/2] [ValueTracking] Add support for non-splat vecs in computeConstantRange --- llvm/lib/Analysis/ValueTracking.cpp | 10 +++++++++- llvm/test/Transforms/InstCombine/add.ll | 4 +--- .../Transforms/InstCombine/addsub-constant-folding.ll | 4 ++-- llvm/test/Transforms/InstCombine/saturating-add-sub.ll | 4 +--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index dc3c90ba9db16..5f5d7e07cac1e 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(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(V)) { APInt Lower = APInt(BitWidth, 0); diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll index 1079f4fab1cd8..2ae0181974bf8 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> , [[A:%.*]] +; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> , [[A:%.*]] ; CHECK-NEXT: ret <2 x i8> [[C]] ; %B = xor <2 x i8> %A, diff --git a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll index 83a45e697e59e..3dbd80c773d14 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> , [[ARG:%.*]] +; CHECK-NEXT: [[T1:%.*]] = sub nsw <2 x i8> , [[ARG:%.*]] ; CHECK-NEXT: ret <2 x i8> [[T1]] ; %t0 = add nsw <2 x i8> %arg, @@ -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> , [[ARG:%.*]] +; CHECK-NEXT: [[T1:%.*]] = sub nsw <2 x i8> , [[ARG:%.*]] ; CHECK-NEXT: ret <2 x i8> [[T1]] ; %t0 = add nsw <2 x i8> %arg, diff --git a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll index 612c5bf77462d..c1bb6941d4568 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:%.*]], -; CHECK-NEXT: [[R:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[B]], <2 x i8> ) +; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[A:%.*]], ; CHECK-NEXT: ret <2 x i8> [[R]] ; %b = add nuw <2 x i8> %a, From e9282398cda22d705e438b935d0bea394dc93fd6 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Wed, 15 Nov 2023 19:49:30 +0800 Subject: [PATCH 2/2] fixup! [ValueTracking] Add support for non-splat vecs in computeConstantRange --- llvm/test/Transforms/InstCombine/addsub-constant-folding.ll | 3 --- 1 file changed, 3 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll index 3dbd80c773d14..6a6bf74d6152f 100644 --- a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll +++ b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll @@ -203,8 +203,6 @@ define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov1(<2 x i8> %arg ret <2 x i8> %t1 } - -; 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 nsw <2 x i8> , [[ARG:%.*]] @@ -215,7 +213,6 @@ define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2(<2 x i8> %arg ret <2 x i8> %t1 } -; 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 nsw <2 x i8> , [[ARG:%.*]]