[llvm] [ValueTracking] Try to infer range of select from true and false values. (PR #68256)

Mikhail Gudim via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 5 07:30:42 PDT 2023


https://github.com/mgudim updated https://github.com/llvm/llvm-project/pull/68256

>From b6052371165c423caa175c3261e0c8500452dcdf Mon Sep 17 00:00:00 2001
From: Mikhail Gudim <mgudim at gmail.com>
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 b76becf24d10fc9..f5b18785d4869e0 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<IntrinsicInst>(V))
     CR = getRangeForIntrinsic(*II);
-  else if (auto *SI = dyn_cast<SelectInst>(V))
-    CR = getRangeForSelectPattern(*SI, IIQ);
-  else if (isa<FPToUIInst>(V) || isa<FPToSIInst>(V)) {
+  else if (auto *SI = dyn_cast<SelectInst>(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<FPToUIInst>(V) || isa<FPToSIInst>(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 000000000000000..353fa7e1cf5dd33
--- /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
+
+ at 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 <mgudim at gmail.com>
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 a59e19897f061d1..6cd4132eadd77b9 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 <mgudim at gmail.com>
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 3862e26ee49a4ba..e5dfb60c8b8784b 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] }
+ at 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 353fa7e1cf5dd33..000000000000000
--- 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
-
- at 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
-}



More information about the llvm-commits mailing list