[gcc r17-3331] middle-end/126788 - more vector folding
Richard Biener via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:465ee014cb0cf9be62f0fd3de3821c755d37f58d commit r17-3331-g465ee014cb0cf9be62f0fd3de3821c755d37f58d Author: Richard Biener <[email protected]> Date: Thu Aug 13 14:57:56 2026 +0200 middle-end/126788 - more vector folding The last match.pd update for double-conversion folding didn't handle the case where a vector conversion would go away because supportable_convert_operation doesn't consider a noop conversion (or a sign conversion). The following rectifies this, allowing a NOP_EXPR and VIEW_CONVERT_EXPR for same mode types as supportable conversion as we can RTL expand that just fine. This shows that the vectorizer routed sign-conversions through vectorizable_assignment but now vectorizable_conversion would handle it, emitting NOP_EXPRs (which is fine) instead of VIEW_CONVERT_EXPRs (which we declared canonical for vectors). This would confuse some foldings, leading to testsuite FAILs, so make vectorizable_conversion also prefer VIEW_CONVERT_EXPRs here. PR middle-end/126788 * optabs-tree.cc (supportable_convert_operation): For same modes allow NOP_EXPR and VIEW_CONVERT_EXPR. * tree-ssa-forwprop.cc (simplify_vector_constructor): Avoid converting the vector to be used for blending into the result to the type of the permutation. * tree-vect-stmts.cc (vectorizable_conversion): Leave nop-conversions to vectorizable_assignment. * gcc.target/i386/pr126788.c: New testcase. Diff: --- gcc/optabs-tree.cc | 4 ++++ gcc/testsuite/gcc.target/i386/pr126788.c | 24 ++++++++++++++++++++++++ gcc/tree-ssa-forwprop.cc | 1 + gcc/tree-vect-stmts.cc | 9 ++++++++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/gcc/optabs-tree.cc b/gcc/optabs-tree.cc index 5fbdcd3a730d..5360a509f8d8 100644 --- a/gcc/optabs-tree.cc +++ b/gcc/optabs-tree.cc @@ -375,6 +375,10 @@ supportable_convert_operation (enum tree_code code, if (!VECTOR_MODE_P (m1) || !VECTOR_MODE_P (m2)) return false; + if (m1 == m2 + && (CONVERT_EXPR_CODE_P (code) || code == VIEW_CONVERT_EXPR)) + return true; + /* First check if we can done conversion directly. */ if ((code == FIX_TRUNC_EXPR && can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp) diff --git a/gcc/testsuite/gcc.target/i386/pr126788.c b/gcc/testsuite/gcc.target/i386/pr126788.c new file mode 100644 index 000000000000..0448284e8f68 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr126788.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O -msse2" } */ + +typedef int v2si __attribute__((vector_size (8))); +typedef unsigned int v2usi __attribute__((vector_size (8))); +typedef long long v2di __attribute__((vector_size (16))); + +v2si +f1 (v2si a, v2si b) +{ + + v2di z = __builtin_convertvector (a, v2di); + return __builtin_convertvector (z, v2si); +} + +v2usi +f2 (v2si a, v2si b) +{ + + v2di z = __builtin_convertvector (a, v2di); + return __builtin_convertvector (z, v2usi); +} + +/* { dg-final { scan-assembler-not "xmm" { target { ! ia32 } } } } */ diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index 55bd8aee5f83..0044293b7c53 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -4363,6 +4363,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) /* For a real orig[1] (no splat, constant etc.) we might need to nop-convert it. Do so here. */ if (orig[1] && orig[1] != error_mark_node + && !converted_orig1 && !useless_type_conversion_p (perm_type, TREE_TYPE (orig[1])) && tree_nop_conversion_p (TREE_TYPE (perm_type), TREE_TYPE (TREE_TYPE (orig[1])))) diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index a023977bc51f..38a17e29a84c 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -5475,7 +5475,14 @@ vectorizable_conversion (vec_info *vinfo, { gcc_assert (converts.length () <= 2); if (converts.length () == 1) - code1 = converts[0].second; + { + code1 = converts[0].second; + if (CONVERT_EXPR_CODE_P (code) + && tree_nop_conversion_p (TREE_TYPE (vectype_out), + TREE_TYPE (vectype_in))) + /* NOP conversions are handled by vectorizable_assignment. */ + return false; + } else { cvt_type = NULL_TREE;