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 ();                                   \

Reply via email to