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

            Bug ID: 91226
           Summary: wrong propagation of non-canonical _Decimal64 constant
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vincent-gcc at vinc17 dot net
  Target Milestone: ---

It appears that GCC does not propagate non-canonical _Decimal64 constants
correctly, as shown by the following testcase. Tests on a Debian/unstable
Linux/x86_64 machine.

#include <stdio.h>

union u
{
  _Decimal64 d64;
  unsigned long long ull;
};

#define OUT(V)                                          \
  do {                                                  \
    for (int i = 0; i < 8; i++)                         \
      printf (" %02X", ((unsigned char *) &(V))[i]);    \
    printf ("\n");                                      \
  } while (0)

#ifndef N
#define N 0
#endif

int main (void)
{
#ifdef V
  volatile
#endif
    unsigned long long i = 0x6C7386F26FC10000 - N;
  union u x;
  _Decimal64 d;

  x.ull = i;
  OUT (x.d64);
  d = x.d64;
  OUT (d);
  printf ("%a\n", (double) d);
  return 0;
}

On the following test, with -O, one can see that the memory representation has
changed. The value hasn't even been canonicalized correctly, as the expected
value is 0.

cventin% gcc-snapshot -Wall -Wextra tst.c -o tst -O
cventin% ./tst
 00 00 C1 6F F2 86 73 6C
 00 00 34 26 F5 6B DC 31
0x1.c6bf52634p+52

Without optimizations, no issues (and the value is 0 as expected):

cventin% gcc-snapshot -Wall -Wextra tst.c -o tst
cventin% ./tst
 00 00 C1 6F F2 86 73 6C
 00 00 C1 6F F2 86 73 6C
0x0p+0

With optimizations, but the integer constant stored in a volatile variable, the
problem disappears, thus it seems to be related to the propagation of the
_Decimal64 constant:

cventin% gcc-snapshot -Wall -Wextra tst.c -o tst -O -DV
cventin% ./tst
 00 00 C1 6F F2 86 73 6C
 00 00 C1 6F F2 86 73 6C
0x0p+0

The following test is the same as the first one (the issue was reproducible
with -DN=0), but with a canonical _Decimal64 encoding, and the output is
correct. This shows that the issue probably came from the non-canonical
encoding in the first test.

cventin% gcc-snapshot -Wall -Wextra tst.c -o tst -O -DN=1
cventin% ./tst
 FF FF C0 6F F2 86 73 6C
 FF FF C0 6F F2 86 73 6C
0x1.1c37937e08p+53

Note: Due to this bug, the GNU MPFR trunk revision 13530 fails in tget_set_d64
when built with Debian's gcc-snapshot 10.0.0 20190718, trunk revision 273586. I
did not see any failure with the previous GCC versions, but the above testcase
fails with GCC 5.5.0, 6.5.0, 7.4.0, 8.3.0 and 9.1.0 (under Debian/unstable).

Reply via email to