-
Notifications
You must be signed in to change notification settings - Fork 11.6k
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
[LVI] Use m_AddLike instead of m_Add when matching simple condition #86058
Conversation
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-transforms Author: None (goldsteinn) Changes
Full diff: https://github.com/llvm/llvm-project/pull/86058.diff 3 Files Affected:
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 9ae31d165235ca..b8bc81197c95c0 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1069,14 +1069,14 @@ static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val,
// Handle range checking idiom produced by InstCombine. We will subtract the
// offset from the allowed range for RHS in this case.
const APInt *C;
- if (match(LHS, m_Add(m_Specific(Val), m_APInt(C)))) {
+ if (match(LHS, m_AddLike(m_Specific(Val), m_APInt(C)))) {
Offset = *C;
return true;
}
// Handle the symmetric case. This appears in saturation patterns like
// (x == 16) ? 16 : (x + 1).
- if (match(Val, m_Add(m_Specific(LHS), m_APInt(C)))) {
+ if (match(Val, m_AddLike(m_Specific(LHS), m_APInt(C)))) {
Offset = -*C;
return true;
}
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
index 8dce9ef9fa4350..701d867416a13e 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
@@ -870,6 +870,33 @@ out:
ret i1 false
}
+define i1 @clamp_high1_or(i32 noundef %a) {
+; CHECK-LABEL: @clamp_high1_or(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
+; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
+; CHECK: a_guard:
+; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
+; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[A]], 1
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
+; CHECK-NEXT: ret i1 false
+; CHECK: out:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %cmp = icmp sle i32 %a, 5
+ br i1 %cmp, label %a_guard, label %out
+
+a_guard:
+ %sel_cmp = icmp eq i32 %a, 5
+ %add = or disjoint i32 %a, 1
+ %sel = select i1 %sel_cmp, i32 5, i32 %add
+ %res = icmp eq i32 %sel, 6
+ ret i1 %res
+out:
+ ret i1 false
+}
+
define i1 @clamp_high2(i32 noundef %a) {
; CHECK-LABEL: @clamp_high2(
; CHECK-NEXT: entry:
@@ -897,6 +924,35 @@ out:
ret i1 false
}
+
+define i1 @clamp_high2_or_disjoint(i32 noundef %a) {
+; CHECK-LABEL: @clamp_high2_or_disjoint(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
+; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
+; CHECK: a_guard:
+; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
+; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[A]], 1
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
+; CHECK-NEXT: ret i1 false
+; CHECK: out:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %cmp = icmp sle i32 %a, 5
+ br i1 %cmp, label %a_guard, label %out
+
+a_guard:
+ %sel_cmp = icmp ne i32 %a, 5
+ %add = or disjoint i32 %a, 1
+ %sel = select i1 %sel_cmp, i32 %add, i32 5
+ %res = icmp eq i32 %sel, 6
+ ret i1 %res
+out:
+ ret i1 false
+}
+
+
define i1 @clamp_high3(i32 noundef %a) {
; CHECK-LABEL: @clamp_high3(
; CHECK-NEXT: entry:
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index 101820a4c65f23..06292a7d644e82 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -587,6 +587,22 @@ define i1 @test_assume_cmp_with_offset(i64 %idx) {
ret i1 %cmp2
}
+define i1 @test_assume_cmp_with_offset_or(i64 %idx) {
+; CHECK-LABEL: @test_assume_cmp_with_offset_or(
+; CHECK-NEXT: [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
+; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
+; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP1]])
+; CHECK-NEXT: [[IDX_OFF2:%.*]] = or disjoint i64 [[IDX]], 1
+; CHECK-NEXT: ret i1 true
+;
+ %idx.off1 = add i64 %idx, -5
+ %cmp1 = icmp ult i64 %idx.off1, 3
+ tail call void @llvm.assume(i1 %cmp1)
+ %idx.off2 = or disjoint i64 %idx, 1
+ %cmp2 = icmp ult i64 %idx.off2, 10
+ ret i1 %cmp2
+}
+
define void @test_cmp_phi(i8 %a) {
; CHECK-LABEL: @test_cmp_phi(
; CHECK-NEXT: entry:
|
Disjoint or in the range idiom seems a bit odd to me. @dtcxzyw Can you please check whether this has any impact? |
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, it looks like there is some impact, so I guess it's fine.
However, I don't think your test coverage is right. The test in icmp.ll is not affected by the change. You need a disjoint or in the dominating condition, not at the use-site.
Sorry, was pretty lax on the tests as figured it was straight forward, will update |
We have more complete logic for handling `Add`, so try to use that logic for `or disjoint` (which can definitionally be treated as `add`).
Updated the test so it works... |
ec30a87
to
23bbdef
Compare
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.
or disjoint
like add; NFC