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).