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