"Andre Vieira (lists)" <andre.simoesdiasvie...@arm.com> writes:
> This patch adds support for C23's _BitInt for the AArch64 port when 
> compiling for little endianness.  Big Endianness requires further 
> target-agnostic support and we therefor disable it for now.
>
> The tests expose some suboptimal codegen for which I'll create PR's for 
> optimizations after this goes in.
>
> gcc/ChangeLog:
>
>       * config/aarch64/aarch64.cc (TARGET_C_BITINT_TYPE_INFO): Declare MACRO.
>       (aarch64_bitint_type_info): New function.
>       (aarch64_return_in_memory_1): Return large _BitInt's in memory.
>       (aarch64_function_arg_alignment): Adapt to correctly return the ABI
>       mandated alignment of _BitInt(N) where N > 128 as the alignment of
>       TImode.
>       (aarch64_composite_type_p): Return true for _BitInt(N), where N > 128.
>
> libgcc/ChangeLog:
>
>       * config/aarch64/t-softfp (softfp_extras): Add floatbitinthf,
>       floatbitintbf, floatbitinttf and fixtfbitint.
>       * config/aarch64/libgcc-softfp.ver (GCC_14.0.0): Add __floatbitinthf,
>       __floatbitintbf, __floatbitinttf and __fixtfbitint.
>
> gcc/testsuite/ChangeLog:
>
>       * gcc.target/aarch64/bitint-alignments.c: New test.
>       * gcc.target/aarch64/bitint-args.c: New test.
>       * gcc.target/aarch64/bitint-sizes.c: New test.
>       * gcc.target/aarch64/bitfield-bitint-abi.h: New header.
>       * gcc.target/aarch64/bitfield-bitint-abi-align16.c: New test.
>       * gcc.target/aarch64/bitfield-bitint-abi-align8.c: New test.

Since we don't support big-endian yet, I assume the tests should be
conditional on aarch64_little_endian.

