-
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
Unneeded call to panic!() #73031
Comments
This optimizes well with u8pub fn foo(a: &mut u8, q: i32) -> i32 {
*a = if q == 5 {
1
} else {
2
};
match *a {
1 => 1,
2 => 2,
_ => unreachable!(),
}
} example::foo:
xor ecx, ecx
cmp esi, 5
sete cl
mov al, 2
sub al, cl
mov byte ptr [rdi], al
mov eax, 2
sub eax, ecx
ret With an enum, the important part of the optimized LLVM IR looks like this: start:
%_4 = icmp eq i32 %q, 5
%. = select i1 %_4, i8 1, i8 2
store i8 %., i8* %a, align 1
%_6 = zext i8 %. to i64
switch i64 %_6, label %bb5 [
i64 0, label %bb4
i64 1, label %bb8
i64 2, label %bb7
] And with start:
%_4 = icmp eq i32 %q, 5
%. = select i1 %_4, i8 1, i8 2
store i8 %., i8* %a, align 1
%spec.select = select i1 %_4, i32 1, i32 2
ret i32 %spec.select So it seems that LLVM doesn't propagate value ranges though u8 as u64pub fn foo(a: &mut u8, q: i32) -> i32 {
*a = if q == 5 {
1
} else {
2
};
match *a as u64 {
1 => 1,
2 => 2,
_ => unreachable!(),
}
} example::foo:
push rax
xor r8d, r8d
cmp esi, 5
sete dl
mov cl, 2
sub cl, dl
mov byte ptr [rdi], cl
mov eax, 1
cmp cl, 1
je .LBB5_3
mov r8b, dl
mov eax, 2
sub rax, r8
cmp rax, 2
jne .LBB5_4
mov eax, 2
.LBB5_3:
pop rcx
ret
.LBB5_4:
call std::panicking::begin_panic
ud2 With an enum, various things that make the size of the discriminant the same as the size of the enum in memory (hence avoiding the enums// this generates a panic branch
pub enum All {
None = 0,
Foo = 1,
Bar = 2,
}
// these do not
#[repr(u8)]
pub enum All {
None,
Foo,
Bar,
}
pub enum All {
None = 1,
Foo = 2,
Bar = 3,
}
pub enum All {
None,
Foo,
Bar = 3,
}
pub enum All {
None = -1,
Foo,
Bar,
} I don't know why rustc does this. I assume it has something to do with the default discriminant type being Edit: it seems that LLVM is able to see through the zext in...some cases. I can't tell why, and it doesn't really seem to help us. See: https://godbolt.org/z/W8SeHC. |
I've filed the upstream issue: https://bugs.llvm.org/show_bug.cgi?id=46244 @eddyb is it possible for us to avoid the |
@rustbot modify labels: +A-LLVM |
Like #77812 (comment), this will be fixed in LLVM 12: https://llvm.godbolt.org/z/jxjEbq |
Seems to be fixed on the latest nightly by #81451 |
Add codegen tests for some issues closed by LLVM 12 Namely rust-lang#73031, rust-lang#75546, and rust-lang#77812
The following:
compiles to:
The
unreachable!
and should be eliminatedThe text was updated successfully, but these errors were encountered: