On Wed, Jan 29, 2025 at 03:46:46PM +0100, Richard Biener wrote:
> The following guards the BIT_FIELD_REF expansion fallback for
> MEM_REFs of entities expanded to register (or constant) further,
> avoiding large out-of-bound offsets by, when the access does not
> overlap the base object, expanding the offset as if it were zero.
> 
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> 
> I didn't feel lucky enough trying to simply return const0_rtx for
> fully out-of-bound accesses.
> 
> OK?
> 
> Thanks,
> Richard.
> 
>       PR middle-end/118692
>       * expr.cc (expand_expr_real_1): When expanding a MEM_REF
>       as BIT_FIELD_REF avoid large offsets for accesses not
>       overlapping the base object.
> 
>       * gcc.dg/pr118692.c: New testcase.
> ---
>  gcc/expr.cc                     |  8 ++++++++
>  gcc/testsuite/gcc.dg/pr118692.c | 10 ++++++++++
>  2 files changed, 18 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/pr118692.c
> 
> diff --git a/gcc/expr.cc b/gcc/expr.cc
> index 7f3149b85ee..10467f82c0d 100644
> --- a/gcc/expr.cc
> +++ b/gcc/expr.cc
> @@ -11806,6 +11806,14 @@ expand_expr_real_1 (tree exp, rtx target, 
> machine_mode tmode,
>                 set_mem_size (temp, int_size_in_bytes (type));
>               return temp;
>             }
> +         /* When the access is fully outside of the underlying object
> +            expand the offset as zero.  This avoids out-of-bound
> +            BIT_FIELD_REFs and generates smaller code for these cases
> +            with UB.  */
> +         type_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type));
> +         if (!ranges_maybe_overlap_p (offset, type_size, 0,
> +                                      GET_MODE_SIZE (DECL_MODE (base))))
> +           offset = 0;
>           exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
>                         bitsize_int (offset * BITS_PER_UNIT));
>           REF_REVERSE_STORAGE_ORDER (exp) = reverse;
> diff --git a/gcc/testsuite/gcc.dg/pr118692.c b/gcc/testsuite/gcc.dg/pr118692.c
> new file mode 100644
> index 00000000000..49cff35b8b7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr118692.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +_Complex cf;

Please use _Complex double here.
> +
> +void
> +foo(char c)
> +{
> +  cf += *(_Complex *)__builtin_memcpy(8143523003042804629 + &c, 0, 0);

Ditto here.
I think it might be a good idea to use LL suffix after the constant too.

Otherwise LGTM.

        Jakub

Reply via email to