-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: