https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91226

--- Comment #1 from joseph at codesourcery dot com <joseph at codesourcery dot 
com> ---
This appears to be a bug in libdecnumber/bid/bid2dpd_dpd2bid.c.  
_bid_to_dpd32 checks for a too-large significand, but _bid_to_dpd64 does 
not.  Furthermore, _bid_to_dpd128 has the same bug of not checking for 
too-large significands, as shown by the following test (which outputs 0 
without optimization, which is correct, but 8e+33 with -O2, which is 
wrong).  (_bid_to_dpd128 also doesn't check at all for the case where the 
first four bits of the combination field are 1100, 1101 or 1110, in which 
case the significand is always too large and so the value is always a 
noncanonical zero.)

#include <stdio.h>

union u
{
  _Decimal128 d128;
  unsigned __int128 u128;
};

#define U128(hi, lo) (((unsigned __int128) lo) \
                      | (((unsigned __int128) hi) << 64))

int
main (void)
{
  unsigned __int128 i = U128 (0x3041ed09bead87c0ULL, 0x378d8e6400000001ULL);
  union u x;
  _Decimal128 d;
  x.u128 = i;
  d = x.d128;
  printf ("%g\n", (double) d);
  return 0;
}

Reply via email to