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

--- Comment #16 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Avinash Jayakar <[email protected]>:

https://gcc.gnu.org/g:83998f47450c088493c971d46ae3b6dadb7242b3

commit r17-4163-g83998f47450c088493c971d46ae3b6dadb7242b3
Author: Manjunath S Matti <[email protected]>
Date:   Fri Sep 11 05:06:56 2026 -0500

    rs6000: Add ABI and libgcc support for C23 _BitInt [PR117584]

    Jakub, thanks for floatbitinttf-ibm128.c and fixtfbitint-ibm128.c and
    the follow-up fix.

    The changes have been bootstrapped and regression tested on
    powerpc64le-linux and powerpc64-linux (m64/m32).

    This patch implements the powerpc64le/ppc64/ppc32 target hook and
    libgcc runtime support needed for GCC's existing C23 _BitInt
    front-end/middle-end machinery to work on rs6000.  Previously
    TARGET_C_BITINT_TYPE_INFO was unimplemented on this target, so
    _BitInt was entirely unsupported.

    rs6000_bitint_type_info selects the limb mode by precision: QImode,
    HImode or SImode for n <= 8, 16 or 32 respectively, and above that the
    widest integer that fits in one general purpose register,
    i.e. DImode on 64-bit PowerPC and SImode on 32-bit PowerPC.

    The ABI limb mode always equals the internal limb mode, so a _BitInt
    wider than one limb is an array of limbs, ordered least to most
    significant on little-endian and most to least significant on
    big-endian, exactly like any other multi-word integer.  Padding bits
    above the precision in the most significant limb are unspecified
    (bitint_ext_undef).  Neither property is conditional on endianness, so
    the same rule describes ppc64le, ppc64 big-endian and ppc32.

    Large _BitInt -- more than 16 bytes under ELFv2, more than 8 bytes
    otherwise -- is passed and returned by reference, as aggregates of
    those sizes already are.  The threshold is computed in one place,
    rs6000_bitint_large_p, so that rs6000_return_in_memory and
    rs6000_pass_by_reference cannot drift apart.  Both use BITINT_TYPE_P
    rather than a TREE_CODE test, so that C2Y bit-precise enums backed by
    _BitInt are handled identically to plain _BitInt.

    rs6000_function_value excludes BITINT_TYPE from the generic sub-word
    integer promotion, so that the mode used for a _BitInt return value
    agrees with the one the middle end computes for the type.

    13 powerpc execution tests covering alignment, size, argument and
    return passing (including the by-reference threshold and the
    transition around 128 bits), arithmetic, bitwise and shift operations,
    comparisons, conversions, byte layout, struct layout and varargs

    Tested on powerpc64le-linux and powerpc64-linux (big endian, both
    multilibs).  One known failure remains on big endian:
    gcc.dg/torture/bitint-16.c fails its -O2 execution test with -m32.

    2026-09-11  Manjunath Matti  <[email protected]>

    gcc/ChangeLog:

            PR target/117584
            * config/rs6000/rs6000-call.cc (rs6000_bitint_large_p): New
            function.
            (rs6000_return_in_memory): Return large _BitInt values, and enums
            backed by _BitInt, via a hidden pointer.
            (rs6000_pass_by_reference): Pass large _BitInt values, and enums
            backed by _BitInt, by reference.
            * config/rs6000/rs6000.cc (TARGET_C_BITINT_TYPE_INFO): Define.
            (init_float128_ibm): Set bitinttofp_optab and bitintfromfp_optab
            libfuncs to __floatbitinttf and __fixtfbitint.
            (init_float128_ieee): Set bitinttofp_optab and bitintfromfp_optab
            libfuncs to __floatbitintkf and __fixkfbitint.
            (rs6000_function_value): Exclude BITINT_TYPE from sub-word integer
            return value promotion.
            (rs6000_bitint_type_info): New function.

    libgcc/ChangeLog:

            PR target/117584
            * config/rs6000/float128-sed: Add __floatbitinttf/__floatbitintkf
            and __fixtfbitint/__fixkfbitint substitution rules.
            * config/rs6000/float128-sed-hw: Likewise.
            * config/rs6000/libgcc-glibc.ver (GCC_17.0.0): New version node
            inheriting GCC_4.2.0; export __floatbitintkf, __fixkfbitint,
            __floatbitinttf, __fixtfbitint, __floatbitintsf, __fixsfbitint,
            __floatbitintdf and __fixdfbitint.
            * config/rs6000/t-float128 (fp128_softfp_funcs): Add floatbitintkf
            and fixkfbitint.
            (rs6000_bitint_bin_funcs, rs6000_bitint_bin_src): New; add to
            LIB2ADD unconditionally.
            (rs6000_bitint_dec_funcs, rs6000_bitint_dec_src): New; add to
            LIB2ADD_ST when decimal float is enabled.
            * config/rs6000/t-linux (ibm128_bitint_funcs, ibm128_bitint_src):
            New; add to LIB2ADD.
            (ibm128_bitint_objs, IBM128_BITINT_CFLAGS): New.
            * config/rs6000/floatbitinttf-ibm128.c: New file.
            * config/rs6000/fixtfbitint-ibm128.c: New file.

    gcc/testsuite/ChangeLog:

            PR target/117584
            * gcc.target/powerpc/bitint-abi-call.c: New test.
            * gcc.target/powerpc/bitint-alignments-powerpc.c: New test.
            * gcc.target/powerpc/bitint-args-powerpc.c: New test.
            * gcc.target/powerpc/bitint-arith-powerpc.c: New test.
            * gcc.target/powerpc/bitint-bitint-to-ibm128.c: New test.
            * gcc.target/powerpc/bitint-bitwise-powerpc.c: New test.
            * gcc.target/powerpc/bitint-compare-powerpc.c: New test.
            * gcc.target/powerpc/bitint-conversions-powerpc.c: New test.
            * gcc.target/powerpc/bitint-endian-powerpc.c: New test.
            * gcc.target/powerpc/bitint-ibm128-to-bitint.c: New test.
            * gcc.target/powerpc/bitint-sizes-powerpc.c: New test.
            * gcc.target/powerpc/bitint-struct-layout.c: New test.
            * gcc.target/powerpc/bitint-varargs.c: New test.

    Co-authored-by: Jakub Jelinek <[email protected]>
    Signed-off-by: Manjunath Matti <[email protected]>

Reply via email to