http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55939
--- Comment #11 from Aldy Hernandez <aldyh at gcc dot gnu.org> 2013-01-29 17:26:46 UTC --- In adding debugging printfs throughout a locally reduced testcase, I ran into something peculiar, that may or may not be related to this PR. Perhaps some floating point savvy person comment? double d, d2; ... if (d != d2) { dumpd(d,d2); return -1; } By this point, "d" and "d2" are in fp2/fp3, and we compare them in extended-precision real mode (fcmp.x) below: (gdb) si 0x80000670 154 if (d != d2) 1: x/i $pc => 0x80000670 <check_random+260>: fcmpx %fp3,%fp2 (gdb) info reg fp2 fp2 9.5869038983080764131982923476680188e-94 (raw 0x3ec90000fff801fffff84000) (gdb) info reg fp3 fp3 9.5869038983080764090401284414100591e-94 (raw 0x3ec90000fff801fffff83ff8) Notice above that the registers are slightly different, so d != d2. (gdb) si 0x80000674 154 if (d != d2) 1: x/i $pc => 0x80000674 <check_random+264>: fbne 0x80000692 <check_random+294> (gdb) 156 dumpd(d,d2); 1: x/i $pc => 0x80000692 <check_random+294>: fmoved %fp2,%sp@- (gdb) si 0x80000696 156 dumpd(d,d2); 1: x/i $pc => 0x80000696 <check_random+298>: fmoved %fp3,%sp@- (gdb) 0x8000069a 156 dumpd(d,d2); 1: x/i $pc => 0x8000069a <check_random+302>: jsr 0x80000508 <dumpd> Notice we pass fp2/fp3 in the stack as arguments to dumpd(). Interestingly, we move them with fmove.d which is double-precision (instead of the compare we did prior in .x mode). With dumpd() implemented as below, "a" will be the same as "b", since we chopped off some bits with the fmove.d explained above. void dumpd(double a, double b) { ... if (a == b) dump_same(); ... ... } dumpd() gets executed as follows: 1: x/i $pc => 0x8000050c <dumpd+4>: fmoved %fp@(8),%fp1 (gdb) 0x80000512 90 { 1: x/i $pc => 0x80000512 <dumpd+10>: fmoved %fp@(16),%fp0 (gdb) info reg fp1 fp1 9.5869038983080764131982923476680188e-94 (raw 0x3ec90000fff801fffff84000) (gdb) info reg fp0 fp0 9.5869038983080764131982923476680188e-94 (raw 0x3ec90000fff801fffff84000) Notice fp0 and fp1 are now the same. (gdb) 93 if (a == b) 1: x/i $pc => 0x80000528 <dumpd+32>: fcmpx %fp0,%fp1 (gdb) 0x8000052c 93 if (a == b) 1: x/i $pc => 0x8000052c <dumpd+36>: fbeq 0x80000538 <dumpd+48> (gdb) 110 } 1: x/i $pc => 0x80000538 <dumpd+48>: unlk %fp etc etc etc. I'm a bit flaky as to FP standards, but it seems suspect that two values that are different, suddenly become the same when passed to a function. Is this one of those FP quirks, and I'm horrendously misguided?