[all-commits] [llvm/llvm-project] 49df87: [libc][printf] Fix out-of-range shift in float320 ...

Simon Tatham via All-commits all-commits at lists.llvm.org
Wed Jun 18 00:58:13 PDT 2025


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 49df87e71b73b230ecb21335dcb5f5390eebdab3
      https://github.com/llvm/llvm-project/commit/49df87e71b73b230ecb21335dcb5f5390eebdab3
  Author: Simon Tatham <simon.tatham at arm.com>
  Date:   2025-06-18 (Wed, 18 Jun 2025)

  Changed paths:
    M libc/src/__support/FPUtil/dyadic_float.h

  Log Message:
  -----------
  [libc][printf] Fix out-of-range shift in float320 printf (#144542)

If you enable `LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_FLOAT320` and use a
`%f` style printf format directive to print a nonzero number too small
to show up in the output digits, e.g. `printf("%.2f", 0.001)`, then the
output would be intermittently incorrect, because
`DyadicFloat::as_mantissa_type_rounded` would try to shift the 320-bit
mantissa right by more than 320 bits, invoking the 'undefined behavior'
clause commented in the `shift()` function in `big_int.h`.

There were already tests in the libc test suite exercising this case,
e.g. the subnormal tests in `LlvmLibcSPrintfTest.FloatDecimalConv` use
`%f` at the default precision of 6 decimal places on tiny numbers such
as 2^-1027. But because the behavior is undefined, they don't visibly
fail all the time, and in all previous test runs we'd tried with
USE_FLOAT320, they had got lucky.

The fix is simply to detect an out-of-range right shift before doing it,
and instead just set the output value to zero.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list