[gcc r17-3285] tree-optimization/126862 - fix live lane extract dominance check for PHIs
Richard Biener via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:2026474385dc23e9896577db08d963bc3a96f256 commit r17-3285-g2026474385dc23e9896577db08d963bc3a96f256 Author: Richard Biener <[email protected]> Date: Fri Aug 14 11:14:00 2026 +0200 tree-optimization/126862 - fix live lane extract dominance check for PHIs We were not correctly verifying dominance of the vector definition with the scalar use in case of PHI use stmts. We have to ensure the respective PHI edge source can reach the definition. PR tree-optimization/126862 * tree-vect-slp.cc (vect_bb_slp_mark_live_stmts): For PHI uses verify dominance to the PHI use edge source. * gcc.dg/vect/bb-slp-pr126862.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/vect/bb-slp-pr126862.c | 30 ++++++++++++++++ gcc/tree-vect-slp.cc | 55 +++++++++++++++++------------ 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr126862.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr126862.c new file mode 100644 index 000000000000..da54b941d799 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr126862.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3" } */ + +#include <stdint.h> +static uint16_t +(safe_mod_func_uint16_t_u_u)(uint16_t ui1, uint16_t ui2 ){ + return + (ui2 == 0) ? + ((ui1)) : + (ui1 % ui2); +} +struct a {}; +int32_t b[4][5]; +int16_t c[5]; +uint16_t d; +int32_t *e(struct a, uint16_t, uint32_t, int32_t *, int64_t); +uint32_t f() { + int32_t g[4][5]; + for (b[3][3] = 0; b[3][3] <= 3; b[3][3]++) { + struct a h; + e(h, 0, g[2][4], &b[3][3], b[9][4]); + } +} +int32_t *e(struct a, uint16_t, uint32_t, int32_t *k, int64_t) { + int32_t i[4]; + uint16_t *j = &d; + if (c[4] ^= safe_mod_func_uint16_t_u_u(++*j, 0), *i) + *j = 0; + return k; +} diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 985aa4281b31..ebddec49b912 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -9269,32 +9269,43 @@ vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo, slp_tree node, during code-generation, simply not replacing uses for those hopefully rare cases. */ imm_use_iterator use_iter; - gimple *use_stmt; - stmt_vec_info use_stmt_info; bool live_p = false; bool can_insert = true; - FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p)) - if (!is_gimple_debug (use_stmt) - && (!(use_stmt_info = bb_vinfo->lookup_stmt (use_stmt)) - || !PURE_SLP_STMT (use_stmt_info))) - { - live_p = true; - if (!last_stmt) - last_stmt - = (node->si ? node->si - : vect_find_last_scalar_stmt_in_slp (node)->stmt); - if (!vect_stmt_dominates_stmt_p (last_stmt, use_stmt)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Cannot determine insertion place for " - "lane extract of %T at node %p\n", - DEF_FROM_PTR (def_p), (void *)node); + use_operand_p use_p; + FOR_EACH_IMM_USE_FAST (use_p, use_iter, DEF_FROM_PTR (def_p)) + { + gimple *use_stmt = USE_STMT (use_p); + stmt_vec_info use_stmt_info; + if (!(!is_gimple_debug (use_stmt) + && (!(use_stmt_info = bb_vinfo->lookup_stmt (use_stmt)) + || !PURE_SLP_STMT (use_stmt_info)))) + continue; + live_p = true; + if (!last_stmt) + last_stmt + = (node->si ? node->si + : vect_find_last_scalar_stmt_in_slp (node)->stmt); + if (is_a <gphi *> (use_stmt)) + { + if (!dominated_by_p (CDI_DOMINATORS, + phi_arg_edge_from_use (use_p)->src, + gimple_bb (last_stmt))) can_insert = false; - break; - } - } + } + else if (!vect_stmt_dominates_stmt_p (last_stmt, use_stmt)) + can_insert = false; + if (!can_insert) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Cannot determine insertion place for " + "lane extract of %T at node %p\n", + DEF_FROM_PTR (def_p), (void *)node); + can_insert = false; + break; + } + } if (live_p && can_insert) { /* Only record a live stmt when we can replace all uses. We