-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[ValueTracking] Compute knownbits for (and/or cond0, cond1)
on both sides of branch
#82818
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
…h sides of branch; NFC
@llvm/pr-subscribers-llvm-analysis Author: None (goldsteinn) Changes
Full diff: https://github.com/llvm/llvm-project/pull/82818.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 653b3d4ffd9883..562b1e574aea4d 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -711,10 +711,17 @@ static void computeKnownBitsFromCond(const Value *V, Value *Cond,
const SimplifyQuery &SQ, bool Invert) {
Value *A, *B;
if (Depth < MaxAnalysisRecursionDepth &&
- (Invert ? match(Cond, m_LogicalOr(m_Value(A), m_Value(B)))
- : match(Cond, m_LogicalAnd(m_Value(A), m_Value(B))))) {
- computeKnownBitsFromCond(V, A, Known, Depth + 1, SQ, Invert);
- computeKnownBitsFromCond(V, B, Known, Depth + 1, SQ, Invert);
+ match(Cond, m_LogicalOp(m_Value(A), m_Value(B)))) {
+ KnownBits Known2(Known.getBitWidth());
+ KnownBits Known3(Known.getBitWidth());
+ computeKnownBitsFromCond(V, A, Known2, Depth + 1, SQ, Invert);
+ computeKnownBitsFromCond(V, B, Known3, Depth + 1, SQ, Invert);
+ if (Invert ? match(Cond, m_LogicalOr(m_Value(A), m_Value(B)))
+ : match(Cond, m_LogicalAnd(m_Value(A), m_Value(B))))
+ Known = Known2.unionWith(Known3);
+ else
+ Known2 = Known2.intersectWith(Known3);
+ Known = Known.unionWith(Known2);
}
if (auto *Cmp = dyn_cast<ICmpInst>(Cond))
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index 246579cc4cd0c0..b658ee0d2ef4e2 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -124,6 +124,65 @@ exit:
ret i8 %or2
}
+
+define i8 @test_cond_and_bothways(i8 %x) {
+; CHECK-LABEL: @test_cond_and_bothways(
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 91
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i8 [[AND]], 24
+; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[X]], 0
+; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
+; CHECK: if:
+; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
+; CHECK-NEXT: ret i8 [[OR1]]
+; CHECK: exit:
+; CHECK-NEXT: ret i8 -4
+;
+ %and = and i8 %x, 91
+ %cmp0 = icmp ne i8 %and, 24
+ %cmp1 = icmp ne i8 %x, 0
+ %cond = and i1 %cmp0, %cmp1
+ br i1 %cond, label %if, label %exit
+
+if:
+ %or1 = or i8 %x, -4
+ ret i8 %or1
+
+exit:
+ %or2 = or i8 %x, -4
+ ret i8 %or2
+}
+
+define i8 @test_cond_or_bothways(i8 %x) {
+; CHECK-LABEL: @test_cond_or_bothways(
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 91
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i8 [[AND]], 24
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 0
+; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i8 -4
+; CHECK: exit:
+; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
+; CHECK-NEXT: ret i8 [[OR2]]
+;
+ %and = and i8 %x, 91
+ %cmp0 = icmp eq i8 %and, 24
+ %cmp1 = icmp eq i8 %x, 0
+ %cond = or i1 %cmp0, %cmp1
+ br i1 %cond, label %if, label %exit
+
+if:
+ %or1 = or i8 %x, -4
+ ret i8 %or1
+
+exit:
+ %or2 = or i8 %x, -4
+ ret i8 %or2
+}
+
+
+
define i8 @test_cond_and_commuted(i8 %x, i1 %c1, i1 %c2) {
; CHECK-LABEL: @test_cond_and_commuted(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
|
@llvm/pr-subscribers-llvm-transforms Author: None (goldsteinn) Changes
Full diff: https://github.com/llvm/llvm-project/pull/82818.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 653b3d4ffd9883..562b1e574aea4d 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -711,10 +711,17 @@ static void computeKnownBitsFromCond(const Value *V, Value *Cond,
const SimplifyQuery &SQ, bool Invert) {
Value *A, *B;
if (Depth < MaxAnalysisRecursionDepth &&
- (Invert ? match(Cond, m_LogicalOr(m_Value(A), m_Value(B)))
- : match(Cond, m_LogicalAnd(m_Value(A), m_Value(B))))) {
- computeKnownBitsFromCond(V, A, Known, Depth + 1, SQ, Invert);
- computeKnownBitsFromCond(V, B, Known, Depth + 1, SQ, Invert);
+ match(Cond, m_LogicalOp(m_Value(A), m_Value(B)))) {
+ KnownBits Known2(Known.getBitWidth());
+ KnownBits Known3(Known.getBitWidth());
+ computeKnownBitsFromCond(V, A, Known2, Depth + 1, SQ, Invert);
+ computeKnownBitsFromCond(V, B, Known3, Depth + 1, SQ, Invert);
+ if (Invert ? match(Cond, m_LogicalOr(m_Value(A), m_Value(B)))
+ : match(Cond, m_LogicalAnd(m_Value(A), m_Value(B))))
+ Known = Known2.unionWith(Known3);
+ else
+ Known2 = Known2.intersectWith(Known3);
+ Known = Known.unionWith(Known2);
}
if (auto *Cmp = dyn_cast<ICmpInst>(Cond))
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index 246579cc4cd0c0..b658ee0d2ef4e2 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -124,6 +124,65 @@ exit:
ret i8 %or2
}
+
+define i8 @test_cond_and_bothways(i8 %x) {
+; CHECK-LABEL: @test_cond_and_bothways(
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 91
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i8 [[AND]], 24
+; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[X]], 0
+; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
+; CHECK: if:
+; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
+; CHECK-NEXT: ret i8 [[OR1]]
+; CHECK: exit:
+; CHECK-NEXT: ret i8 -4
+;
+ %and = and i8 %x, 91
+ %cmp0 = icmp ne i8 %and, 24
+ %cmp1 = icmp ne i8 %x, 0
+ %cond = and i1 %cmp0, %cmp1
+ br i1 %cond, label %if, label %exit
+
+if:
+ %or1 = or i8 %x, -4
+ ret i8 %or1
+
+exit:
+ %or2 = or i8 %x, -4
+ ret i8 %or2
+}
+
+define i8 @test_cond_or_bothways(i8 %x) {
+; CHECK-LABEL: @test_cond_or_bothways(
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 91
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i8 [[AND]], 24
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 0
+; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i8 -4
+; CHECK: exit:
+; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
+; CHECK-NEXT: ret i8 [[OR2]]
+;
+ %and = and i8 %x, 91
+ %cmp0 = icmp eq i8 %and, 24
+ %cmp1 = icmp eq i8 %x, 0
+ %cond = or i1 %cmp0, %cmp1
+ br i1 %cond, label %if, label %exit
+
+if:
+ %or1 = or i8 %x, -4
+ ret i8 %or1
+
+exit:
+ %or2 = or i8 %x, -4
+ ret i8 %or2
+}
+
+
+
define i8 @test_cond_and_commuted(i8 %x, i1 %c1, i1 %c2) {
; CHECK-LABEL: @test_cond_and_commuted(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
|
(and/or cond0, cond1)
on both sides of branch
b43f0da
to
a6a7dcd
Compare
@dtcxzyw Can you please rerun the tests? @goldsteinn What's the compile-time impact? |
No meaningful affect: |
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.
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.
You'll also have to adjust the logic in DomCondCache to recurse into all and/or, not just ones that match the top-level type. Unless you intentionally only want to handle the inverted type at the top level?
Please recheck compile-time impact after doing that.
… sides of branch The false branch for `and` and true branch for `or` provide less information (intersection as opposed to union), but still can give some useful information.
a6a7dcd
to
69d7bdd
Compare
Mostly minimal with two notable regressions: |
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
The false branch for
and
and true branch foror
provide lessinformation (intersection as opposed to union), but still can give
some useful information.