-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Optimize char_try_from_u32 #94112
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
Optimize char_try_from_u32 #94112
Conversation
The optimization was proposed by @falk-hueffner in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct.
r? @scottmcm (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
Hmm, looks like we have all the edges tested in rust/library/core/tests/char.rs Lines 13 to 21 in f838a42
@bors r+ (Though I still think it'd be good to teach LLVM about this pattern, so we never need to do it again by hand.) |
📌 Commit 7c3ebec has been approved by |
Testing all possible input values (just for fun): use std::intrinsics::transmute;
#[inline]
pub const fn char_try_from_u32_old(i: u32) -> Result<char, ()> {
if (i > char::MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
Err(())
} else {
// SAFETY: checked that it's a legal unicode value
Ok(unsafe { transmute(i) })
}
}
#[inline]
pub const fn char_try_from_u32_new(i: u32) -> Result<char, ()> {
if (i ^ 0xD800).wrapping_sub(0x800) >= 0x110000 - 0x800 {
Err(())
} else {
// SAFETY: checked that it's a legal unicode value
Ok(unsafe { transmute(i) })
}
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn test_char_try_from_u32() {
for i in 0..=u32::MAX {
assert_eq!(char_try_from_u32_new(i), char_try_from_u32_old(i));
}
}
}
|
Alive2 also approves of the transformation. There was little chance that a superoptimizer would yield an incorrect simplified expression in the first place, but it's still a nice confirmation. |
Optimize char_try_from_u32 The optimization was proposed by `@falk-hueffner` in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct. The generated code is 2 instructions shorter and uses 2 registers instead of 4 on x86.
Optimize char_try_from_u32 The optimization was proposed by ``@falk-hueffner`` in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct. The generated code is 2 instructions shorter and uses 2 registers instead of 4 on x86.
Optimize char_try_from_u32 The optimization was proposed by ```@falk-hueffner``` in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct. The generated code is 2 instructions shorter and uses 2 registers instead of 4 on x86.
Optimize char_try_from_u32 The optimization was proposed by ````@falk-hueffner```` in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct. The generated code is 2 instructions shorter and uses 2 registers instead of 4 on x86.
Optimize char_try_from_u32 The optimization was proposed by `````@falk-hueffner````` in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct. The generated code is 2 instructions shorter and uses 2 registers instead of 4 on x86.
Optimize char_try_from_u32 The optimization was proposed by ``````@falk-hueffner`````` in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct. The generated code is 2 instructions shorter and uses 2 registers instead of 4 on x86.
…askrgr Rollup of 14 pull requests Successful merges: - rust-lang#93580 (Stabilize pin_static_ref.) - rust-lang#93639 (Release notes for 1.59) - rust-lang#93686 (core: Implement ASCII trim functions on byte slices) - rust-lang#94002 (rustdoc: Avoid duplicating macros in sidebar) - rust-lang#94019 (removing architecture requirements for RustyHermit) - rust-lang#94023 (adapt static-nobundle test to use llvm-nm) - rust-lang#94091 (Fix rustdoc const computed value) - rust-lang#94093 (Fix pretty printing of enums without variants) - rust-lang#94097 (Add module-level docs for `rustc_middle::query`) - rust-lang#94112 (Optimize char_try_from_u32) - rust-lang#94113 (document rustc_middle::mir::Field) - rust-lang#94122 (Fix miniz_oxide types showing up in std docs) - rust-lang#94142 (rustc_typeck: adopt let else in more places) - rust-lang#94146 (Adopt let else in more places) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
The optimization was proposed by @falk-hueffner in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct. The generated code is 2 instructions shorter and uses 2 registers instead of 4 on x86.