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)
