Bug 302234

Summary: fesetround() function does not affect FPU calculations
Product: [Developer tools] valgrind Reporter: Alexander Kuznetsov <akuz48>
Component: generalAssignee: Julian Seward <jseward>
Status: RESOLVED DUPLICATE    
Severity: normal CC: tom
Priority: NOR    
Version: 3.7.0   
Target Milestone: ---   
Platform: Ubuntu   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Code to reproduce

Description Alexander Kuznetsov 2012-06-20 12:33:00 UTC
Created attachment 71983 [details]
Code to reproduce

Under valgrind floating point calculations produce different results.
Code that reproduces issue 
compile with 
gcc -g -o roundtest roundtest.c -lm
Then run round test under valgrind and without it.

Running from command line  gives
$ ./roundtest
DEFAULT i = 41, res = 5.12499999999999911182,	 res1 = 5.12000000000000010658,	 res1*100. = 512.00000000000000000000
FE_TONEAREST i = 41, res = 5.12499999999999911182,	 res1 = 5.12000000000000010658,	 res1*100. = 512.00000000000000000000
FE_UPWARD i = 41, res = 5.12499999999999911182,	 res1 = 5.13000000000000078160,	 res1*100. = 513.00000000000011368684
FE_DOWNWARD i = 41, res = 5.12499999999999911182,	 res1 = 5.11999999999999921840,	 res1*100. = 511.99999999999994315658

Note that FE_UPWARD mode produces res1 = 5.13000000000000078160.
While under valgrind it gives 

==15269== Memcheck, a memory error detector
==15269== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==15269== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==15269== Command: ./roundtest
==15269== 
DEFAULT i = 41, res = 5.12499999999999911182,	 res1 = 5.12000000000000010658,	 res1*100. = 512.00000000000000000000
FE_TONEAREST i = 41, res = 5.12499999999999911182,	 res1 = 5.12000000000000010658,	 res1*100. = 512.00000000000000000000
FE_UPWARD i = 41, res = 5.12499999999999911182,	 res1 = 5.12000000000000010658,	 res1*100. = 512.00000000000000000000
FE_DOWNWARD i = 41, res = 5.12499999999999911182,	 res1 = 5.12000000000000010658,	 res1*100. = 512.00000000000000000000
==15269== 
==15269== HEAP SUMMARY:
==15269==     in use at exit: 0 bytes in 0 blocks
==15269==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==15269== 
==15269== All heap blocks were freed -- no leaks are possible
==15269== 
==15269== For counts of detected and suppressed errors, rerun with: -v
==15269== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

and gives res1 = 5.12000000000000010658 which is wrong. Correct is 5.13

Comment
As far as I understand fesetround() function on Intel platform sets rounding mode in FPU state registers EFLAGS (for x87 instruction set) and MXSCR (for SSE mmx instructions). It looks like valgrind does not correctly handle contents of this registers and program run always in default rounding mode.
Comment 1 Alexander Kuznetsov 2012-06-20 12:37:33 UTC
This is not an Ubuntu Package ussue. it can be easily reproduced on RHEL5
x86_64
Comment 2 Tom Hughes 2012-06-20 12:58:22 UTC

*** This bug has been marked as a duplicate of bug 136779 ***