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

Reply via email to