From b6052371165c423caa175c3261e0c8500452dcdf Mon Sep 17 00:00:00 2001 From: Mikhail Gudim Date: Wed, 4 Oct 2023 15:58:29 -0400 Subject: [PATCH 1/3] [ValueTracking] Try to infer range of select from true and false values. When computing range of `select` instruction, first compute the union of ranges of "True" and "False" operands of the `select` instruction. --- llvm/lib/Analysis/ValueTracking.cpp | 11 ++++++++--- .../ValueTracking/constant-range-select.ll | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Analysis/ValueTracking/constant-range-select.ll diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index b76becf24d10f..f5b18785d4869 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8841,9 +8841,14 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned, CR = ConstantRange::getNonEmpty(Lower, Upper); } else if (auto *II = dyn_cast(V)) CR = getRangeForIntrinsic(*II); - else if (auto *SI = dyn_cast(V)) - CR = getRangeForSelectPattern(*SI, IIQ); - else if (isa(V) || isa(V)) { + else if (auto *SI = dyn_cast(V)) { + ConstantRange CRTrue = computeConstantRange( + SI->getTrueValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1); + ConstantRange CRFalse = computeConstantRange( + SI->getFalseValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1); + CR = CRTrue.unionWith(CRFalse); + CR = CR.intersectWith(getRangeForSelectPattern(*SI, IIQ)); + } else if (isa(V) || isa(V)) { APInt Lower = APInt(BitWidth, 0); APInt Upper = APInt(BitWidth, 0); // TODO: Return ConstantRange. diff --git a/llvm/test/Analysis/ValueTracking/constant-range-select.ll b/llvm/test/Analysis/ValueTracking/constant-range-select.ll new file mode 100644 index 0000000000000..353fa7e1cf5dd --- /dev/null +++ b/llvm/test/Analysis/ValueTracking/constant-range-select.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s + +@a = dso_local local_unnamed_addr global [10 x i32] zeroinitializer, align 4 + +; CHECK-LABEL: Function: select_in_gep +; CHECK: NoAlias: i32* %arrayidx, i32* getelementptr inbounds ([10 x i32], ptr @a, i64 0, i64 3) +define i32 @select_in_gep(i1 %c) { +entry: + %cond = select i1 %c, i64 2, i64 1 + %0 = load i32, ptr getelementptr inbounds ([10 x i32], ptr @a, i64 0, i64 3), align 4 + %arrayidx = getelementptr inbounds [10 x i32], ptr @a, i64 0, i64 %cond + store i32 %0, ptr %arrayidx, align 4 + %1 = load i32, ptr getelementptr inbounds ([10 x i32], ptr @a, i64 0, i64 3), align 4 + ret i32 %1 +} From da18398115605889f56b3832916232feff61c4c5 Mon Sep 17 00:00:00 2001 From: Mikhail Gudim Date: Wed, 4 Oct 2023 17:41:03 -0400 Subject: [PATCH 2/3] Fixed failing test. --- llvm/test/Transforms/InstCombine/binop-select.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/binop-select.ll b/llvm/test/Transforms/InstCombine/binop-select.ll index a59e19897f061..6cd4132eadd77 100644 --- a/llvm/test/Transforms/InstCombine/binop-select.ll +++ b/llvm/test/Transforms/InstCombine/binop-select.ll @@ -324,12 +324,12 @@ define i32 @sub_sel_op1_use(i1 %b) { ; CHECK-LABEL: @sub_sel_op1_use( ; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 42, i32 41 ; CHECK-NEXT: call void @use(i32 [[S]]) -; CHECK-NEXT: [[R:%.*]] = sub nsw i32 42, [[S]] +; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i32 42, [[S]] ; CHECK-NEXT: ret i32 [[R]] ; %s = select i1 %b, i32 42, i32 41 call void @use(i32 %s) - %r = sub nsw i32 42, %s + %r = sub nuw nsw i32 42, %s ret i32 %r } From c499f0d1027b65bdd3ab27fa1f8a164370a00614 Mon Sep 17 00:00:00 2001 From: Mikhail Gudim Date: Thu, 5 Oct 2023 10:09:37 -0400 Subject: [PATCH 3/3] Addressed review comments. --- llvm/test/Analysis/BasicAA/range.ll | 14 +++++++++++++- .../ValueTracking/constant-range-select.ll | 15 --------------- 2 files changed, 13 insertions(+), 16 deletions(-) delete mode 100644 llvm/test/Analysis/ValueTracking/constant-range-select.ll diff --git a/llvm/test/Analysis/BasicAA/range.ll b/llvm/test/Analysis/BasicAA/range.ll index 3862e26ee49a4..e5dfb60c8b878 100644 --- a/llvm/test/Analysis/BasicAA/range.ll +++ b/llvm/test/Analysis/BasicAA/range.ll @@ -2,6 +2,7 @@ %struct.S = type { i32, [2 x i32], i32 } %struct.S2 = type { i32, [4 x i32], [4 x i32] } +@G = global [10 x i32] zeroinitializer, align 4 ; CHECK: Function: t1 ; CHECK: NoAlias: i32* %gep1, i32* %gep2 @@ -258,8 +259,19 @@ join: ret void } -declare void @llvm.assume(i1) +; CHECK-LABEL: Function: select_in_gep +; CHECK: NoAlias: i32* %arrayidx, i32* getelementptr inbounds ([10 x i32], ptr @G, i64 0, i64 3) +define i32 @select_in_gep(i1 %c) { +entry: + %select_ = select i1 %c, i64 2, i64 1 + %arrayidx = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select_ + store i32 42, ptr %arrayidx, align 4 + %load_ = load i32, ptr getelementptr inbounds ([10 x i32], ptr @G, i64 0, i64 3), align 4 + ret i32 %load_ +} + +declare void @llvm.assume(i1) !0 = !{ i32 0, i32 2 } !1 = !{ i32 0, i32 1 } diff --git a/llvm/test/Analysis/ValueTracking/constant-range-select.ll b/llvm/test/Analysis/ValueTracking/constant-range-select.ll deleted file mode 100644 index 353fa7e1cf5dd..0000000000000 --- a/llvm/test/Analysis/ValueTracking/constant-range-select.ll +++ /dev/null @@ -1,15 +0,0 @@ -; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s - -@a = dso_local local_unnamed_addr global [10 x i32] zeroinitializer, align 4 - -; CHECK-LABEL: Function: select_in_gep -; CHECK: NoAlias: i32* %arrayidx, i32* getelementptr inbounds ([10 x i32], ptr @a, i64 0, i64 3) -define i32 @select_in_gep(i1 %c) { -entry: - %cond = select i1 %c, i64 2, i64 1 - %0 = load i32, ptr getelementptr inbounds ([10 x i32], ptr @a, i64 0, i64 3), align 4 - %arrayidx = getelementptr inbounds [10 x i32], ptr @a, i64 0, i64 %cond - store i32 %0, ptr %arrayidx, align 4 - %1 = load i32, ptr getelementptr inbounds ([10 x i32], ptr @a, i64 0, i64 3), align 4 - ret i32 %1 -}