https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124135
--- Comment #21 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jakub Jelinek <[email protected]>: https://gcc.gnu.org/g:46520c0d388611586452cce8843d0d466eb4bb10 commit r16-7924-g46520c0d388611586452cce8843d0d466eb4bb10 Author: Jakub Jelinek <[email protected]> Date: Fri Mar 6 10:32:00 2026 +0100 tree-inline: Fix up ICE on !is_gimple_reg is_gimple_reg_type copying [PR124135] The first testcase below ICEs e.g. with -O2 on s390x-linux, the second with -O2 -m32 on x86_64-linux. We have <bb 2> [local count: 1073741824]: if (x_4(D) != 0) goto <bb 3>; [33.00%] else goto <bb 4>; [67.00%] <bb 3> [local count: 354334800]: _7 = qux (42); foo (0, &<retval>, _7); <bb 4> [local count: 1073741824]: return <retval>; on a target where <retval> has gimple reg type but is aggregate_value_p and TREE_ADDRESSABLE too. fnsplit splits this into <bb 2> [local count: 354334800]: _1 = qux (42); foo (0, &<retval>, _1); <bb 3> [local count: 354334800]: return <retval>; in the *.part.0 function and if (x_4(D) != 0) goto <bb 3>; [33.00%] else goto <bb 4>; [67.00%] <bb 3> [local count: 354334800]: <retval> = _Z3bari.part.0 (); <bb 4> [local count: 1073741824]: return <retval>; in the original function. Now, dunno if already that isn't invalid because <retval> has TREE_ADDRESSABLE set in the latter, but at least it is accepted by tree-cfg.cc verification. tree lhs = gimple_call_lhs (stmt); if (lhs && (!is_gimple_reg (lhs) && (!is_gimple_lvalue (lhs) || verify_types_in_gimple_reference (TREE_CODE (lhs) == WITH_SIZE_EXPR ? TREE_OPERAND (lhs, 0) : lhs, true)))) { error ("invalid LHS in gimple call"); return true; } While lhs is not is_gimple_reg, it is is_gimple_lvalue here. Now, inlining of the *.part.0 fn back into the original results in <retval> = a; statement which already is diagnosed by verify_gimple_assign_single: case VAR_DECL: case PARM_DECL: if (!is_gimple_reg (lhs) && !is_gimple_reg (rhs1) && is_gimple_reg_type (TREE_TYPE (lhs))) { error ("invalid RHS for gimple memory store: %qs", code_name); debug_generic_stmt (lhs); debug_generic_stmt (rhs1); return true; } __float128/long double are is_gimple_reg_type, but both operands aren't is_gimple_reg. The following patch fixes it by doing separate load and store, i.e. _42 = a; <retval> = 42; in this case. If we want to change verify_gimple_assign to disallow !is_gimple_reg (lhs) for is_gimple_reg_type (TREE_TYPE (lhs)), we'd need to change fnsplit instead, but I'd be afraid such a change would be more stage1 material (and certainly nothing that should be even backported to release branches). 2026-03-05 Jakub Jelinek <[email protected]> PR tree-optimization/124135 * tree-inline.cc (expand_call_inline): If both gimple_call_lhs (stmt) and use_retvar aren't gimple regs but have gimple reg type, use separate load of use_retva into SSA_NAME and then store of it into gimple_call_lhs (stmt). * g++.dg/torture/pr124135-1.C: New test. * g++.dg/torture/pr124135-2.C: New test.
