public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug other/97473] New: Spilled function parameters not aligned properly on multiple non-x86 targets
@ 2020-10-17 20:03 nate at thatsmathematics dot com
  2020-10-18 14:55 ` [Bug other/97473] " hjl.tools at gmail dot com
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: nate at thatsmathematics dot com @ 2020-10-17 20:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97473

            Bug ID: 97473
           Summary: Spilled function parameters not aligned properly on
                    multiple non-x86 targets
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nate at thatsmathematics dot com
  Target Milestone: ---

Created attachment 49394
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49394&action=edit
Test case

Suppose we have a type V requiring alignment, such as with
__attribute__((aligned(N))).  In current versions of gcc, both 10.2 and recent
trunk, it appears that local (auto) variables of this type are properly aligned
on the stack, at least on all the targets I tested.  However, on many targets
other than x86, alignment is apparently not respected for function parameters
of this type when their address is taken. 

The function parameter may actually be passed in a register, in which case when
its address is taken, it must be spilled to the stack.  But on the failing
targets, the spilled copy is not sufficiently aligned, and so for instance,
other functions which receive a pointer to this variable will find it does not
have the alignment that it should.

I'm not sure if this is a bug or a limitation, but it's quite counterintuitive,
since function parameters generally can be treated like local variables for
most other purposes.  I couldn't find any mention of this in the documentation
or past bug reports.

This can be reproduced by a very short C example like the following:

typedef int V __attribute__((aligned(64)));

void g(V *);

void f(V x) {
    g(&x);
}

The function g can get a pointer that is not aligned to 64 bytes.  A more
complete test case is attached, which I tested mainly on ARM and AArch64 with
gcc 10.2 and also trunk.  It seems to happen with or without optimization, so
long as one prevents IPA of g.  Inspection of the assembly shows gcc does not
generate any code to align the objects beyond the stack alignment guaranteed by
the ABI (8 bytes for ARM, 16 bytes for AArch64).

It fails on (complete gcc -v output below):

- aarch64-linux-gnu 10.2.0 and trunk from today
- arm-linux-gnueabihf 10.2.0 and trunk from last week
- alpha-linux-gnu 10.2.0
- sparc64-linux-gnu 10.2.0
- mips-linux-gnu 10.2.0

It succeeds on:

- x86_64-linux-gnu 10.2.0, also with -m32

On x86_64-linux-gnu, gcc generates instructions to align the stack and place
the spilled copy of x at an aligned address, and the testcase passes there. 
(Perhaps this was implemented to support AVX?)  With -m32 it copies x from its
original unaligned position on the stack into an aligned stack slot.

As noted, auto variables of the same type do get proper alignment on all the
platforms I tested, and so one can work around with `V tmp = x; g(&tmp);`.

For what it's worth, clang on ARM and AArch64 does align the spilled copies.

I was not sure which pass of the compiler is responsible for this so I just
chose component "other".  I didn't think "target" was appropriate as this
affects many targets, though not all.

This issue was brought to my attention by StackOverflow user Alf (thanks!), see
https://stackoverflow.com/questions/64287587/memory-alignment-issues-with-gcc-vector-extension-and-arm-neon.
 Alf's original program was in C++ for ARM32 with NEON and the hard-float ABI,
and involved mixing functions that passed vector types (like int32x4_t) either
by value or by by reference.  In this setting they can be passed by value in
SIMD registers, but in memory they require 16-byte alignment.  This was
violated, resulting in bus errors at runtime.  So there is "real life" code
affected by this.

I tried including full `gcc -v` output from all versions tested, but it seems
to be triggering the bugzilla spam filter, so I'm omitting it.  Hopefully it
isn't needed, but let me know if it is.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug other/97473] Spilled function parameters not aligned properly on multiple non-x86 targets
  2020-10-17 20:03 [Bug other/97473] New: Spilled function parameters not aligned properly on multiple non-x86 targets nate at thatsmathematics dot com
@ 2020-10-18 14:55 ` hjl.tools at gmail dot com
  2020-10-18 19:04 ` nate at thatsmathematics dot com
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: hjl.tools at gmail dot com @ 2020-10-18 14:55 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97473

--- Comment #1 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to Nate Eldredge from comment #0)
>
> On x86_64-linux-gnu, gcc generates instructions to align the stack and place
> the spilled copy of x at an aligned address, and the testcase passes there. 
> (Perhaps this was implemented to support AVX?)  With -m32 it copies x from
> its original unaligned position on the stack into an aligned stack slot.
> 

When we enabled AVX in GCC, we updated middle-end to properly align
the shack with backend hooks.  A backend can properly align the stack
if it implements similar hooks for stack re-alignment.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug other/97473] Spilled function parameters not aligned properly on multiple non-x86 targets
  2020-10-17 20:03 [Bug other/97473] New: Spilled function parameters not aligned properly on multiple non-x86 targets nate at thatsmathematics dot com
  2020-10-18 14:55 ` [Bug other/97473] " hjl.tools at gmail dot com
@ 2020-10-18 19:04 ` nate at thatsmathematics dot com
  2020-10-19  7:31 ` [Bug target/97473] " rguenth at gcc dot gnu.org
  2020-10-20  0:06 ` hp at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: nate at thatsmathematics dot com @ 2020-10-18 19:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97473

--- Comment #2 from Nate Eldredge <nate at thatsmathematics dot com> ---
Possibly related to bug 84877 ?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug target/97473] Spilled function parameters not aligned properly on multiple non-x86 targets
  2020-10-17 20:03 [Bug other/97473] New: Spilled function parameters not aligned properly on multiple non-x86 targets nate at thatsmathematics dot com
  2020-10-18 14:55 ` [Bug other/97473] " hjl.tools at gmail dot com
  2020-10-18 19:04 ` nate at thatsmathematics dot com
@ 2020-10-19  7:31 ` rguenth at gcc dot gnu.org
  2020-10-20  0:06 ` hp at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-10-19  7:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97473

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|other                       |target

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
To not disrupt the ABI such parameters have to be copied in the callee to
appropriately aligned stack slots or (with disrupting the ABI), passed
by reference.

I think separate bugs, one for each affected target, are appropriate here.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug target/97473] Spilled function parameters not aligned properly on multiple non-x86 targets
  2020-10-17 20:03 [Bug other/97473] New: Spilled function parameters not aligned properly on multiple non-x86 targets nate at thatsmathematics dot com
                   ` (2 preceding siblings ...)
  2020-10-19  7:31 ` [Bug target/97473] " rguenth at gcc dot gnu.org
@ 2020-10-20  0:06 ` hp at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: hp at gcc dot gnu.org @ 2020-10-20  0:06 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97473

Hans-Peter Nilsson <hp at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hp at gcc dot gnu.org

--- Comment #4 from Hans-Peter Nilsson <hp at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #3)
> To not disrupt the ABI such parameters have to be copied in the callee to
> appropriately aligned stack slots or (with disrupting the ABI), passed
> by reference.
> 
> I think separate bugs, one for each affected target, are appropriate here.

This definitely looks like a dup of PR84877.

If that one should be split into separate target-specific PRs, then that's a
separate issue.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-10-20  0:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-17 20:03 [Bug other/97473] New: Spilled function parameters not aligned properly on multiple non-x86 targets nate at thatsmathematics dot com
2020-10-18 14:55 ` [Bug other/97473] " hjl.tools at gmail dot com
2020-10-18 19:04 ` nate at thatsmathematics dot com
2020-10-19  7:31 ` [Bug target/97473] " rguenth at gcc dot gnu.org
2020-10-20  0:06 ` hp at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).