Auto merge of #87794 - bonega:enum_niche_prefer_zero, r=nagisa
Enum should prefer discriminant zero for niche
Given an enum with unassigned zero-discriminant, rust should prefer it for niche selection.
Zero as discriminant for `Option<Enum>` makes it possible for LLVM to optimize resulting asm.
- Eliminate branch when expected value coincides.
- Use smaller instruction `test eax, eax` instead of `cmp eax, ?`
- Possible interaction with zeroed memory?
Example:
```rust
pub enum Size {
One = 1,
Two = 2,
Three = 3,
}
pub fn handle(x: Option<Size>) -> u8 {
match x {
None => {0}
Some(size) => {size as u8}
}
}
```
In this case discriminant zero is available as a niche.
Above example on nightly:
```asm
mov eax, edi
cmp al, 4
jne .LBB0_2
xor eax, eax
.LBB0_2:
ret
```
PR:
```asm
mov eax, edi
ret
```
I created this PR because I had a performance regression when I tried to use an enum to represent legal grapheme byte-length for utf8.
Using an enum instead of `NonZeroU8` [here](d683304f5d/src/internal/decoder_incomplete.rs (L90))
resulted in a performance regression of about 5%.
I consider this to be a somewhat realistic benchmark.
Thanks to `@ogoffart` for pointing me in the right direction!
Edit: Updated description
This commit is contained in:
commit
9f85cd6f2a
3 changed files with 82 additions and 9 deletions
14
src/test/ui/enum-discriminant/niche-prefer-zero.rs
Normal file
14
src/test/ui/enum-discriminant/niche-prefer-zero.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Check that niche selection prefers zero.
|
||||
// See https://github.com/rust-lang/rust/pull/87794
|
||||
// run-pass
|
||||
#[repr(u8)]
|
||||
pub enum Size {
|
||||
One = 1,
|
||||
Two = 2,
|
||||
Three = 3,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// check that `None` is zero
|
||||
assert_eq!(0, unsafe { std::mem::transmute::<Option<Size>, u8>(None) });
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue