Skip to content
Snippets Groups Projects
Commit 1c26adba authored by Richard Sandiford's avatar Richard Sandiford
Browse files

aarch64: Fix ABI handling of aligned enums [PR109661]

aarch64_function_arg_alignment has traditionally taken the alignment
of a scalar type T from TYPE_ALIGN (TYPE_MAIN_VARIANT (T)).  This is
supposed to discard any user alignment and give the alignment of the
underlying fundamental type.

PR109661 shows that this did the wrong thing for enums with
a defined underlying type, because:

(1) The enum itself could be aligned, using attributes.
(2) The enum would pick up any user alignment on the underlying type.

We get the right behaviour if we look at the TYPE_MAIN_VARIANT
of the underlying type instead.

As always, this affects register and stack arguments differently,
because:

(a) The code that handles register arguments only considers the
    alignment of types that occupy two registers, whereas the
    stack alignment is applied regardless of size.

(b) The code that handles register arguments tests the alignment
    for equality with 16 bytes, so that (unexpected) greater alignments
    are ignored.  The code that handles stack arguments instead caps the
    alignment to 16 bytes.

There is now (since GCC 13) an assert to trap the difference between
(a) and (b), which is how the new incompatiblity showed up.

Clang alredy handled the testcases correctly, so this patch aligns
the GCC behaviour with the Clang behaviour.

I'm planning to remove the asserts on the branches, since we don't
want to change the ABI there.

gcc/
	PR target/109661
	* config/aarch64/aarch64.cc (aarch64_function_arg_alignment): Add
	a new ABI break parameter for GCC 14.  Set it to the alignment
	of enums that have an underlying type.  Take the true alignment
	of such enums from the TYPE_ALIGN of the underlying type's
	TYPE_MAIN_VARIANT.
	(aarch64_function_arg_boundary): Update accordingly.
	(aarch64_layout_arg, aarch64_gimplify_va_arg_expr): Likewise.
	Warn about ABI differences.

gcc/testsuite/
	* g++.target/aarch64/pr109661-1.C: New test.
	* g++.target/aarch64/pr109661-2.C: Likewise.
	* g++.target/aarch64/pr109661-3.C: Likewise.
	* g++.target/aarch64/pr109661-4.C: Likewise.
	* gcc.target/aarch64/pr109661-1.c: Likewise.
parent 3a4a39b3
No related branches found
No related tags found
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment