On Thu, Jun 18, 2026 at 9:24 AM Alex Coplan <[email protected]> wrote:
>
> Hi all,
>
> svset_impl::fold lowers svset intrinsics into a copy of the entire tuple
> and then a subsequent update of the given tuple member to the new vector
> value, e.g.:
>
>   D.14149 = svset2_f32 (a, 0, v);
>
> gets lowered into:
>
>   D.14149 = a;
>   D.14149.__val[0] = v;
>
> .  Because both stmts use the lhs of the original call stmt, the code
> unshares the expressions.  As svset_impl::fold notes:
>
>     /* [...]
>        The fold routines expect the replacement statement to have the
>        same lhs as the original call, so return the copy statement
>        rather than the field update.  */
>
> ultimately gsi_replace asserts that:
>
>   gimple_get_lhs (orig_stmt) == gimple_get_lhs (stmt)
>
> i.e. requiring pointer equality, but the copy stmt we build is:
>
>   gassign *copy = gimple_build_assign (unshare_expr (f.lhs), rhs_tuple);
>
> and notably the unshare_expr means that the pointer equality test above
> fails.  For VAR_DECLs (as above) it happens to work, since those aren't
> unshared.  mostly_copy_tree_r (called from unshare_expr) has:
>
>   /* Stop at types, decls, constants like copy_tree_r.  */
>   else if (TREE_CODE_CLASS (code) == tcc_type
>            || TREE_CODE_CLASS (code) == tcc_declaration
>            || TREE_CODE_CLASS (code) == tcc_constant)
>     *walk_subtrees = 0;
>
> but for MEM_EXPRs (as with the tescase in the PR) we *do* actually
> unshare them, and thus trip the assert in gsi_replace (or since
> r17-1237-g4fb2541debcca1, ICE in completely_unused, but the root cause
> is the same).
>
> We want the stmt returned from svset_impl::fold (copy) to have a
> pointer-identical lhs as the original stmt, so this patch just changes
> which use of f.lhs is unshared.  We keep copy's use as per the original
> stmt, and unshare the use in the update stmt instead.
>
> Bootstrapped/regtested on aarch64-linux-gnu, OK for trunk and backports
> to all active branches after some time to bake?


Ok. In fact now svset_impl::fold matches the other functions which has
this same pattern.

Thanks,
Andrea

>
> Thanks,
> Alex
>
> gcc/ChangeLog:
>
>         PR target/125818
>         * config/aarch64/aarch64-sve-builtins-base.cc (svset_impl::fold): Fix
>         unsharing to ensure the returned stmt has the exact same lhs as the
>         original.


>
> gcc/testsuite/ChangeLog:
>
>         PR target/125818
>         * gcc.target/aarch64/torture/pr125818.c: New test.
> ---
>  gcc/config/aarch64/aarch64-sve-builtins-base.cc     | 4 ++--
>  gcc/testsuite/gcc.target/aarch64/torture/pr125818.c | 6 ++++++
>  2 files changed, 8 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/torture/pr125818.c
>

Reply via email to