https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92824
Bug ID: 92824
Summary: Wrong optimization: representation of long doubles not
copied even with memcpy
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: ch3root at openwall dot com
Target Milestone: ---
Source code:
----------------------------------------------------------------------
#include <string.h>
#include <stdio.h>
int main()
{
long double x, y;
unsigned char *px = (unsigned char *)&x;
unsigned char *py = (unsigned char *)&y;
// make x pseudo-denormal
x = 0;
px[7] = 0x80;
// set padding
px[10] = 0x80;
px[11] = 0x80;
px[12] = 0x80;
px[13] = 0x80;
px[14] = 0x80;
px[15] = 0x80;
// uncomment if you don't like pseudo-denormals
//memset(&x, 0x80, sizeof x);
y = x;
memcpy(&y, &x, sizeof y);
for (int i = sizeof y; i-- > 0;)
printf("%02x ", py[i]);
printf("\n");
}
----------------------------------------------------------------------
Results:
----------------------------------------------------------------------
$ gcc -std=c11 -pedantic -Wall -Wextra test.c && ./a.out
80 80 80 80 80 80 00 00 80 00 00 00 00 00 00 00
$ gcc -std=c11 -pedantic -Wall -Wextra -O3 test.c && ./a.out
00 00 00 00 00 00 00 01 80 00 00 00 00 00 00 00
----------------------------------------------------------------------
gcc x86-64 version: gcc (GCC) 10.0.0 20191205 (experimental)
Another variation of pr92486 and pr71475. This time on trunk and without
structs. Feel free to close as dup.
There are two issues here:
- padding is not copied;
- if pseudo-denormals are not considered trap representions in gcc, their
non-padding bytes are not preserved too (the exponent is changed from 0 to 1).
(OTOH it seems sNaN in double on x86-32 is not converted to qNaN in such a
situation.)