On Tue, Feb 3, 2026 at 2:36 PM Robin Dapp <[email protected]> wrote:
>
> Hi,
>
> The same handling for nop conversions we did in the !maybe_ident case is
> also necessary in for maybe_ident. This patch performs the necessary
> preprocessing before the if and unifies the nop-conversion handling.
>
> I'm not so happy with how all these patches trickled down one by one
> but I'm going to blame it partially on the lack of test coverage and
> the opaque code in simplify_vector_constructor. The rest is on me.
> And test coverage has definitely improved now :)
>
> Bootstrapped and regtested on x86, power10, and aarch64.
> Regtested on riscv64.
OK.
Richard.
> Regards
> Robin
>
> PR tree-optimization/123925
>
> gcc/ChangeLog:
>
> * tree-ssa-forwprop.cc (simplify_vector_constructor):
> Add nop-conversion handling for maybe_ident.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/rvv/autovec/pr123925.c: New test.
> ---
> .../gcc.target/riscv/rvv/autovec/pr123925.c | 28 ++++++++++
> gcc/tree-ssa-forwprop.cc | 55 +++++++++++--------
> 2 files changed, 60 insertions(+), 23 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123925.c
>
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123925.c
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123925.c
> new file mode 100644
> index 00000000000..c209387531c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123925.c
> @@ -0,0 +1,28 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target riscv_v_ok } */
> +/* { dg-add-options riscv_v } */
> +/* { dg-additional-options "-std=gnu99" } */
> +
> +typedef __attribute__((__vector_size__ (8))) unsigned char U;
> +typedef __attribute__((__vector_size__ (8))) signed long V;
> +
> +signed char s;
> +V v;
> +
> +void
> +__attribute__ ((noipa))
> +foo (U u, V *r)
> +{
> + __builtin_memmove (&s, &u, 1);
> + v += s;
> + *r = v;
> +}
> +
> +int
> +main ()
> +{
> + V x;
> + foo ((U) {248}, &x);
> + if (x[0] != -8)
> + __builtin_abort();
> +}
> diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> index cea5e70dd75..74e2875d769 100644
> --- a/gcc/tree-ssa-forwprop.cc
> +++ b/gcc/tree-ssa-forwprop.cc
> @@ -3975,14 +3975,29 @@ simplify_vector_constructor (gimple_stmt_iterator
> *gsi)
> if (refnelts < nelts)
> return false;
>
> + /* Determine the element type for the conversion source.
> + As orig_elem_type keeps track of the original type, check
> + if we need to perform a sign swap after permuting.
> + We need to be able to construct a vector type from the element
> + type which is not possible for e.g. BitInt or pointers
> + so pun with an integer type if needed. */
> + tree perm_eltype = TREE_TYPE (TREE_TYPE (orig[0]));
> + bool sign_change_p = false;
> + if (conv_code != ERROR_MARK
> + && orig_elem_type[0]
> + && TYPE_SIGN (orig_elem_type[0]) != TYPE_SIGN (perm_eltype))
> + {
> + perm_eltype = signed_or_unsigned_type_for
> + (TYPE_UNSIGNED (orig_elem_type[0]), perm_eltype);
> + sign_change_p = true;
> + }
> + tree conv_src_type = build_vector_type (perm_eltype, nelts);
> +
> if (maybe_ident)
> {
> - tree conv_src_type
> - = (nelts != refnelts
> - ? (conv_code != ERROR_MARK
> - ? build_vector_type (TREE_TYPE (TREE_TYPE (orig[0])), nelts)
> - : type)
> - : TREE_TYPE (orig[0]));
> + /* When there is no conversion, use the target type directly. */
> + if (conv_code == ERROR_MARK && nelts != refnelts)
> + conv_src_type = type;
> if (conv_code != ERROR_MARK
> && !supportable_convert_operation (conv_code, type, conv_src_type,
> &conv_code))
> @@ -4104,6 +4119,15 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
> gsi_insert_before (gsi, lowpart, GSI_SAME_STMT);
> orig[0] = gimple_assign_lhs (lowpart);
> }
> + else if (sign_change_p)
> + {
> + gassign *conv
> + = gimple_build_assign (make_ssa_name (conv_src_type),
> + build1 (VIEW_CONVERT_EXPR, conv_src_type,
> + orig[0]));
> + gsi_insert_before (gsi, conv, GSI_SAME_STMT);
> + orig[0] = gimple_assign_lhs (conv);
> + }
> if (conv_code == ERROR_MARK)
> {
> tree src_type = TREE_TYPE (orig[0]);
> @@ -4135,22 +4159,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
> && orig[1] == error_mark_node
> && !maybe_blend[0])
> return false;
> - tree mask_type, perm_type, conv_src_type;
> + tree mask_type, perm_type;
> perm_type = TREE_TYPE (orig[0]);
> - /* Determine the element type for the conversion source.
> - As orig_elem_type keeps track of the original type, check
> - if we need to perform a sign swap after permuting.
> - We need to be able to construct a vector type from the element
> - type which is not possible for e.g. BitInt or pointers
> - so pun with an integer type if needed. */
> - tree conv_elem_type = TREE_TYPE (perm_type);
> - if (conv_code != ERROR_MARK
> - && orig_elem_type[0]
> - && TYPE_SIGN (orig_elem_type[0]) != TYPE_SIGN (conv_elem_type))
> - conv_elem_type = signed_or_unsigned_type_for (TYPE_UNSIGNED
> - (orig_elem_type[0]),
> - conv_elem_type);
> - conv_src_type = build_vector_type (conv_elem_type, nelts);
> if (conv_code != ERROR_MARK
> && !supportable_convert_operation (conv_code, type, conv_src_type,
> &conv_code))
> @@ -4280,8 +4290,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
> /* Otherwise, we can still have an intermediate sign change.
> ??? In that case we have two subsequent conversions.
> We should be able to merge them. */
> - else if (conv_code != ERROR_MARK
> - && tree_nop_conversion_p (conv_src_type, perm_type))
> + else if (sign_change_p)
> res = gimple_build (&stmts, VIEW_CONVERT_EXPR, conv_src_type, res);
> /* Finally, apply the conversion. */
> if (conv_code != ERROR_MARK)
> --
> 2.52.0