-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Tell LLVM about impossible niche tags #139098
base: master
Are you sure you want to change the base?
Conversation
rustbot has assigned @compiler-errors. Use |
Some changes occurred in compiler/rustc_codegen_ssa |
c325ff6
to
98e9cb2
Compare
tests/codegen/enum/enum-match.rs
Outdated
// CHECK-LABEL: define{{.+}}i1 @match4_is_c(i8{{.+}}%e) | ||
// CHECK-NEXT: start | ||
// CHECK-NEXT: %[[REL_VAR:.+]] = add nsw i8 %e, -2 | ||
// CHECK-NEXT: %[[NOT_NICHE:.+]] = icmp ugt i8 %[[REL_VAR]], 4 | ||
// CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i8 %[[REL_VAR]], 2 | ||
// CHECK-NEXT: call void @llvm.assume(i1 %[[NOT_IMPOSSIBLE]]) | ||
// CHECK-NEXT: ret i1 %[[NOT_NICHE]] | ||
#[no_mangle] | ||
pub fn match4_is_c(e: MiddleNiche) -> bool { | ||
// Before #139098, this couldn't optimize out the `select` because it looked | ||
// like it was possible for a `2` to be produced on both sides. | ||
|
||
std::intrinsics::discriminant_value(&e) == 2 | ||
} |
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.
Compare on nightly, https://rust.godbolt.org/z/4bdKKjeG5
define noundef zeroext i1 @match4_is_c(i8 noundef range(i8 0, 7) %e) unnamed_addr {
start:
%0 = add nsw i8 %e, -2
%1 = icmp ugt i8 %0, 4
%_01 = icmp eq i8 %0, 2
%_0 = or i1 %1, %_01
ret i1 %_0
}
This comment has been minimized.
This comment has been minimized.
r? compiler |
I was trying to find a better way of emitting discriminant calculations, but sadly had no luck.
So here's a fairly small PR with the bits that did seem worth bothering:
As the
TagEncoding::Niche
docs describe, it's possible to end up with a dead value in the input that's not already communicated via the range parameter attribute nor the range load metadata attribute. So this adds anllvm.assume
in non-debug mode to tell LLVM about that. (That way it can tell that the sides of theselect
have disjoint possible values.)I'd written a bunch more tests, or at least made them parameterized, in the process of trying things out, so this checks in those tests to hopefully help future people not trip on the same weird edge cases, like when the tag type is
i8
but yet there's still a variant index and discriminant of258
which doesn't fit in that tag type because the enum is really weird.