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

Reply via email to