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

--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Kyrylo Tkachov <[email protected]>:

https://gcc.gnu.org/g:b14ad46e6689cba2dd316bf677ad4f36278f9d3d

commit r17-2191-gb14ad46e6689cba2dd316bf677ad4f36278f9d3d
Author: Kyrylo Tkachov <[email protected]>
Date:   Wed Jun 17 02:03:41 2026 -0700

    aarch64: Fix ICE in aarch64_function_arg_alignment with may_alias
[PR124146]

    aarch64_function_arg_alignment returns the ABI alignment of an argument.
    For scalars and vectors this is the natural alignment of the type,
    ignoring any user-specified alignment.  The code obtains the natural
    alignment from the TYPE_MAIN_VARIANT, relying on the main variant having
    no user alignment.  PR108910 showed that this does not hold for pointers,
    and that case is handled explicitly.

    PR124146 is another counterexample.  An attribute that affects type
    identity, such as may_alias, makes a type its own TYPE_MAIN_VARIANT, so
    the main variant retains the user alignment requested by the aligned
    attribute.  TYPE_MAIN_VARIANT therefore does not strip the alignment and
    the gcc_assert (!TYPE_USER_ALIGN (type)) fires.

    In the testcase the may_alias+aligned type reaches the argument-passing
    code because foo is inlined into bar and forwprop propagates the value
    of that type directly into the recursive call to bar.

    Fix it by ignoring user alignment explicitly: when the type still has
    user alignment, use the natural alignment of its mode, exactly as the
    !type path at the top of the function already does.  Behaviour is
    unchanged for the existing (non-user-aligned) cases, since the natural
    alignment of a scalar or vector equals its mode alignment.  This also
    gives the natural alignment when a may_alias typedef lowers the
    alignment of a 16-byte type, matching the AAPCS64 (and Clang).

    The same applies to _BitInt, which is covered by pr124146-4.c: user
    alignment is ignored so a _BitInt up to 64 bits uses a single register,
    one between 65 and 128 bits uses a 16-byte two-register container, and
    one wider than 128 bits is passed by reference.

    Bootstrapped and tested on aarch64-none-linux-gnu.

    gcc/
            PR target/124146
            * config/aarch64/aarch64.cc (aarch64_function_arg_alignment):
            Ignore user alignment left on a type's main variant; use the
            mode's natural alignment instead.

    gcc/testsuite/
            PR target/124146
            * gcc.target/aarch64/pr124146.c: New test.
            * gcc.target/aarch64/pr124146-2.c: New test.
            * gcc.target/aarch64/pr124146-3.c: New test.
            * gcc.target/aarch64/pr124146-4.c: New test.

    Signed-off-by: Kyrylo Tkachov <[email protected]>

Reply via email to