https://gcc.gnu.org/g:9acbae69609a41df0f20db6222842414a85067ea

commit r17-2739-g9acbae69609a41df0f20db6222842414a85067ea
Author: Kyrylo Tkachov <[email protected]>
Date:   Sun Jul 26 05:18:52 2026 -0700

    middle-end: look through VEC_DUPLICATE_EXPR in ssa_uniform_vector_p
    
    ssa_uniform_vector_p is documented as returning the element a uniform
    vector is a splat from, and it handles VEC_DUPLICATE_EXPR when it is
    handed the bare tree.  It did not handle the much more common gimple
    form, where the splat is the RHS of an SSA definition: VEC_DUPLICATE_EXPR
    is a unary operation, so gimple_assign_single_p is false for it and the
    SSA_NAME path fell through to NULL_TREE.
    
    Splats started reaching the helper in that form with
    r17-2019-g770ff476d06f ("aarch64: Port NEON vector creation intrinsics to
    pragma-based framework"), after which vdup_n_u8 and friends fold to
    
      uniform_vec_5 = [vec_duplicate_expr] _1;
    
    rather than to a CONSTRUCTOR, so ssa_uniform_vector_p stopped seeing
    through them.  Callers that lose out are the lowpart-to-highpart NEON
    builtin fold in the aarch64 back end, vector shift and division
    lowering in tree-vect-generic.cc, and the CONSTRUCTOR-of-splats
    simplification in tree-ssa-forwprop.cc.
    
    For gcc.target/aarch64/simd/fold_to_highpart_7.c this restores
    
      ldr     q0, [x1]
      ld1r    {v31.16b}, [x0]
      umull2  v0.8h, v0.16b, v31.16b
    
    in place of a lowpart umull with the highpart fold missed.
    Bootstrapped and tested on aarch64-none-linux-gnu.
    
    gcc/ChangeLog:
    
            * tree.cc (ssa_uniform_vector_p): Look through a
            VEC_DUPLICATE_EXPR SSA definition.
    
    Signed-off-by: Kyrylo Tkachov <[email protected]>

Diff:
---
 gcc/tree.cc | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/gcc/tree.cc b/gcc/tree.cc
index b80068093225..c8aa42b3e10e 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -10878,6 +10878,11 @@ ssa_uniform_vector_p (tree op)
       gimple *def_stmt = SSA_NAME_DEF_STMT (op);
       if (gimple_assign_single_p (def_stmt))
        return uniform_vector_p (gimple_assign_rhs1 (def_stmt));
+      /* A VEC_DUPLICATE_EXPR is a unary assignment, so it is not covered
+        by the gimple_assign_single_p case above.  */
+      if (is_gimple_assign (def_stmt)
+         && gimple_assign_rhs_code (def_stmt) == VEC_DUPLICATE_EXPR)
+       return gimple_assign_rhs1 (def_stmt);
     }
   return NULL_TREE;
 }

Reply via email to