On Mon, Jan 27, 2025 at 11:32:17AM +0100, Richard Biener wrote:
> When RTL expansion of an out-of-bound access of a register falls
> back to a BIT_FIELD_REF we have to ensure that's valid. The
> following avoids negative offsets by expanding through a stack
> temporary.
>
> Bootstrap and regtest running on x86_64-unknown-linux-gnu.
>
> OK if that succeeds?
>
> Thanks,
> Richard.
>
> PR middle-end/118643
> * expr.cc (expand_expr_real_1): Avoid falling back to BIT_FIELD_REF
> expansion for negative offset.
>
> * gcc.dg/pr118643.c: New testcase.
> --- a/gcc/expr.cc
> +++ b/gcc/expr.cc
> @@ -11796,13 +11796,15 @@ expand_expr_real_1 (tree exp, rtx target,
> machine_mode tmode,
> && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
> return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
> target, tmode, modifier);
> - if (TYPE_MODE (type) == BLKmode)
> + if (TYPE_MODE (type) == BLKmode
> + || maybe_lt (offset, 0))
The whole condition would fit on one line.
> {
> temp = assign_stack_temp (DECL_MODE (base),
> GET_MODE_SIZE (DECL_MODE (base)));
> store_expr (base, temp, 0, false, false);
> - temp = adjust_address (temp, BLKmode, offset);
> - set_mem_size (temp, int_size_in_bytes (type));
> + temp = adjust_address (temp, TYPE_MODE (type), offset);
> + if (TYPE_MODE (type) == BLKmode)
> + set_mem_size (temp, int_size_in_bytes (type));
> return temp;
> }
> exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
Otherwise LGTM.
Jakub