Summary: | Wrong computations with long double on AMD64 | ||
---|---|---|---|
Product: | [Developer tools] valgrind | Reporter: | Wolfgang Bangerth <bangerth> |
Component: | general | Assignee: | Julian Seward <jseward> |
Status: | RESOLVED DUPLICATE | ||
Severity: | major | CC: | njn |
Priority: | NOR | ||
Version: | 3.1.0 | ||
Target Milestone: | --- | ||
Platform: | Compiled Sources | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Attachments: | program that behaves differently under valgrind |
Description
Wolfgang Bangerth
2005-12-05 20:23:31 UTC
> Valgrind and its associated tools do not treat long doubles any > different than doubles. That's true. It's a documentated limitation: http://www.valgrind.org/docs/manual/manual-core.html#manual-core.limits > The problem with this is, of course, that it leads to algorithms that > converge when run on the command line, but loop forever when run under > valgrind. It also means your program is inherently unportable - you have no chance of it working on ppc, nor if you compile it to use SSE on x86/amd64 for example if it was vectorised. > It also means your program is inherently unportable
Not really. What it means is that gcc+valgrind does not implement C99.
Take this program, for example:
#include <stdio.h>
#include <float.h>
#include <assert.h>
int
main (int argc, char **argv)
{
long double ld = argc * LDBL_MIN;
printf ("%Lg\n", ld);
assert (ld > 0);
return 0;
}
When you run that with no arguments, argc==1, then C99 guarantees that
the program will print a positive number and exit cleanly. Under
valgrind, it instead prints zero and aborts. (I don't have the c++
standard handy, but I'm sure it says something of the same nature.)
That Valgrind does not handly this is all clearly documented, but please
don't blame it on the subject program.
> It also means your program is inherently unportable - you have no chance > of it working on ppc I think this is an unfair characterization. It may be true that one shouldn't be using things like long double eps = 1e-19; and test for that as a convergence criterion. But what people do in their codes is stuff like long double eps = std::numeric_limits<long double>::eps(); This *is* portable, but leads to different behavior in algorithms when run freestanding and under valgrind on x86. > nor if you compile it to use SSE on x86/amd64 > for example if it was vectorised. That's also not quite correct since long double variables can't be vectorized anyway. Either way, the point I wanted to make is not so much whether the example program I showed is good or bad style (it's a reduced testcase, not part of a portable program) but that with this program we get different behavior for a program depending on whether it is run under valgrind or not. That's certainly an undesirable feature. Thanks Wolfgang Created attachment 32672 [details]
program that behaves differently under valgrind
Here is another program that behaves differently under valgrind than
natively.
Natively:
1020 5.61779e+306 1020 0.5
1021 1.12356e+307 1021 0.5
1022 2.24712e+307 1022 0.5
1023 4.49423e+307 1023 0.5
1024 8.98847e+307 1024 0.5
1025 1.79769e+308 1025 0.5
1026 3.59539e+308 1026 0.5
1027 7.19077e+308 1027 0.5
1028 1.43815e+309 1028 0.5
Under "valgrind --tool=memcheck" (on AMD64):
1020 5.61779e+306 1020 0.5
1021 1.12356e+307 1021 0.5
1022 2.24712e+307 1022 0.5
1023 4.49423e+307 1023 0.5
1024 8.98847e+307 1024 0.5
1025 inf 0 inf
This program is not unportable; it is part of the gnulib testsuite and known
to succeed on all platforms.
The problem is that valgrind appears to assume a different format for
'long double', which does not match the constants in <float.h>.
> This program is not unportable; it is part of the gnulib testsuite and known
> to succeed on all platforms.
What does "succeed" mean in this context? "Produces identical results
on all platforms?" FWIW, here's the output on openSUSE 10.3 on ppc32
(running natively):
1020 5.61779e+306 1020 0.5
1021 1.12356e+307 1021 0.5
1022 2.24712e+307 1022 0.5
1023 4.49423e+307 1023 0.5
1024 8.98847e+307 1024 0.5
*** This bug has been marked as a duplicate of bug 179915 *** *** This bug has been marked as a duplicate of bug 197915 *** |