https://gcc.gnu.org/g:bc97874bec823e08def7c6acd04c26e2174ca0b3
commit r16-2780-gbc97874bec823e08def7c6acd04c26e2174ca0b3 Author: Yang Yujie <yangyu...@loongson.cn> Date: Tue Aug 5 12:59:30 2025 +0200 bitint: Allow unused bits when testing extended _BitInt ABIs In LoongArch psABI, large _BitInt(N) (N > 64) objects are only extended to fill the highest 8-byte chunk that contains any used bit, but the size of such a large _BitInt type is a multiple of their 16-byte alignment. So there may be an entire unused 8-byte chunk that is not filled by extension, and this chunk shouldn't be checked when testing if the object is properly extended. The original bitintext.h assumed that all bits within sizeof(_BitInt(N)) beyond used bits are filled by extension. This patch changes that for LoongArch and possibly any future ports with a similar behavior. P.S. For encoding this test as well as type-generic programming, it would be nice to have a builtin function to obtain "N" at compile time from _BitInt(N)-typed expressions. But here we stick to existing ones (__builtin_clrsbg / __builtin_clzg). * gcc.dg/bitintext.h (S, CEIL, PROMOTED_SIZE): Define. (BEXTC): Generalize to only check extension within PROMOTED_SIZE bits. Diff: --- gcc/testsuite/gcc.dg/bitintext.h | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.dg/bitintext.h b/gcc/testsuite/gcc.dg/bitintext.h index 99fedb32a9a5..d5f2689daec4 100644 --- a/gcc/testsuite/gcc.dg/bitintext.h +++ b/gcc/testsuite/gcc.dg/bitintext.h @@ -4,6 +4,24 @@ do_copy (void *p, const void *q, __SIZE_TYPE__ r) __builtin_memcpy (p, q, r); } +/* Obtain the value of N from a _BitInt(N)-typed expression X + at compile time. */ +#define S(x) \ + ((typeof (x)) -1 < 0 \ + ? __builtin_clrsbg (__builtin_choose_expr ((typeof (x)) -1 < 0, \ + (typeof (x)) -1, -1)) + 1 \ + : __builtin_popcountg (__builtin_choose_expr ((typeof (x)) -1 < 0, \ + 0U, (typeof (x)) -1))) + +#define CEIL(x,y) (((x) + (y) - 1) / (y)) + +/* Promote a _BitInt type to include its padding bits. */ +#if defined (__s390x__) || defined(__arm__) +#define PROMOTED_SIZE(x) sizeof (x) +#elif defined(__loongarch__) +#define PROMOTED_SIZE(x) (sizeof (x) > 8 ? CEIL (S (x), 64) * 8 : sizeof (x)) +#endif + /* Macro to test whether (on targets where psABI requires it) _BitInt with padding bits have those filled with sign or zero extension. */ #if defined(__s390x__) || defined(__arm__) || defined(__loongarch__) @@ -11,14 +29,14 @@ do_copy (void *p, const void *q, __SIZE_TYPE__ r) do { \ if ((typeof (x)) -1 < 0) \ { \ - _BitInt(sizeof (x) * __CHAR_BIT__) __x; \ + _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \ do_copy (&__x, &(x), sizeof (__x)); \ if (__x != (x)) \ __builtin_abort (); \ } \ else \ { \ - unsigned _BitInt(sizeof (x) * __CHAR_BIT__) __x; \ + unsigned _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \ do_copy (&__x, &(x), sizeof (__x)); \ if (__x != (x)) \ __builtin_abort (); \