Bug 325328

Summary: __float128 loses precision under memcheck
Product: [Developer tools] valgrind Reporter: John Reiser <jreiser>
Component: memcheckAssignee: Julian Seward <jseward>
Status: REPORTED ---    
Severity: normal    
Priority: NOR    
Version: 3.8.0   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: executable test case __exp10(__float128) for x86_64, compressed

Description John Reiser 2013-09-26 12:51:45 UTC
Created attachment 82498 [details]
executable test case __exp10(__float128) for x86_64, compressed

__float128 manipulations can lose around 70 bits of precision (i.e., maintain only about 41 bits of precision) when run under memcheck using valgrind-3.8.1 on x86_64.  The test case program below prints
    3fbc79ca10c9242235d511e976394d7a    ## normal execution
    3fbc79ca10c9240e12445f2000000000   ## valgrind-3.8.1
The program uses Intel math library libimf and also libirc,  A complete executable for x86_64 is attached (29KB after compression).

A short diagnosis suggests that the problem occurs when __exp10 separates __float128 into two 80-bit floating point numbers, then operates extensively in 80-bit floating-point arithmetic.

----- test case (from Peter van Hoof, [valgrind-users] 2013-09-24, "mysterious failures when using valgrind")
#include <iostream>
#include <iomanip>

using namespace std;

extern "C" {
	__float128 __exp10q(__float128);
}

struct f128 {
	union {
		__float128 f;
		long long x[2];
	};
};

int main()
{
	f128 x, y;
	x.x[0] = 0x0;
	x.x[1] = 0xc003400000000000ULL; // __float128(-20)
	y.f = __exp10q(x.f);
	cout << hex << setfill('0');
	cout << setw(16) << y.x[1] << setw(16) << y.x[0] << endl;
	return 0;
}
----- end test case
Comment 1 Julian Seward 2014-05-09 11:53:02 UTC
As this is an 80-bit FP problem, we should probably close this as a dup of 197915.