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.

Reply via email to