On Wed, 7 Oct 2026, Igor Shevlyakov wrote:

> From: Igor Shevlyakov <[email protected]>
> 
> expand_builtin_return wraps the address returned by __builtin_apply in
> a BLKmode MEM with the default MEM_ALIGN of 8 bits, so every
> return-register restore produced by adjust_address is treated as
> byte-aligned.  On strict-alignment targets, or targets whose address
> legitimacy or load/store selection depends on MEM_ALIGN, this picks
> misaligned access sequences or addresses the target cannot handle.
> 
> The argument of __builtin_return must be the value returned by
> __builtin_apply, and expand_builtin_apply allocates that block with
> assign_stack_local (..., -1), which aligns it to BIGGEST_ALIGNMENT
> capped at MAX_SUPPORTED_STACK_ALIGNMENT.  Record that alignment on the
> MEM.
> 
> The patch attached to the PR goes the other way: it expands each restore
> through expand_misaligned_mem_ref whenever MEM_ALIGN is below the mode's
> alignment.  That only pessimizes valid code: the documentation requires
> the argument of __builtin_return to be a value returned by
> __builtin_apply, and that block always has the alignment recorded here.
> The PR's testcase passes an arbitrary pointer, which is outside that
> contract.

The alignment is actually rounded down according to 'size' but that
size is lost?

>       PR rtl-optimization/112417
> 
> gcc/ChangeLog:
> 
>       * builtins.cc (expand_builtin_return): Set the alignment of the
>       result block.
> 
> gcc/testsuite/ChangeLog:
> 
>       * gcc.target/i386/pr112417.c: New test.
> 
> Signed-off-by: Igor Shevlyakov <[email protected]>
> ---
> Bootstrapped and regtested on x86_64-pc-linux-gnu (-m32/-m64), no new 
> regressions.
> 
>  gcc/builtins.cc                          |  4 ++++
>  gcc/testsuite/gcc.target/i386/pr112417.c | 19 +++++++++++++++++++
>  2 files changed, 23 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr112417.c
> 
> diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> index e31947bfed6..b8cad151624 100644
> --- a/gcc/builtins.cc
> +++ b/gcc/builtins.cc
> @@ -1845,6 +1845,10 @@ expand_builtin_return (rtx result)
>  
>    apply_result_size ();
>    result = gen_rtx_MEM (BLKmode, result);
> +  /* RESULT was allocated by __builtin_apply with assign_stack_local
> +     (..., -1); record the alignment that gives it.  */
> +  set_mem_align (result, MIN (BIGGEST_ALIGNMENT,
> +                           MAX_SUPPORTED_STACK_ALIGNMENT));
>  
>    if (targetm.have_untyped_return ())
>      {
> diff --git a/gcc/testsuite/gcc.target/i386/pr112417.c 
> b/gcc/testsuite/gcc.target/i386/pr112417.c
> new file mode 100644
> index 00000000000..2f60af37284
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr112417.c
> @@ -0,0 +1,19 @@
> +/* PR rtl-optimization/112417 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mno-avx -mtune=generic" } */
> +
> +/* The block returned by __builtin_apply is aligned to BIGGEST_ALIGNMENT,
> +   so __builtin_return can restore the SSE return registers with aligned
> +   loads.  */
> +
> +extern void target (int, double);
> +
> +void
> +fwd (int a, double d)
> +{
> +  void *args = __builtin_apply_args ();
> +  void *ret = __builtin_apply ((void (*) ()) target, args, 64);
> +  __builtin_return (ret);
> +}
> +
> +/* { dg-final { scan-assembler "\tmovdqa\t" } } */
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri; (HRB 36809, AG Nuernberg)

Reply via email to