-
Notifications
You must be signed in to change notification settings - Fork 17.9k
[InstCombine] Fold @llvm.experimental.get.vector.length when cnt <= max_lanes #169293
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
Changes from 3 commits
c61d4f2
4da2081
2f71e8a
db24622
68b9cb6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,80 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; RUN: opt < %s -passes=instcombine,verify -S | FileCheck %s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| define i32 @cnt_known_lt() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-LABEL: define i32 @cnt_known_lt() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: ret i32 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %x = call i32 @llvm.experimental.get.vector.length(i32 1, i32 2, i1 false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ret i32 %x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| define i32 @cnt_not_known_lt() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-LABEL: define i32 @cnt_not_known_lt() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: [[X:%.*]] = call i32 @llvm.experimental.get.vector.length.i32(i32 2, i32 1, i1 false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: ret i32 [[X]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %x = call i32 @llvm.experimental.get.vector.length(i32 2, i32 1, i1 false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ret i32 %x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| define i32 @cnt_known_lt_scalable() vscale_range(2, 4) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-LABEL: define i32 @cnt_known_lt_scalable( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-SAME: ) #[[ATTR0:[0-9]+]] { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: ret i32 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %x = call i32 @llvm.experimental.get.vector.length(i32 2, i32 1, i1 true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ret i32 %x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| define i32 @cnt_not_known_lt_scalable() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-LABEL: define i32 @cnt_not_known_lt_scalable() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: [[X:%.*]] = call i32 @llvm.experimental.get.vector.length.i32(i32 2, i32 1, i1 true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: ret i32 [[X]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %x = call i32 @llvm.experimental.get.vector.length(i32 2, i32 1, i1 true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ret i32 %x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| define i32 @cnt_known_lt_runtime(i32 %x) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-LABEL: define i32 @cnt_known_lt_runtime( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-SAME: i32 [[X:%.*]]) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: [[ICMP:%.*]] = icmp ult i32 [[X]], 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: call void @llvm.assume(i1 [[ICMP]]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: ret i32 [[X]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %icmp = icmp ule i32 %x, 3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| call void @llvm.assume(i1 %icmp) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %y = call i32 @llvm.experimental.get.vector.length(i32 %x, i32 3, i1 false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ret i32 %y | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| define i32 @cnt_known_lt_runtime_trunc(i64 %x) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-LABEL: define i32 @cnt_known_lt_runtime_trunc( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-SAME: i64 [[X:%.*]]) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: [[ICMP:%.*]] = icmp ult i64 [[X]], 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: call void @llvm.assume(i1 [[ICMP]]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: [[Y:%.*]] = trunc nuw nsw i64 [[X]] to i32 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: ret i32 [[Y]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %icmp = icmp ule i64 %x, 3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| call void @llvm.assume(i1 %icmp) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %y = call i32 @llvm.experimental.get.vector.length(i64 %x, i32 3, i1 false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ret i32 %y | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; FIXME: We should be able to deduce the constant range from AssumptionCache | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why doesn't this work? llvm-project/llvm/lib/Analysis/ValueTracking.cpp Lines 10303 to 10328 in 1580f4b
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Btw the reason for using
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The get.vector.length being in the recurrence makes it no longer "simple", doesn't it?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From what I can tell that is correct, I didn't see anywhere in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
matchSimpleRecurrence doesn't care what the step is so it can still handle get.vector.length in the recurrence. The only issue is that we currently don't deduce anything apart from the low zero bits in computeKnownBitsFromOperator.
Yes, we should separately add support for that too.
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index dbceb8e55784..c2ba85d4bfac 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1857,6 +1857,15 @@ static void computeKnownBitsFromOperator(const Operator *I,
Known3.countMinTrailingZeros()));
auto *OverflowOp = dyn_cast<OverflowingBinaryOperator>(BO);
+
+ if (!OverflowOp)
+ break;
+
+ if (Opcode == Instruction::Sub && Q.IIQ.hasNoUnsignedWrap(OverflowOp)) {
+ Known.Zero.setHighBits(std::min(Known2.countMinLeadingZeros(),
+ Known3.countMinLeadingZeros()));
+ }
+
Actually Known2 and Known3 weren't what I thought they were, I don't think the above is correct. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; rather than relying on KnownBits, which in this case only knows x <= 3. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| define i32 @cnt_known_lt_runtime_assumption(i32 %x) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-LABEL: define i32 @cnt_known_lt_runtime_assumption( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-SAME: i32 [[X:%.*]]) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: [[ICMP:%.*]] = icmp ult i32 [[X]], 3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: call void @llvm.assume(i1 [[ICMP]]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: [[Y:%.*]] = call i32 @llvm.experimental.get.vector.length.i32(i32 [[X]], i32 2, i1 false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; CHECK-NEXT: ret i32 [[Y]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %icmp = icmp ule i32 %x, 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| call void @llvm.assume(i1 %icmp) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| %y = call i32 @llvm.experimental.get.vector.length(i32 %x, i32 2, i1 false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ret i32 %y | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.