-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Optimize char_try_from_u32 #94112
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.