https://gcc.gnu.org/g:ad45faeb14a4acb551ecbb61bc1b0e1f6ce500b0
commit r17-2067-gad45faeb14a4acb551ecbb61bc1b0e1f6ce500b0 Author: Icenowy Zheng <[email protected]> Date: Wed Jul 1 00:11:42 2026 +0800 RISC-V: Change initial value for fmin/fmax autovec reduce [PR126049] Currently the auto-vectorization of C fmin()/fmax() uses infinity/-infinity as the initial value for reduction, which introduces bogus infinity values when iterating over an array with only NaNs. As all C fmin()/fmax(), RV F/D fmin/fmax, RVV vfmin/vfmax and RVV vfredmin/vfredmax are implementing the IEEE754 minimumNumber or maximumNumber behavior, an initial value of NaN is more suitable than infinity when reducing the vector (if the input vector is all NaN, the result will still be NaN and if the input vector contains non-NaN elements they will cover the initial NaN). Change the initial value during reduction from corresponding inf to a quiet NaN. PR target/126049 gcc/ChangeLog: * config/riscv/autovec.md: Change fmin/fmax reduction initial value from inf/-inf to NaN for proper semantics of corresponding C funtion. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr126049.c: New. Diff: --- gcc/config/riscv/autovec.md | 4 ++-- .../gcc.target/riscv/rvv/autovec/pr126049.c | 26 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 31584f4918c4..f6ec19d0025f 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -2436,7 +2436,7 @@ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)" { REAL_VALUE_TYPE rv; - real_inf (&rv, true); + real_nan (&rv, "", 1, VOIDmode); rtx f = const_double_from_real_value (rv, <VEL>mode); riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, UNSPEC_REDUC_MAX_VL0_SAFE, @@ -2451,7 +2451,7 @@ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)" { REAL_VALUE_TYPE rv; - real_inf (&rv, false); + real_nan (&rv, "", 1, VOIDmode); rtx f = const_double_from_real_value (rv, <VEL>mode); riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, UNSPEC_REDUC_MIN_VL0_SAFE, diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126049.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126049.c new file mode 100644 index 000000000000..1fab44665258 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr126049.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-require-effective-target riscv_v_ok } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O2 -ftree-vectorize" } */ + +#define NAN (__builtin_nan("")) + +__attribute__ ((noipa)) float +maxx (float *arr, unsigned int sz) +{ + float val = NAN; + unsigned int i; + + for (i = 0; i < sz; i++) + val = __builtin_fmaxf (val, arr[i]); + + return val; +} + +int +main () +{ + float arr[] = { NAN, NAN, NAN, NAN }; + float res = maxx (arr, 4); + if (!__builtin_isnan (res)) + __builtin_abort (); +}
