Open BalaRishi-AMD opened 4 years ago
This is potentially a counter-point to bug 46376, comment 15. We are relying on the system, but still getting blamed for an FP accuracy bug.
The way these functions are defined is fundamentally weird: for almost every other library function, the result is precisely predictable. But the math functions can return whatever they want.
Does this mean that gcc has its own implementation of cbrt() that is more accurate than the system's?
gcc uses MPFR for compile-time constant folding, which always produces correctly rounded results.
Assuming again that host == target, I think we would see the same result independent of whether we constant fold the call or not.
So even though our cbrt() handling is not consistent with most libm calls, I don't see how this is a compiler bug rather than a bug for the system's (some version of Linux?) math library.
This is potentially a counter-point to bug 46376, comment 15. We are relying on the system, but still getting blamed for an FP accuracy bug.
Does this mean that gcc has its own implementation of cbrt() that is more accurate than the system's?
It looks like host and target are the same from the description, but would it be more accurate to say clang is using the target's libm in this case?
Ie, unlike most mathlib calls, we are not constant folding calls to cbrt() even when compiling with optimization:
Somehow got confused here. Yes, you're right, we're not folding it at all.
clang is using the host's libm to compute cbrt. Apparently the error of that implementation is greater than 1 ulp.
It looks like host and target are the same from the description, but would it be more accurate to say clang is using the target's libm in this case?
Ie, unlike most mathlib calls, we are not constant folding calls to cbrt() even when compiling with optimization:
$ clang cbrt.c -w -O2 -S -o - | grep cbrt callq _cbrt
clang is using the host's libm to compute cbrt. Apparently the error of that implementation is greater than 1 ulp.
Extended Description
$ cat foo.c
include
include
include
include
int main() { double d; d = 2.0; printf("pow((2.0), 1.0/3.0) = % .16e\n", pow((2.0), 1.0/3.0)); printf("cbrt(2.0) = % .16e\n", cbrt(2.0)); }
$ gcc foo.c -o foo -lm $ ./foo pow((2.0), 1.0/3.0) = 1.2599210498948732e+00 cbrt(2.0) = 1.2599210498948732e+00
$ clang foo.c -o foo -lm $ ./foo pow((2.0), 1.0/3.0) = 1.2599210498948732e+00 cbrt(2.0) = 1.2599210498948734e+00 // <====