-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[ValueTracking] Refactor isKnownNonEqualFromContext
#127388
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-transforms @llvm/pr-subscribers-llvm-analysis Author: Yingwei Zheng (dtcxzyw) ChangesThis patch avoids adding RHS for comparisons with two variable operands (#118493 (comment)). Instead, we iterate over related dominating conditions of both V1 and V2 in Compile-time improvement: https://llvm-compile-time-tracker.com/compare.php?from=c6d95c441a29a45782ff72d6cb82839b86fd0e4a&to=88464baedd7b1731281eaa0ce4438122b4d218a7&stat=instructions:u Full diff: https://github.com/llvm/llvm-project/pull/127388.diff 1 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 2a49a10447e0b..c1d3e9fd7e010 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3786,6 +3786,63 @@ static bool isNonEqualPointersWithRecursiveGEP(const Value *A, const Value *B,
(StartOffset.sle(OffsetB) && StepOffset.isNegative()));
}
+static bool isKnownNonEqualFromContext(const Value *V1, const Value *V2,
+ unsigned Depth, const SimplifyQuery &Q) {
+ if (!Q.CxtI)
+ return false;
+
+ // Try to infer NonEqual based on information from dominating conditions.
+ if (Q.DC && Q.DT) {
+ auto IsKnownNonEqualFromDominatingCondition = [&](const Value *V) {
+ for (BranchInst *BI : Q.DC->conditionsFor(V)) {
+ Value *Cond = BI->getCondition();
+ BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
+ if (Q.DT->dominates(Edge0, Q.CxtI->getParent()) &&
+ isImpliedCondition(Cond, ICmpInst::ICMP_NE, V1, V2, Q.DL,
+ /*LHSIsTrue=*/true, Depth)
+ .value_or(false))
+ return true;
+
+ BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
+ if (Q.DT->dominates(Edge1, Q.CxtI->getParent()) &&
+ isImpliedCondition(Cond, ICmpInst::ICMP_NE, V1, V2, Q.DL,
+ /*LHSIsTrue=*/false, Depth)
+ .value_or(false))
+ return true;
+ }
+
+ return false;
+ };
+
+ if (IsKnownNonEqualFromDominatingCondition(V1) ||
+ IsKnownNonEqualFromDominatingCondition(V2))
+ return true;
+ }
+
+ if (!Q.AC)
+ return false;
+
+ // Try to infer NonEqual based on information from assumptions.
+ for (auto &AssumeVH : Q.AC->assumptionsFor(V1)) {
+ if (!AssumeVH)
+ continue;
+ CallInst *I = cast<CallInst>(AssumeVH);
+
+ assert(I->getFunction() == Q.CxtI->getFunction() &&
+ "Got assumption for the wrong function!");
+ assert(I->getIntrinsicID() == Intrinsic::assume &&
+ "must be an assume intrinsic");
+
+ if (isImpliedCondition(I->getArgOperand(0), ICmpInst::ICMP_NE, V1, V2, Q.DL,
+ /*LHSIsTrue=*/true, Depth)
+ .value_or(false) &&
+ isValidAssumeForContext(I, Q.CxtI, Q.DT))
+ return true;
+ }
+
+ return false;
+}
+
/// Return true if it is known that V1 != V2.
static bool isKnownNonEqual(const Value *V1, const Value *V2,
const APInt &DemandedElts, unsigned Depth,
@@ -3857,49 +3914,8 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2,
match(V2, m_PtrToIntSameSize(Q.DL, m_Value(B))))
return isKnownNonEqual(A, B, DemandedElts, Depth + 1, Q);
- if (!Q.CxtI)
- return false;
-
- // Try to infer NonEqual based on information from dominating conditions.
- if (Q.DC && Q.DT) {
- for (BranchInst *BI : Q.DC->conditionsFor(V1)) {
- Value *Cond = BI->getCondition();
- BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
- if (Q.DT->dominates(Edge0, Q.CxtI->getParent()) &&
- isImpliedCondition(Cond, ICmpInst::ICMP_NE, V1, V2, Q.DL,
- /*LHSIsTrue=*/true, Depth)
- .value_or(false))
- return true;
-
- BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
- if (Q.DT->dominates(Edge1, Q.CxtI->getParent()) &&
- isImpliedCondition(Cond, ICmpInst::ICMP_NE, V1, V2, Q.DL,
- /*LHSIsTrue=*/false, Depth)
- .value_or(false))
- return true;
- }
- }
-
- if (!Q.AC)
- return false;
-
- // Try to infer NonEqual based on information from assumptions.
- for (auto &AssumeVH : Q.AC->assumptionsFor(V1)) {
- if (!AssumeVH)
- continue;
- CallInst *I = cast<CallInst>(AssumeVH);
-
- assert(I->getFunction() == Q.CxtI->getFunction() &&
- "Got assumption for the wrong function!");
- assert(I->getIntrinsicID() == Intrinsic::assume &&
- "must be an assume intrinsic");
-
- if (isImpliedCondition(I->getArgOperand(0), ICmpInst::ICMP_NE, V1, V2, Q.DL,
- /*LHSIsTrue=*/true, Depth)
- .value_or(false) &&
- isValidAssumeForContext(I, Q.CxtI, Q.DT))
- return true;
- }
+ if (isKnownNonEqualFromContext(V1, V2, Depth, Q))
+ return true;
return false;
}
@@ -10278,7 +10294,8 @@ void llvm::findValuesAffectedByCondition(
bool HasRHSC = match(B, m_ConstantInt());
if (ICmpInst::isEquality(Pred)) {
AddAffected(A);
- AddAffected(B);
+ if (IsAssume)
+ AddAffected(B);
if (HasRHSC) {
Value *Y;
// (X & C) or (X | C).
|
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.
Looks good to me
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.
Could you kindly add the NFC tag to the title? It's not obvious that this patch is an NFC, although the patch summary has an explanation.
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.
What's the reason for the additional diffs on llvm-opt-benchmark?
It is not NFC. See dtcxzyw/llvm-opt-benchmark#2121. The net effect is positive. |
Could add some tests extracted from the diffs? |
Case 1 (regression):
With this patch, we do not add |
Case 2 (improvement):
With this patch, we iterate over related dominating conditions of |
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, but I'm not sure if @nikic would assess the regression differently.
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.
Okay, so the differences here are because isImpliedCondition can also use things other than equality conditions, and we may pick up different "unrelated" conditions depending on how we query things.
I don't really have a strong opinion on how this query is done, so this approach is fine by me.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/3/builds/14720 Here is the relevant piece of the build log for the reference
|
This patch avoids adding RHS for comparisons with two variable operands (llvm#118493 (comment)). Instead, we iterate over related dominating conditions of both V1 and V2 in `isKnownNonEqualFromContext`, as suggested by goldsteinn (llvm#117442 (comment)). Compile-time improvement: https://llvm-compile-time-tracker.com/compare.php?from=c6d95c441a29a45782ff72d6cb82839b86fd0e4a&to=88464baedd7b1731281eaa0ce4438122b4d218a7&stat=instructions:u
This patch avoids adding RHS for comparisons with two variable operands (llvm#118493 (comment)). Instead, we iterate over related dominating conditions of both V1 and V2 in `isKnownNonEqualFromContext`, as suggested by goldsteinn (llvm#117442 (comment)). Compile-time improvement: https://llvm-compile-time-tracker.com/compare.php?from=c6d95c441a29a45782ff72d6cb82839b86fd0e4a&to=88464baedd7b1731281eaa0ce4438122b4d218a7&stat=instructions:u
This patch avoids adding RHS for comparisons with two variable operands (llvm#118493 (comment)). Instead, we iterate over related dominating conditions of both V1 and V2 in `isKnownNonEqualFromContext`, as suggested by goldsteinn (llvm#117442 (comment)). Compile-time improvement: https://llvm-compile-time-tracker.com/compare.php?from=c6d95c441a29a45782ff72d6cb82839b86fd0e4a&to=88464baedd7b1731281eaa0ce4438122b4d218a7&stat=instructions:u
This patch avoids adding RHS for comparisons with two variable operands (#118493 (comment)). Instead, we iterate over related dominating conditions of both V1 and V2 in
isKnownNonEqualFromContext
, as suggested by goldsteinn (#117442 (comment)).Compile-time improvement: https://llvm-compile-time-tracker.com/compare.php?from=c6d95c441a29a45782ff72d6cb82839b86fd0e4a&to=88464baedd7b1731281eaa0ce4438122b4d218a7&stat=instructions:u