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

            Bug ID: 128624
           Summary: wrong code at -O0: (unsigned)(_Decimal64)2147483648
                    gives 0 (libbid sentinel 0x80000000 is also a valid
                    result)
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: dfp, wrong-code
          Severity: normal
          Priority: P3
         Component: libgcc
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jeffchen006 at gmail dot com
  Target Milestone: ---

int printf(const char *, ...);
int main(void) {
  _Decimal64 d = 2147483648.DD;
  printf("%u\n", (unsigned)d);
}

$ gcc -O0 t.c && ./a.out
0
$ gcc -O1 t.c && ./a.out
2147483648

Expected: 2147483648. 2^31 is exact in _Decimal64 and fits in unsigned int, so
the result must be 2147483648. -O1 folds the conversion at compile time and is
correct. -O0 calls __bid_fixunsddsi, which is wrong.

Suspected cause: libgcc/config/libbid/_dd_to_usi.c, _td_to_usi.c, _sd_to_usi.c:
"if (res == 0x80000000) res = 0;". The invalid sentinel is equal to the valid
result 2^31. The _to_udi.c files have the same problem with 0x8000000000000000
((unsigned long long)(_Decimal128)9223372036854775808 gives 0). Code is from
the 2007 libbid import (200359e888d).

Known to fail: 8.5.0, 10.5.0, 11.4.0, 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0,
17.0.

-O0 -fsanitize=undefined,address is clean.

gcc version 17.0.0 20261111 (experimental) (a2a11abfad3), x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release

Reply via email to