Am Montag, dem 06.07.2026 um 19:23 +0200 schrieb Jakub Jelinek:
> On Mon, Jul 06, 2026 at 05:09:53PM +0200, Martin Uecker wrote:
> > The design looks very reasonable to me, but I have two
> > comments/questions:
> > 
> > Do we need the full generality, i.e.  support for LE, BE and
> > any limb type or could we simply fix this to whatever corresponds
> > to the ABI?  Maybe I am missing something obvious.
> 
> Hardcoding some limb type to some _BitInt limb type (but which one,
> on many architectures we have two, the ABI one which influences
> size/alignment decision and another one, often smaller width
> but sometimes the same, which is used in most of the operations)
> would simplify it a little bit, but would be a nightmare for C library
> writers or users which want to write similar APIs in their libraries.

> As I wrote, at least for the libc built with older compiler which doesn't
> support this (which is something that needs to be supported for at least
> a few years), my plan was that one would compile these intrinsics/macros
> into assembly and use in the library.  But the library better should be
> able to choose what limb it wants to use and use it on all architectures,
> rather than dealing with on aarch64 I need 128-bit limb type, on x86_64
> 64-bit limb type, on i686 32-bit limb type, ...

I would have assumed they might want to anyway use the same limb type
that is also used by the ABI for _BitInt for large N.  Then one would
need to expose this type to  the user somehow (__BITINT_LIMB_T__). 
But Joseph also gave an argument why libraries might want to pick another
type, so I guess it is better to allow a choice.

> 
> Now, one could hardcode some limb type for all users, say
> unsigned long, but I wasn't sure that is the right choice for all the
> C libraries and all users.  I'd say the most usual choices will be likely
> unsinged long, unsigned int and unsigned long long, but already that that
> point the intrinsic needs to support all the cases the posted patch handles,
> namely when the user chosen limb has smaller width than the _BitInt internal
> limb type (but right now the _BitInt internal limb type width has to be
> divisible by the user chosen limb width in that case), or same width, or
> larger width (the posted patch requires double the width in that case).
> I intentionally chose not to support bit-precise integers in the
> type-generic macro, don't think splitting some _BitInt(n) for runtime n
> into an array of _BitInt(17) or array of _BitInt(925) is useful or
> worth the effort.
> 
> Regarding endianity, sure, we could hardcode say little-endian ordering,
> or always match the architecture endianity, but that again makes the
> C library maintainance harder for little gain on the compiler side.
> 
> > In general for libraries (or user code) there is the issue
> > that different systems may support a different number of bits,
> > and once a library is compiled with one compiler could break
> > (or have limitations) for code using another.  This may become
> > a bigger concern when we want to introduce standard library
> > functionality using _BitInt.   So I wonder  whether these 
> > builtins could be made to work for an arbitrary number 
> > of bits exceeding what the current limit for GCC is.
> 
> There are psABIs which specify the size/alignment/passing/returning of
> _BitInt(N), and GCC chose to support _BitInt only on architectures
> where this is specified or where GCC is a de-factor psABI for the arch.
> For both the __builtin_va_arg_bitint va_arg side, and
> __builtin_bitint_*pack (or __builtin_va_arg_bitint __builtin_bitint_unpack
> side) the emitted code uses (matching the psABIs), something like
>   if (n <= 8)
>     load using _BitInt(8) (but with alias set matching anything or any 
> _BitInt)
>   else if (n <= 16)
>     load using _BitInt(16) (but with alias set matching anything or any 
> _BitInt)
>   else if (n <= 32)
>     load using _BitInt(32) (but with alias set matching anything or any 
> _BitInt)
> ...
>   else
>     load or handle using VLA of the ABI and/or internal limb types with
>     alias set matching anything or any _BitInt
> so the first few n values are handled as special cases and rest handles the
> larger ones of arbitrary sizes.  And what GCC emits in that case can handle
> any BITINT_MAXWIDTH, doesn't stop at 65535, will happily handle even the
> clang BITINT_MAXWIDTH it has on the 2 or 3 architectures (rest have I think
> still 128 and don't follow psABI or follow it by accident).
> Of course unless clang chooses to follow psABI for N <= 65535 and for some
> larger ones chooses some completely different ABI.  I'm not aware of that
> though, who would bother with something like that.  All that e.g. GCC
> supports internally is some small width special cases and then anything
> larger being treated usually as a struct with a single array member of
> the ABI limb type.

That makes sense, so there is no arbitrary limit and - assuming no one
switches to some new ABI for large N - no compatibility risks. 


Martin

Reply via email to