https://gcc.gnu.org/g:a0cc9450a03bb7ef716e4d3734786ea920a35fe8
commit r16-4948-ga0cc9450a03bb7ef716e4d3734786ea920a35fe8 Author: Tamar Christina <[email protected]> Date: Mon Nov 3 08:07:13 2025 +0000 vect: Fix null dereference in boolean reductions [PR122475] neutral_op can be null, so guard against that. gcc/ChangeLog: PR tree-optimization/122475 * tree-vect-loop.cc (vectorizable_reduction): Check for neutral_op. gcc/testsuite/ChangeLog: PR tree-optimization/122475 * gcc.dg/vect/pr122475.c: New test. * gcc.target/aarch64/sve/vect-reduc-bool-19.c: New test. * gcc.target/aarch64/sve/vect-reduc-bool-20.c: New test. Diff: --- gcc/testsuite/gcc.dg/vect/pr122475.c | 13 +++++++++ .../gcc.target/aarch64/sve/vect-reduc-bool-19.c | 17 ++++++++++++ .../gcc.target/aarch64/sve/vect-reduc-bool-20.c | 32 ++++++++++++++++++++++ gcc/tree-vect-loop.cc | 4 ++- 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.dg/vect/pr122475.c b/gcc/testsuite/gcc.dg/vect/pr122475.c new file mode 100644 index 000000000000..ed229c5475cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr122475.c @@ -0,0 +1,13 @@ +/* { dg-additional-options "-march=armv8-a+sve" { target aarch64*-*-* } } */ +/* Check that we don't ICE. */ +int a; +int b; +int main() { + for (char t = 0; t < 14; t += 2) + for (int u = 0; u < 242; u += 4) { + a = a < 0 ? a : 0; + b = b < 0 ? b : 0; + } +} + +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" { target aarch64*-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c new file mode 100644 index 000000000000..6492c44c0651 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-19.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mautovec-preference=sve-only -fdump-tree-vect-details -O3 --param vect-epilogues-nomask=0" } */ + +int p[128]; + +bool __attribute__((noipa)) +fand (int n, bool r1, bool r2) +{ + bool r = true; + for (int i = 0; i < (n/2); i+=2) + { + r &= (p[i] != 0) & r1; + r &= (p[i+1] != 0) & r2; + } + return r; +} +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c new file mode 100644 index 000000000000..83c5c206dd25 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-20.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mautovec-preference=sve-only -fdump-tree-vect-details -O3 --param vect-epilogues-nomask=0" } */ + +#include <stdbool.h> +#include <stdint.h> + +void vec_slp_cmp (char* restrict a, char* restrict b, int n) { + bool x0 = b[0] != 0; + bool x1 = b[1] != 0; + bool x2 = b[2] != 0; + bool x3 = b[3] != 0; + for (int i = 0; i < n; ++i) { + x0 &= (a[i * 4] != 0); + x1 &= (a[i * 4 + 1] != 0); + x2 &= (a[i * 4 + 2] != 0); + x3 &= (a[i * 4 + 3] != 0); + } + b[0] = x0; + b[1] = x1; + b[2] = x2; + b[3] = x3; +} + +void vec_slp_cmp1 (char* restrict a, char* restrict b, int n) { + bool x0 = b[0] != 0; + for (int i = 0; i < n; ++i) { + x0 &= (a[i] != 0); + } + b[0] = x0; +} + +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" { target aarch64*-*-* } } } */ diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 50cdc2a90fa2..576a69c82d25 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -7578,7 +7578,9 @@ vectorizable_reduction (loop_vec_info loop_vinfo, if ((double_reduc || neutral_op) && !nunits_out.is_constant () && (SLP_TREE_LANES (slp_node) != 1 && !reduc_chain) - && !operand_equal_p (neutral_op, vect_phi_initial_value (reduc_def_phi)) + && (!neutral_op + || !operand_equal_p (neutral_op, + vect_phi_initial_value (reduc_def_phi))) && !direct_internal_fn_supported_p (IFN_VEC_SHL_INSERT, vectype_out, OPTIMIZE_FOR_SPEED)) {
