On 21/10/2021 20:45, Florian Weimer wrote:
* Paul Floyd:
Unless someone else has an Idea this is going to need some debugging
inside Valgrind.
It's probably the glibc implementation that is incorrectly executed by
valgrind. “g++ -fno-builtin” reproduces the issue with the original
sources.
Yes, this is what is happening. Stepping through libc cbrtl with
debuginfo, outside of Valgrind the return is where the arrow is,
presumably fpclassify saying that it is FP_ZERO. xe is an int, can't
imagine comparing it to zero is going to be a problem.
54 if (xe == 0 && fpclassify (x) <= FP_ZERO) │
>55 return x + x;
The enum values returned by fpclassify are FP_NAN 0, FP_INFINITE 1,
FP_ZERO 2.
Inside Valgrind this test is false, and the (wrong) value that is
calculated corresponds to the expressions and constants in the code.
# define fpclassify(x) __builtin_fpclassify (FP_NAN,
FP_INFINITE, \
FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
From what I see this builtin performs
/* fpclassify(x) ->
isnan(x) ? FP_NAN :
(fabs(x) == Inf ? FP_INFINITE :
(fabs(x) >= DBL_MIN ? FP_NORMAL :
(x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
For the first test, it looks like there is a 'fucomi'.That will set the
parity flag if the input is NaN, but I only see ZF set.
The next test is another 'fucomi' comparing to the largest long double
followed by a 'ja', testing for Inf. The result is just CF set - less than.
The third test is a 'fcompi' with ldbl_min. This sets ZF, and is
followed by a 'jae'. That's wrong. That would mean 0.0 == ldbl_min.
If internally we are working with double precision that it's to be
expected that ldbl_min underflows to 0.0 and the comparison is true.
It's a shame the libc test is done in this order. I don't see any easy
fix for this.
A+
Paul
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users