diff options
author | Andrew Stubbs <ams@baylibre.com> | 2025-03-20 09:32:31 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2025-03-25 12:24:16 +0100 |
commit | 2ef1a37e7823b21eda524972c006e0e8c26f97b3 (patch) | |
tree | cd2679cf278f242c5411ef617936ccc1b9d134d2 | |
parent | c7f1b0791916a118388f242c9a948821829acf91 (diff) | |
download | newlib-2ef1a37e7823b21eda524972c006e0e8c26f97b3.zip newlib-2ef1a37e7823b21eda524972c006e0e8c26f97b3.tar.gz newlib-2ef1a37e7823b21eda524972c006e0e8c26f97b3.tar.bz2 |
Fix GCN SIMD libm bug
Since January, GCC has been miscompiling Newlib libm on AMD GCN due to
undefined behaviour in the RESIZE_VECTOR macro. It was "working" but expanding
the size of a vector would no longer zero the additional lanes, as it expected.
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119325
-rw-r--r-- | newlib/libm/machine/amdgcn/amdgcn_veclib.h | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/newlib/libm/machine/amdgcn/amdgcn_veclib.h b/newlib/libm/machine/amdgcn/amdgcn_veclib.h index bd67740..9e9d3eb 100644 --- a/newlib/libm/machine/amdgcn/amdgcn_veclib.h +++ b/newlib/libm/machine/amdgcn/amdgcn_veclib.h @@ -85,8 +85,21 @@ typedef union { #define RESIZE_VECTOR(to_t, from) \ ({ \ - __auto_type __from = (from); \ - *((to_t *) &__from); \ + to_t __to; \ + if (VECTOR_WIDTH (to_t) < VECTOR_WIDTH (__typeof (from))) \ + asm ("; no-op cast %0" : "=v"(__to) : "0"(from)); \ + else \ + { \ + unsigned long __mask = -1L; \ + int lanes = VECTOR_WIDTH (__typeof (from)); \ + __mask <<= lanes; \ + __builtin_choose_expr ( \ + V_SF_SI_P (to_t), \ + ({asm ("v_mov_b32 %0, 0" : "=v"(__to) : "0"(from), "e"(__mask));}), \ + ({asm ("v_mov_b32 %H0, 0\n\t" \ + "v_mov_b32 %L0, 0" : "=v"(__to) : "0"(from), "e"(__mask));})); \ + } \ + __to; \ }) /* Bit-wise cast vector FROM to type TO_T. */ |