> [...]
> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-bitint-abi-align16.c 
> b/gcc/testsuite/gcc.target/aarch64/bitfield-bitint-abi-align16.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..048d04e4c1bf90215892aa0173f22226246a097d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-bitint-abi-align16.c
> @@ -0,0 +1,378 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fno-stack-protector -save-temps -fno-schedule-insns 
> -fno-schedule-insns2" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +#define ALIGN 16
> +#include "bitfield-bitint-abi.h"
> +
> +// f1-f16 are all the same
> +
> +/*
> +** f1:
> +**   and     x0, x2, 1
> +**   ret
> +*/
> +/*
> +** f8:
> +**   and     x0, x2, 1
> +**   ret
> +*/
> +/*
> +** f16:
> +**   and     x0, x2, 1
> +**   ret
> +*/
> +
> +/* fp seems to be unable to optimize away stack-usage, TODO: to fix.  */
> +
> +/*
> +** fp:
> +**...
> +**   and     x0, x1, 1
> +**...
> +**   ret
> +*/
> +
> +// all other f1p-f8p generate the same code, for f16p the value comes from x2
> +/*
> +** f1p:
> +**   and     x0, x1, 1
> +**   ret
> +*/
> +/*
> +** f8p:
> +**   and     x0, x1, 1
> +**   ret
> +*/
> +/*
> +** f16p:
> +**   and     x0, x2, 1
> +**   ret
> +*/
> +
> +// g1-g16 are all the same
> +/*
> +** g1:
> +**   mov     (x[0-9]+), x0
> +**   mov     w0, w1
> +**   and     x4, \1, 9223372036854775807
> +**   and     x2, \1, 1
> +**   mov     x3, 0
> +**   b       f1
> +*/
> +
> +/*
> +** g8:
> +**   mov     (x[0-9]+), x0
> +**   mov     w0, w1
> +**   and     x4, \1, 9223372036854775807
> +**   and     x2, \1, 1
> +**   mov     x3, 0
> +**   b       f8
> +*/
> +/*
> +** g16:
> +**   mov     (x[0-9]+), x0
> +**   mov     w0, w1
> +**   and     x4, \1, 9223372036854775807
> +**   and     x2, \1, 1
> +**   mov     x3, 0
> +**   b       f16
> +*/
> +
> +// again gp different from the rest
> +
> +/*
> +** gp:
> +**   sub     sp, sp, #16
> +**   mov     (x[0-9]+), x0
> +**   mov     w0, w1
> +**   sbfx    x([0-9]+), \1, 0, 63
> +**   mov     (w[0-9]+), 0
> +**   bfi     \3, w\2, 0, 1
> +**   and     x3, x\2, 9223372036854775807
> +**   mov     x2, 0
> +**   str     xzr, \[sp\]
> +**   strb    \3, \[sp\]
> +**   ldr     x1, \[sp\]
> +**   add     sp, sp, 16
> +**   b       fp
> +*/
> +
> +// g1p-g8p are all the same, g16p uses x2 to pass parameter to f16p
> +
> +/*
> +** g1p:
> +**   mov     (w[0-9]+), w1
> +**   and     x3, x0, 9223372036854775807
> +**   and     x1, x0, 1
> +**   mov     x2, 0
> +**   mov     w0, \1
> +**   b       f1p
> +*/
> +/*
> +** g8p:
> +**   mov     (w[0-9]+), w1
> +**   and     x3, x0, 9223372036854775807
> +**   and     x1, x0, 1
> +**   mov     x2, 0
> +**   mov     w0, \1
> +**   b       f8p
> +*/
> +/*
> +** g16p:
> +**   mov     (x[0-9]+), x0
> +**   mov     w0, w1
> +**   and     x4, \1, 9223372036854775807
> +**   and     x2, \1, 1
> +**   mov     x3, 0
> +**   b       f16p
> +*/
> +
> +// f*_stack are all the same
> +/*
> +** f1_stack:
> +**   ldr     (x[0-9]+), \[sp, 16\]
> +**   and     x0, \1, 1
> +**   ret
> +*/
> +/*
> +** f8_stack:
> +**   ldr     (x[0-9]+), \[sp, 16\]
> +**   and     x0, \1, 1
> +**   ret
> +*/
> +/*
> +** f16_stack:
> +**   ldr     (x[0-9]+), \[sp, 16\]
> +**   and     x0, \1, 1
> +**   ret
> +*/
> +
> +// fp{,1,8}_stack are all the same but fp16_stack loads from sp+16
> +/*
> +** fp_stack:
> +**   ldr     (x[0-9]+), \[sp, 8\]
> +**   and     x0, \1, 1
> +**   ret
> +*/
> +/*
> +** f1p_stack:
> +**   ldr     (x[0-9]+), \[sp, 8\]
> +**   and     x0, \1, 1
> +**   ret
> +*/
> +/*
> +** f8p_stack:
> +**   ldr     (x[0-9]+), \[sp, 8\]
> +**   and     x0, \1, 1
> +**   ret
> +*/
> +
> +/*
> +** f16p_stack:
> +**   ldr     (x[0-9]+), \[sp, 16\]
> +**   and     x0, \1, 1
> +**   ret
> +*/
> +
> +/*
> +** gp_stack:
> +**...
> +**   mov     x([0-9]+), x0
> +**   sxtw    (x[0-9]+), w1
> +**   mov     x0, \2
> +**   and     (x[0-9]+), \2, 9223372036854775807

I assume this is x7, is that right?  x7 doesn't seem to be set elsewhere.
If so, I think this is one case that we need to match as x7 rather than
capture.  Similarly for the other stack tests, including in *-align8.c.

> +**   mov     (w[0-9]+), 0
> +**   bfi     \4, w\1, 0, 1
> +**   strb    wzr, \[sp, 16\]
> +**   mov     x6, \3
> +**   mov     x5, \3
> +**   mov     x4, \3
> +**   mov     x3, \3
> +**   mov     x2, \3
> +**   str     xzr, \[sp, 48\]
> +**   strb    \4, \[sp, 48\]
> +**   ldr     (x[0-9]+), \[sp, 48\]
> +**   stp     \3, \5, \[sp\]
> +**   mov     x1, \3
> +**   bl      fp_stack
> +**   sbfx    x0, x0, 0, 63
> +**...
> +**   ret
> +*/
> [...]
> diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-bitint-abi-align8.c 
> b/gcc/testsuite/gcc.target/aarch64/bitfield-bitint-abi-align8.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..11f0580fd60c3d619126c5b41d646e22374c3593
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/bitfield-bitint-abi-align8.c
> @@ -0,0 +1,380 @@
> [...]
> +/*
> +** g16:
> +**   mov     x2, x0

This set and...

> +**   mov     w0, w1
> +**   and     x4, x2, 9223372036854775807
> +**   and     x2, x2, 1

...these two reads should be captured.  (The destination of the last
instruction must be x2, of course.)

> +**   mov     x3, 0
> +**   b       f16
> +*/
> +
> +// again gp different from the rest
> +
> +/*
> +** gp:
> +**   sub     sp, sp, #16
> +**   mov     (x[0-9]+), x0
> +**   mov     w0, w1
> +**   sbfx    x([0-9]+), \1, 0, 63
> +**   mov     w1, 0
> +**   bfi     w1, w\2, 0, 1

The use of w1 in the last two instructions should be captured
similarly to the align16.c test.

> diff --git a/gcc/testsuite/gcc.target/aarch64/bitint-alignments.c 
> b/gcc/testsuite/gcc.target/aarch64/bitint-alignments.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..4de31fe7ebd933247911c48ace01ab520fe194a3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/bitint-alignments.c
> @@ -0,0 +1,58 @@
> +/* { dg-do run } */
> +/* { dg-options "-std=c23" } */
> +
> +static long unsigned int
> +calc_size (int n)

Would be more natural as calc_align(of).

> +{
> +  if (n > 64)
> +    return alignof(__int128_t);
> +  if (n > 32)
> +    return alignof(long long);
> +  if (n > 16)
> +    return alignof(int);
> +  if (n > 8)
> +    return alignof(short);
> +  else
> +    return alignof(char);
> +}
> +
> +#define CHECK_ALIGNMENT(N) \
> +  if (alignof(_BitInt(N)) != calc_size(N)) \
> +    __builtin_abort ();

I'm relying on Jakub's previous LGTM for the libgcc changes :)

OK with those changes.  Thanks a lot for doing this.

Richard

Reply via email to