https://bugs.kde.org/show_bug.cgi?id=359950
Bug ID: 359950 Summary: Wrong result comparing doubles on x87 Product: valgrind Version: 3.10.0 Platform: Ubuntu Packages OS: Linux Status: UNCONFIRMED Severity: normal Priority: NOR Component: general Assignee: jsew...@acm.org Reporter: wellnho...@aevum.de This is on Ubuntu 15.04, x86 (32-bit). Using stock valgrind 1:3.10.1-1ubuntu3~15.04, gcc 4:4.9.2-2ubuntu2. Test program: #include <math.h> #include <stdint.h> #include <stdio.h> int test(int64_t i, double d) { double a = (double)i; int comparison = (a == d || a < d || a > d); printf("%lld %f\n", i, d); return comparison; } int main() { int64_t i = (INT64_C(1) << 60) - 1; double d = pow(2.0, 60.0); printf("%d\n", test(i, d)); return 0; } When compiled with -O2 and run under valgrind, the result is: ==3514== Memcheck, a memory error detector ==3514== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==3514== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==3514== Command: ./vg_bug ==3514== 1152921504606846975 1152921504606846976.000000 0 ==3514== ==3514== HEAP SUMMARY: ==3514== in use at exit: 0 bytes in 0 blocks ==3514== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==3514== ==3514== All heap blocks were freed -- no leaks are possible ==3514== ==3514== For counts of detected and suppressed errors, rerun with: -v ==3514== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) All three comparisons returned false. Dump of assembler code for function test: 0x08048480 <+0>: push %esi 0x08048481 <+1>: push %ebx 0x08048482 <+2>: sub $0x14,%esp 0x08048485 <+5>: mov 0x20(%esp),%ecx 0x08048489 <+9>: mov 0x24(%esp),%ebx 0x0804848d <+13>: fldl 0x28(%esp) 0x08048491 <+17>: mov %ecx,(%esp) 0x08048494 <+20>: mov %ebx,0x4(%esp) 0x08048498 <+24>: fildll (%esp) 0x0804849b <+27>: fucomi %st(1),%st 0x0804849d <+29>: jp 0x80484a6 <test+38> 0x0804849f <+31>: mov $0x1,%esi 0x080484a4 <+36>: je 0x80484b8 <test+56> 0x080484a6 <+38>: xor %eax,%eax 0x080484a8 <+40>: fucomip %st(1),%st 0x080484aa <+42>: setne %al 0x080484ad <+45>: mov %eax,%esi 0x080484af <+47>: jmp 0x80484ba <test+58> 0x080484b1 <+49>: lea 0x0(%esi,%eiz,1),%esi 0x080484b8 <+56>: fstp %st(0) 0x080484ba <+58>: sub $0x10,%esp 0x080484bd <+61>: fstpl (%esp) 0x080484c0 <+64>: push %ebx 0x080484c1 <+65>: push %ecx 0x080484c2 <+66>: push $0x8048560 0x080484c7 <+71>: push $0x1 0x080484c9 <+73>: call 0x8048330 <__printf_chk@plt> 0x080484ce <+78>: add $0x34,%esp 0x080484d1 <+81>: mov %esi,%eax 0x080484d3 <+83>: pop %ebx 0x080484d4 <+84>: pop %esi 0x080484d5 <+85>: ret The strange thing is that this works as expected if the first printf statement in function test is omitted. Without the first printf: Dump of assembler code for function test: 0x08048460 <+0>: sub $0xc,%esp 0x08048463 <+3>: fldl 0x18(%esp) 0x08048467 <+7>: fildll 0x10(%esp) 0x0804846b <+11>: fstpl (%esp) 0x0804846e <+14>: fldl (%esp) 0x08048471 <+17>: fucomi %st(1),%st 0x08048473 <+19>: jp 0x804847c <test+28> 0x08048475 <+21>: mov $0x1,%eax 0x0804847a <+26>: je 0x8048490 <test+48> 0x0804847c <+28>: xor %eax,%eax 0x0804847e <+30>: fucomip %st(1),%st 0x08048480 <+32>: fstp %st(0) 0x08048482 <+34>: setne %al 0x08048485 <+37>: jmp 0x8048494 <test+52> 0x08048487 <+39>: mov %esi,%esi 0x08048489 <+41>: lea 0x0(%edi,%eiz,1),%edi 0x08048490 <+48>: fstp %st(0) 0x08048492 <+50>: fstp %st(0) 0x08048494 <+52>: add $0xc,%esp 0x08048497 <+55>: ret Reproducible: Always Steps to Reproduce: 1. gcc -Wall -O2 vg_bug.c -o vg_bug 2. valgrind ./vg_bug Actual Results: ==3617== Memcheck, a memory error detector ==3617== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==3617== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==3617== Command: ./vg_bug ==3617== 1152921504606846975 1152921504606846976.000000 0 ==3617== ==3617== HEAP SUMMARY: ==3617== in use at exit: 0 bytes in 0 blocks ==3617== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==3617== ==3617== All heap blocks were freed -- no leaks are possible ==3617== ==3617== For counts of detected and suppressed errors, rerun with: -v ==3617== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) Expected Results: ==3617== Memcheck, a memory error detector ==3617== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==3617== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==3617== Command: ./vg_bug ==3617== 1152921504606846975 1152921504606846976.000000 1 ==3617== ==3617== HEAP SUMMARY: ==3617== in use at exit: 0 bytes in 0 blocks ==3617== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==3617== ==3617== All heap blocks were freed -- no leaks are possible ==3617== ==3617== For counts of detected and suppressed errors, rerun with: -v ==3617== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -- You are receiving this mail because: You are watching all bug changes.