Hi,

On 11/09/26 10:17 am, Michael Meissner wrote:
On Thu, Sep 10, 2026 at 05:17:01AM -0500, Manjunath S Matti wrote:
Hi,

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).

Changes from V2:
* Addressed review comments from Jakub.
* Removed stale code in rs6000_promote_function_mode.
* _BitInt <-> IBM double double (__ibm128): Modified files
floatbitinttf-ibm128.c and fixtfbitint-ibm128.c, provided by Jakub.
* Additional testcase bitint-bitint-to-ibm128.c and
bitint-ibm128-to-bitint.c, provided by Jakub.

Changes from V1:
* The major change being limb mode now DImode on 64-bit PowerPC and
SImode on 32-bit PowerPC.
* Padding bits above the precision in the most significant limb are
unspecified(bitint_ext_undef).  So the same rule describes ppc64le,
ppc64 big-endian and ppc32.
* Additional powerpc specific test cases.

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-08-19  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.

This looks good to me.  I tried it doing builds with the long double
format set to IBM double double and IEEE 128-bit.  There are no
additional failures when long double is IEEE 128 bit.

I tried my own test to verify all of the floating point tests correctly
set all of the mantissa bits when doing conversions.

On PowerPC Little Endian, I did notice that one test
(gcc.dg/dfp/int128-4.c) fails.  You can check in the changes to the
master branch, and we can fix it later.  Thanks for doing this work.

I don't see the failure on my setup

PASS: gcc.dg/dfp/int128-4.c (test for excess errors)
PASS: gcc.dg/dfp/int128-4.c execution test

We can look into this later, I will commit the changes for now incorporating suggestions by Jakub.

Thanks for your help and review Jakub and Mike.


Reply via email to