[gcc r17-3502] tree-optimization/126979 - fix SLP pattern representative checks
Richard Biener via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:c3c082917c72ccf2928a39dc5e54a65245f46568 commit r17-3502-gc3c082917c72ccf2928a39dc5e54a65245f46568 Author: Richard Biener <[email protected]> Date: Fri Aug 21 10:17:02 2026 +0200 tree-optimization/126979 - fix SLP pattern representative checks The following makes sure to special-case VEC_PERM nodes when comparing complex nodes. When they still had a representative we ended up comparing random operations (oops). PR tree-optimization/126979 * tree-vect-slp-patterns.cc (compatible_complex_nodes_p): Special case VEC_PERM nodes. Diff: --- gcc/tree-vect-slp-patterns.cc | 113 ++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/gcc/tree-vect-slp-patterns.cc b/gcc/tree-vect-slp-patterns.cc index 2ff7ce2699fd..bf9efacf161f 100644 --- a/gcc/tree-vect-slp-patterns.cc +++ b/gcc/tree-vect-slp-patterns.cc @@ -763,70 +763,77 @@ compatible_complex_nodes_p (slp_compat_nodes_map_t *compat_cache, return true; } - auto a_stmt = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (a)); - auto b_stmt = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (b)); - - if (gimple_code (a_stmt) != gimple_code (b_stmt)) - return false; - - /* code, children, type, externals, loads, constants */ - if (gimple_num_args (a_stmt) != gimple_num_args (b_stmt)) - return false; - - /* At this point, a and b are known to be the same gimple operations. */ - if (is_gimple_call (a_stmt)) - { - if (!compatible_calls_p (dyn_cast <gcall *> (a_stmt), - dyn_cast <gcall *> (b_stmt), false)) - return false; - } - else if (!is_gimple_assign (a_stmt)) + if (SLP_TREE_PERMUTE_P (a) != SLP_TREE_PERMUTE_P (b)) return false; + else if (SLP_TREE_PERMUTE_P (a)) + ; else { - tree_code acode = gimple_assign_rhs_code (a_stmt); - tree_code bcode = gimple_assign_rhs_code (b_stmt); - if ((acode == REALPART_EXPR || acode == IMAGPART_EXPR) - && (bcode == REALPART_EXPR || bcode == IMAGPART_EXPR) - && operand_equal_p (TREE_OPERAND (gimple_assign_rhs1 (a_stmt), 0), - TREE_OPERAND (gimple_assign_rhs1 (b_stmt), 0))) - return true; - - if (acode != bcode) + auto a_stmt = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (a)); + auto b_stmt = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (b)); + + if (gimple_code (a_stmt) != gimple_code (b_stmt)) return false; - } - if (!STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a)) - || !STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b))) - { - for (unsigned i = 0; i < gimple_num_args (a_stmt); i++) + /* code, children, type, externals, loads, constants */ + if (gimple_num_args (a_stmt) != gimple_num_args (b_stmt)) + return false; + + /* At this point, a and b are known to be the same gimple operations. */ + if (is_gimple_call (a_stmt)) { - tree t1 = gimple_arg (a_stmt, i); - tree t2 = gimple_arg (b_stmt, i); - if (TREE_CODE (t1) != TREE_CODE (t2)) + if (!compatible_calls_p (dyn_cast <gcall *> (a_stmt), + dyn_cast <gcall *> (b_stmt), false)) return false; + } + else if (!is_gimple_assign (a_stmt)) + return false; + else + { + tree_code acode = gimple_assign_rhs_code (a_stmt); + tree_code bcode = gimple_assign_rhs_code (b_stmt); + if ((acode == REALPART_EXPR || acode == IMAGPART_EXPR) + && (bcode == REALPART_EXPR || bcode == IMAGPART_EXPR) + && operand_equal_p (TREE_OPERAND (gimple_assign_rhs1 (a_stmt), 0), + TREE_OPERAND (gimple_assign_rhs1 (b_stmt), 0))) + return true; + + if (acode != bcode) + return false; + } - /* If SSA name then we will need to inspect the children - so we can punt here. */ - if (TREE_CODE (t1) == SSA_NAME) - continue; - - if (!operand_equal_p (t1, t2, 0)) + if (!STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a)) + || !STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b))) + { + for (unsigned i = 0; i < gimple_num_args (a_stmt); i++) + { + tree t1 = gimple_arg (a_stmt, i); + tree t2 = gimple_arg (b_stmt, i); + if (TREE_CODE (t1) != TREE_CODE (t2)) + return false; + + /* If SSA name then we will need to inspect the children + so we can punt here. */ + if (TREE_CODE (t1) == SSA_NAME) + continue; + + if (!operand_equal_p (t1, t2, 0)) + return false; + } + } + else + { + auto dr1 = STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a)); + auto dr2 = STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b)); + /* Don't check the last dimension as that's checked by the lineary + checks. This check is also much stricter than what we need + because it doesn't consider loading from adjacent elements + in the same struct as loading from the same base object. + But for now, I'll play it safe. */ + if (!same_data_refs (dr1, dr2, 1)) return false; } } - else - { - auto dr1 = STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a)); - auto dr2 = STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b)); - /* Don't check the last dimension as that's checked by the lineary - checks. This check is also much stricter than what we need - because it doesn't consider loading from adjacent elements - in the same struct as loading from the same base object. - But for now, I'll play it safe. */ - if (!same_data_refs (dr1, dr2, 1)) - return false; - } for (unsigned i = 0; i < SLP_TREE_CHILDREN (a).length (); i++) {