Bug 319393 - bad rounding in cvtsi2ss instruction
Summary: bad rounding in cvtsi2ss instruction
Status: REPORTED
Alias: None
Product: valgrind
Classification: Developer tools
Component: vex (show other bugs)
Version: 3.8.0
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-05-06 05:01 UTC by chzchzchz
Modified: 2020-04-12 17:51 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description chzchzchz 2013-05-06 05:01:22 UTC
libvex translates cvtsi2ss into an I64StoF64, followed by an F64toF32. In some cases, this leads to loss of precision which diverges from hardware results.

Here's a test case:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
        uint64_t        rbx, rcx;

        rbx = 0x0100000100000001;
        __asm__ __volatile__(
                "cvtsi2ss       %%rbx,%%xmm2           \n"
                "movd           %%xmm2, %%rcx          \n"
        : "=c" (rcx) : "b" (rbx) : "%xmm2");

        printf("rcx: %lx\n", rcx);

        return 0;
}

Reproducible: Always

Steps to Reproduce:
1. compile test case
2. run on valgrind
3. run natively
Actual Results:  
Valgrind gives: "rcx: 5b800000"
Native gives: "rcx: 5b800001"


Expected Results:  
Valgrind should return "rcx: 5b800001".
Comment 1 Julian Seward 2013-07-02 16:07:56 UTC
I guess this happens because the value is rounded twice, as opposed
to once when running on real hardware.
Comment 2 jackrabbit 2019-09-10 21:11:00 UTC
Just ran into this myself, here is another repro where results differ when running under valgrind and not:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
  long a = 0x7fffff4000000001;
  float b = a;
  unsigned c;
  memcpy(&c, &b, sizeof(b));
  printf("%f %u\n", (double) b, c);
  return 0;
}