-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[ValueTracking] Analyze Select
in isKnownNonEqual
.
#68427
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 ChangesBasic way to recursively analyze Full diff: https://github.com/llvm/llvm-project/pull/68427.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3af5a6d9a167de4..1c284e8d85ca417 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3112,6 +3112,23 @@ 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)) {
+ if (SI1->getCondition() == SI2->getCondition())
+ 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) {
@@ -3142,6 +3159,9 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
};
}
+ if (isNonEqualSELECT(V1, V2, Depth, Q) || isNonEqualSELECT(V2, V1, Depth, Q))
+ return true;
+
if (isAddOfNonZero(V1, V2, Depth, Q) || isAddOfNonZero(V2, V1, Depth, Q))
return true;
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..1af37245c6d85a6
--- /dev/null
+++ b/llvm/test/Analysis/BasicAA/non-equal-select.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+@G = global [10 x i32] zeroinitializer, align 4
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none, inaccessiblemem: none) uwtable
+define void @select_in_gep1(i1 %c, i64 noundef %x) {
+entry:
+; CHECK: 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 noundef %x) {
+entry:
+ ; TODO: should be "NoAlias" here as well.
+; CHECK: 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
+}
|
416a152
to
579e829
Compare
579e829
to
604c83a
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
604c83a
to
cd8f051
Compare
@nikic @goldsteinn I added a new commit moving the This is necessary so that we can analyze things like |
I don't understand what you mean here. If |
Right, I just thought it's better to do cheaper checks first. |
@nikic @goldsteinn ping |
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
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`.
This is necessary so that we can analyze things like `isKnownNonEqual(X, Y)` where `X = select ... ` and `Y = shl X, 2` for example. In other words, we first should try to do the analysis without "decomposing" `select` first.
41a1dda
to
8e64ec8
Compare
Basic way to recursively analyze
select
inisKnownNonEqual
:select %c, %t, %f
is non-equal to%x
if%t
is non-equal to%x
and%f
is non-equal to%x
.