diff options
| author | iximeow <me@iximeow.net> | 2024-03-20 01:27:33 -0700 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2024-03-20 03:33:07 -0700 |
| commit | e7fbf7223f640c5121b21183cd26ecd3ccb6a820 (patch) | |
| tree | 38f9f6c5f5f44553ad41618048043623aa7cd3cb | |
| parent | b7dcabe55e3b915ba9488dc374f752404c2c8945 (diff) | |
| download | rust-e7fbf7223f640c5121b21183cd26ecd3ccb6a820.tar.gz rust-e7fbf7223f640c5121b21183cd26ecd3ccb6a820.zip | |
improve codegen of fmt_num to delete unreachable panic
it seems LLVM doesn't realize that `curr` is always decremented at least once in either loop formatting characters of the input string by their appropriate radix, and so the later `&buf[curr..]` generates a check for out-of-bounds access and panic. this is unreachable in reality as even for `x == T::zero()` we'll produce at least the character `Self::digit(T::zero())` for at least one character output, and `curr` will always be at least one below `buf.len()`. adjust `fmt_int` to make this fact more obvious to the compiler, which fortunately (or unfortunately) results in a measurable performance improvement for workloads heavy on formatting integers.
| -rw-r--r-- | library/core/src/fmt/num.rs | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index ab2158394bf..abe833a4bf2 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -79,11 +79,11 @@ unsafe trait GenericRadix: Sized { if is_nonnegative { // Accumulate each digit of the number from the least significant // to the most significant figure. - for byte in buf.iter_mut().rev() { + loop { let n = x % base; // Get the current place value. x = x / base; // Deaccumulate the number. - byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; + buf[curr].write(Self::digit(n.to_u8())); // Store the digit in the buffer. if x == zero { // No more digits left to accumulate. break; @@ -91,11 +91,11 @@ unsafe trait GenericRadix: Sized { } } else { // Do the same as above, but accounting for two's complement. - for byte in buf.iter_mut().rev() { + loop { let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. - byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; + buf[curr].write(Self::digit(n.to_u8())); // Store the digit in the buffer. if x == zero { // No more digits left to accumulate. break; |
