https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118695
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
We're expanding <retval> = _2 via expand_return:
arg:0 <result_decl 0x7ffff6c88000 D.4676 type <pointer_type 0x7ffff6e20150>
unsigned ignored regdecl SI t.c:1:1 size <integer_cst 0x7ffff6e15120
32> unit-size <integer_cst 0x7ffff6e15138 4>
align:32 warn_if_not_align:0 context <function_decl 0x7ffff6c71800 g>
(reg/f:SI 114 [ <retval> ])>
arg:1 <ssa_name 0x7ffff6e0d828 type <pointer_type 0x7ffff6e20150>
visited
def_stmt _2 = MEM[(int * *)&obj + 4294967295B];
version:2
ptr-info 0x7ffff6c6ed80>>
where DECL_RESULT has (reg/f:SI 114 [ <retval> ])
so we go
else if (retval_rhs != 0
&& !VOID_TYPE_P (TREE_TYPE (retval_rhs))
&& (REG_P (result_rtl)
|| (GET_CODE (result_rtl) == PARALLEL)))
{
/* Compute the return value into a temporary (usually a pseudo reg). */
val
= assign_temp (TREE_TYPE (DECL_RESULT (current_function_decl)), 0, 1);
val = expand_expr (retval_rhs, val, GET_MODE (val), EXPAND_NORMAL);
val = force_not_mem (val);
expand_value_return (val);
where assign_temp gets us (reg:SI 116) but expand_expr () ends up expanding
to
(mem/c:SI (plus:SI (reg/f:SI 109 virtual-stack-vars)
(const_int -5 [0xfffffffffffffffb])) [0 S4 A8])
because we run into
case MEM_REF:
{
...
if (TYPE_MODE (type) == BLKmode || maybe_lt (offset, 0))
{
temp = assign_stack_temp (DECL_MODE (base),
GET_MODE_SIZE (DECL_MODE (base)));
which creates (mem/c:SI (plus:SI (reg/f:SI 109 virtual-stack-vars)
(const_int -4 [0xfffffffffffffffc])) [0 S4 A32])
but then
temp = adjust_address (temp, TYPE_MODE (type), offset);
makes the MEM unaligned (offset is minus one). But the original ref
was aligned (bogously). We already do
if (TYPE_MODE (type) == BLKmode)
set_mem_size (temp, int_size_in_bytes (type));
I suppose we can similarly do a set_mem_align though in this case
get_object_alignment on the MEM_REF correctly returns 8. I suppose
we fail to properly go the extract_bitfield path here that we'd chosen
when going expand_assignment or previous to the -1 offset handling
when dispatching to BIT_FIELD_REF expansion (which cannot handle a -1
offset correctly - we've generated "wrong" code before).