[Bug target/125818] ICE with SVE intrinsics in aarch64_gimple_fold_builtin: expected ssa_name, have mem_ref
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Jun 29 13:50:58 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125818
--- Comment #14 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-14 branch has been updated by Alex Coplan
<acoplan@gcc.gnu.org>:
https://gcc.gnu.org/g:9bc6561c40525b34439958df84eca8c6d54a54fc
commit r14-12712-g9bc6561c40525b34439958df84eca8c6d54a54fc
Author: Alex Coplan <alex.coplan@arm.com>
Date: Thu Jun 18 15:05:07 2026 +0100
aarch64: Fix unsharing in svset_impl::fold [PR125818]
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.
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.
(cherry picked from commit f6aac7ffab9f80d55b58beafc87da3379a70672a)
More information about the Gcc-bugs
mailing list