> Yes, your version is also OK. The attached was bootstrapped and regtested on aarch64, x86 and regtested on riscv. Going to commit it later unless somebody objects.
Regards Robin Subject: [PATCH] vect: Pass truth type to vect_get_vec_defs. For conditional operations the mask is loop invariant and cannot be stored explicitly. By default, for reductions, we deduce the vectype from the statement or the loop but this does not work for conditional operations. Therefore this patch passes the truth type of the reduction input vectype for the mask operand instead. This will override the other choices and make sure we have the proper mask vectype. gcc/ChangeLog: * tree-vect-loop.cc (vect_transform_reduction): Pass truth vectype for mask operand. --- gcc/testsuite/gcc.target/aarch64/pr112406.c | 37 +++++++++++++++++++ .../gcc.target/riscv/rvv/autovec/pr112552.c | 16 ++++++++ gcc/tree-vect-loop.cc | 31 +++++++++++----- 3 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/pr112406.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112552.c diff --git a/gcc/testsuite/gcc.target/aarch64/pr112406.c b/gcc/testsuite/gcc.target/aarch64/pr112406.c new file mode 100644 index 00000000000..46459c68c4a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr112406.c @@ -0,0 +1,37 @@ +/* { dg-do compile { target { aarch64*-*-* } } } */ +/* { dg-options "-march=armv8-a+sve -w -Ofast" } */ + +typedef struct { + int red +} MagickPixelPacket; + +GetImageChannelMoments_image, GetImageChannelMoments_image_0, + GetImageChannelMoments___trans_tmp_1, GetImageChannelMoments_M11_0, + GetImageChannelMoments_pixel_3, GetImageChannelMoments_y, + GetImageChannelMoments_p; + +double GetImageChannelMoments_M00_0, GetImageChannelMoments_M00_1, + GetImageChannelMoments_M01_1; + +MagickPixelPacket GetImageChannelMoments_pixel; + +SetMagickPixelPacket(int color, MagickPixelPacket *pixel) { + pixel->red = color; +} + +GetImageChannelMoments() { + for (; GetImageChannelMoments_y; GetImageChannelMoments_y++) { + SetMagickPixelPacket(GetImageChannelMoments_p, + &GetImageChannelMoments_pixel); + GetImageChannelMoments_M00_1 += GetImageChannelMoments_pixel.red; + if (GetImageChannelMoments_image) + GetImageChannelMoments_M00_1++; + GetImageChannelMoments_M01_1 += + GetImageChannelMoments_y * GetImageChannelMoments_pixel_3; + if (GetImageChannelMoments_image_0) + GetImageChannelMoments_M00_0++; + GetImageChannelMoments_M01_1 += + GetImageChannelMoments_y * GetImageChannelMoments_p++; + } + GetImageChannelMoments___trans_tmp_1 = atan(GetImageChannelMoments_M11_0); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112552.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112552.c new file mode 100644 index 00000000000..32d221ccede --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112552.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -w" } */ + +int a, c, d; +void (*b)(); +void (*e)(); +void g(); + +void h() { + for (; a; --a) { + char *f = h; + e = b || g > 1 ? g : b; + d |= !e; + *f ^= c; + } +} diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index fb8d999ee6b..e67ba6ac0b5 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -8470,15 +8470,28 @@ vect_transform_reduction (loop_vec_info loop_vinfo, /* Get NCOPIES vector definitions for all operands except the reduction definition. */ - vect_get_vec_defs (loop_vinfo, stmt_info, slp_node, ncopies, - single_defuse_cycle && reduc_index == 0 - ? NULL_TREE : op.ops[0], &vec_oprnds0, - single_defuse_cycle && reduc_index == 1 - ? NULL_TREE : op.ops[1], &vec_oprnds1, - op.num_ops == 4 - || (op.num_ops == 3 - && !(single_defuse_cycle && reduc_index == 2)) - ? op.ops[2] : NULL_TREE, &vec_oprnds2); + if (!cond_fn_p) + { + vect_get_vec_defs (loop_vinfo, stmt_info, slp_node, ncopies, + single_defuse_cycle && reduc_index == 0 + ? NULL_TREE : op.ops[0], &vec_oprnds0, + single_defuse_cycle && reduc_index == 1 + ? NULL_TREE : op.ops[1], &vec_oprnds1, + op.num_ops == 3 + && !(single_defuse_cycle && reduc_index == 2) + ? op.ops[2] : NULL_TREE, &vec_oprnds2); + } + else + { + /* For a conditional operation pass the truth type as mask + vectype. */ + gcc_assert (single_defuse_cycle && reduc_index == 1); + vect_get_vec_defs (loop_vinfo, stmt_info, slp_node, ncopies, + op.ops[0], &vec_oprnds0, + truth_type_for (vectype_in), + NULL_TREE, &vec_oprnds1, NULL_TREE, + op.ops[2], &vec_oprnds2, NULL_TREE); + } /* For single def-use cycles get one copy of the vectorized reduction definition. */ -- 2.41.0