RISC-V / GCC 10: invalid operation not set in acos and asin

Aurelien Jarno aurelien@aurel32.net
Wed May 13 16:27:39 GMT 2020


Hi all,

When trying to build the glibc with GCC 10 on riscv64 and then run
the glibc testsuite, I get the following additional testsuite failures
compared to GCC 9:

| FAIL: math/test-double-acos
| FAIL: math/test-double-asin
| FAIL: math/test-float32x-acos
| FAIL: math/test-float32x-asin
| FAIL: math/test-float64-acos
| FAIL: math/test-float64-asin

Here is the detailed output returned by test-double-acos (they are all
similar):

| FAIL: math/test-double-acos
| original exit status 1
| testing double (without inline functions)
| Failure: acos (inf): Exception "Invalid operation" not set
| Failure: acos (-inf): Exception "Invalid operation" not set
| Failure: acos (1.125): Exception "Invalid operation" not set
| Failure: acos (-1.125): Exception "Invalid operation" not set
| Failure: acos (max_value): Exception "Invalid operation" not set
| Failure: acos (-max_value): Exception "Invalid operation" not set
| Failure: acos_downward (inf): Exception "Invalid operation" not set
| Failure: acos_downward (-inf): Exception "Invalid operation" not set
| Failure: acos_downward (1.125): Exception "Invalid operation" not set
| Failure: acos_downward (-1.125): Exception "Invalid operation" not set
| Failure: acos_downward (max_value): Exception "Invalid operation" not set
| Failure: acos_downward (-max_value): Exception "Invalid operation" not set
| Failure: acos_towardzero (inf): Exception "Invalid operation" not set
| Failure: acos_towardzero (-inf): Exception "Invalid operation" not set
| Failure: acos_towardzero (1.125): Exception "Invalid operation" not set
| Failure: acos_towardzero (-1.125): Exception "Invalid operation" not set
| Failure: acos_towardzero (max_value): Exception "Invalid operation" not set
| Failure: acos_towardzero (-max_value): Exception "Invalid operation" not set
| Failure: acos_upward (inf): Exception "Invalid operation" not set
| Failure: acos_upward (-inf): Exception "Invalid operation" not set
| Failure: acos_upward (1.125): Exception "Invalid operation" not set
| Failure: acos_upward (-1.125): Exception "Invalid operation" not set
| Failure: acos_upward (max_value): Exception "Invalid operation" not set
| Failure: acos_upward (-max_value): Exception "Invalid operation" not set
| 
| Test suite completed:
|   372 test cases plus 368 tests for exception flags and
|     368 tests for errno executed.
|   24 errors occurred.

I have tracked the issue to the following piece of code from
sysdeps/ieee754/dbl-64/e_asin.c:

|   else {
|     u.i[HIGH_HALF]=0x7ff00000;
|     v.i[HIGH_HALF]=0x7ff00000;
|     u.i[LOW_HALF]=0;
|     v.i[LOW_HALF]=0;
|     return u.x/v.x;
|   }

GCC 10 optimizes out that code and loads a NaN value from memory instead
of doing the division, which explains why the invalid operation
exception is not set.

The problem doesn't appear with the acosf/asinf, which set the result to
NaN using (x-x)/(x-x). I have tried that trick for acos/asin and it
works fine, at least for riscv64. I wonder if it is an acceptable
solution or if there is a better way to do that.

Thanks,
Aurelien

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net


More information about the Libc-alpha mailing list