https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87303
Bug ID: 87303 Summary: DFmode FP constants are not correctly truncated when promoted to XFmode Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ubizjak at gmail dot com Target Milestone: --- I was looking at the following testsuite failure with -fexcess-precision=standard on 32bit x86 target: FAIL: gcc.c-torture/execute/ieee/acc1.c execution --cut here-- double func (const double *array) { double d = *array; if (d == 0.0) return d; else return d + func (array + 1); } int main () { double values[] = { 0.1e-100, 1.0, -1.0, 0.0 }; if (func (values) != 0.1e-100) abort (); exit (0); } --cut here-- gcc -O2 -fexcess-precision=standard -m32 creates following optimized tree dump: --cut here-- <bb 2> [local count: 1073741824]: values[0] = 1.00000000000000005171617276904849891057306773641595375548e-101; values[1] = 1.0e+0; values[2] = -1.0e+0; values[3] = 0.0; _9 = func (&MEM[(void *)&values + 8B]); _10 = (long double) _9; _11 = _10 + 1.00000000000000005171617276904849891057306773641595375548e-101; _12 = (double) _11; _1 = (long double) _12; if (_1 != 9.9999999999999999997834478666160678572417847571029307194e-102) goto <bb 3>; [0.00%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: abort (); <bb 4> [local count: 1073312328]: exit (0); --cut here-- Please note that the last compare is with XFmode constant that is not correctly truncated to DFmode. The comparison in extended to XFmode (due to -fexcess-precision=standard option), but the constant is not truncated to DFmode value, even if it is alter loaded via XFmode load instruction. (gdb) disass Dump of assembler code for function main: 0x08048350 <+0>: lea 0x4(%esp),%ecx ... 0x08048384 <+52>: call 0x80484e0 <func> 0x08048389 <+57>: faddl 0x80485c0 0x0804838f <+63>: add $0x10,%esp 0x08048392 <+66>: fstpl -0x30(%ebp) 0x08048395 <+69>: fldt 0x80485d0 0x0804839b <+75>: fldl -0x30(%ebp) => 0x0804839e <+78>: fucompp 0x080483a0 <+80>: fnstsw %ax 0x080483a2 <+82>: sahf 0x080483a3 <+83>: jp 0x80483b1 <main+97> 0x080483a5 <+85>: jne 0x80483b1 <main+97> 0x080483a7 <+87>: sub $0xc,%esp 0x080483aa <+90>: push $0x0 0x080483ac <+92>: call 0x8048320 <exit@plt> 0x080483b1 <+97>: call 0x8048340 <abort@plt> End of assembler dump. (gdb) i r flo st0 1.00000000000000005172e-101 (raw 0x3eafb32df8e9f3546800) st1 9.99999999999999999978e-102 (raw 0x3eafb32df8e9f3546564) st2 0 (raw 0x00000000000000000000) st3 0 (raw 0x00000000000000000000) st4 0 (raw 0x00000000000000000000) st5 0 (raw 0x00000000000000000000) st6 0 (raw 0x00000000000000000000) st7 0 (raw 0x00000000000000000000)