[llvm] 9abf3df - [ValueTracking] Analyze `Select` in `isKnownNonEqual`. (#68427)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 24 22:08:45 PDT 2023


Author: Mikhail Gudim
Date: 2023-10-25T01:08:40-04:00
New Revision: 9abf3df111793831dd2fb6dce4cf34c84a5277dc

URL: https://github.com/llvm/llvm-project/commit/9abf3df111793831dd2fb6dce4cf34c84a5277dc
DIFF: https://github.com/llvm/llvm-project/commit/9abf3df111793831dd2fb6dce4cf34c84a5277dc.diff

LOG: [ValueTracking] Analyze `Select` in `isKnownNonEqual`. (#68427)

Basic way to recursively analyze `select` in `isKnownNonEqual`: `select
%c, %t, %f` is non-equal to `%x` if `%t` is non-equal to `%x` and `%f`
is non-equal to `%x`.

Added: 
    llvm/test/Analysis/BasicAA/non-equal-select.ll

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f510f6a42f08c12..c303d261107eb19 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3122,6 +3122,25 @@ static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
   return true;
 }
 
+static bool isNonEqualSelect(const Value *V1, const Value *V2, unsigned Depth,
+                             const SimplifyQuery &Q) {
+  const SelectInst *SI1 = dyn_cast<SelectInst>(V1);
+  if (!SI1)
+    return false;
+
+  if (const SelectInst *SI2 = dyn_cast<SelectInst>(V2)) {
+    const Value *Cond1 = SI1->getCondition();
+    const Value *Cond2 = SI2->getCondition();
+    if (Cond1 == Cond2)
+      return isKnownNonEqual(SI1->getTrueValue(), SI2->getTrueValue(),
+                             Depth + 1, Q) &&
+             isKnownNonEqual(SI1->getFalseValue(), SI2->getFalseValue(),
+                             Depth + 1, Q);
+  }
+  return isKnownNonEqual(SI1->getTrueValue(), V2, Depth + 1, Q) &&
+         isKnownNonEqual(SI1->getFalseValue(), V2, Depth + 1, Q);
+}
+
 /// Return true if it is known that V1 != V2.
 static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
                             const SimplifyQuery &Q) {
@@ -3171,6 +3190,10 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
         Known2.Zero.intersects(Known1.One))
       return true;
   }
+
+  if (isNonEqualSelect(V1, V2, Depth, Q) || isNonEqualSelect(V2, V1, Depth, Q))
+    return true;
+
   return false;
 }
 

diff  --git a/llvm/test/Analysis/BasicAA/non-equal-select.ll b/llvm/test/Analysis/BasicAA/non-equal-select.ll
new file mode 100644
index 000000000000000..fe38a57eeb1b477
--- /dev/null
+++ b/llvm/test/Analysis/BasicAA/non-equal-select.ll
@@ -0,0 +1,79 @@
+; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+ at G = global [10 x i32] zeroinitializer, align 4
+
+define void @select_in_gep1(i1 %c, i64 %x) {
+entry:
+; CHECK-LABEL: Function: select_in_gep1
+; CHECK: NoAlias: i32* %arrayidx1, i32* %arrayidx2
+  %add1_ = add nsw i64 %x, 1
+  %add2_ = add nsw i64 %x, 2
+  %select_ = select i1 %c, i64 %add1_, i64 %add2_
+  %arrayidx1 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select_
+  store i32 42, ptr %arrayidx1, align 4
+  %arrayidx2 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %x
+  store i32 43, ptr %arrayidx2, align 4
+  ret void
+}
+
+define void @select_in_gep2(i1 %c, i64 %x) {
+entry:
+  ; TODO: should be "NoAlias" here as well.
+; CHECK-LABEL: Function: select_in_gep2
+; CHECK: MayAlias:     i32* %arrayidx1, i32* %arrayidx2
+  %add1_ = add nsw i64 %x, 1
+  %add2_ = add nsw i64 %x, 2
+  %add3_ = add nsw i64 %x, 3
+  %select_ = select i1 %c, i64 %add1_, i64 %add2_
+  %arrayidx1 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select_
+  store i32 42, ptr %arrayidx1, align 4
+  %arrayidx2 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %add3_
+  store i32 43, ptr %arrayidx2, align 4
+  ret void
+}
+
+define void @two_selects_in_gep_same_cond(i1 %c, i64 %x) {
+entry:
+; CHECK-LABEL: Function: two_selects_in_gep_same_cond
+; CHECK: NoAlias: i32* %arrayidx1, i32* %arrayidx2
+  %add1_ = add nsw i64 %x, 1
+  %add2_ = add nsw i64 %x, 2
+  %select1_ = select i1 %c, i64 %x, i64 %add1_
+  %select2_ = select i1 %c, i64 %add2_, i64 %x
+  %arrayidx1 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select1_
+  store i32 42, ptr %arrayidx1, align 4
+  %arrayidx2 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select2_
+  store i32 43, ptr %arrayidx2, align 4
+  ret void
+}
+
+define void @two_selects_in_gep_
diff erent_cond1(i1 %c1, i1 %c2, i64 %x) {
+entry:
+; CHECK-LABEL: Function: two_selects_in_gep_
diff erent_cond1
+; CHECK: NoAlias: i32* %arrayidx1, i32* %arrayidx2
+  %add1_ = add nsw i64 %x, 1
+  %add2_ = add nsw i64 %x, 2
+  %add3_ = add nsw i64 %x, 3
+  %add4_ = add nsw i64 %x, 4
+  %select1_ = select i1 %c1, i64 %add1_, i64 %add2_
+  %select2_ = select i1 %c2, i64 %add3_, i64 %add4_
+  %arrayidx1 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select1_
+  store i32 42, ptr %arrayidx1, align 4
+  %arrayidx2 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select2_
+  store i32 43, ptr %arrayidx2, align 4
+  ret void
+}
+
+define void @two_selects_in_gep_
diff erent_cond2(i1 %c1, i1 %c2, i64 %x) {
+entry:
+; CHECK-LABEL: Function: two_selects_in_gep_
diff erent_cond2
+; CHECK: MayAlias: i32* %arrayidx1, i32* %arrayidx2
+  %add1_ = add nsw i64 %x, 1
+  %add2_ = add nsw i64 %x, 2
+  %select1_ = select i1 %c1, i64 %x, i64 %add1_
+  %select2_ = select i1 %c2, i64 %x, i64 %add2_
+  %arrayidx1 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select1_
+  store i32 42, ptr %arrayidx1, align 4
+  %arrayidx2 = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select2_
+  store i32 43, ptr %arrayidx2, align 4
+  ret void
+}


        


More information about the llvm-commits mailing list