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