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/testsuite/ChangeLog:

        * gcc.dg/bitintext.h: Generalize BEXTC to only check extension
        within {S,U}_PROMOTED_SIZE bits.
        * gcc.dg/torture/bitint-82.c: Use the new BEXTC_{U,S} macros.
---
 gcc/testsuite/gcc.dg/bitintext.h         | 48 +++++++++++++-------
 gcc/testsuite/gcc.dg/torture/bitint-82.c | 56 ++++++++++++------------
 2 files changed, 60 insertions(+), 44 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/bitintext.h b/gcc/testsuite/gcc.dg/bitintext.h
index 99fedb32a9a..48d5673440f 100644
--- a/gcc/testsuite/gcc.dg/bitintext.h
+++ b/gcc/testsuite/gcc.dg/bitintext.h
@@ -4,26 +4,42 @@ do_copy (void *p, const void *q, __SIZE_TYPE__ r)
   __builtin_memcpy (p, q, r);
 }
 
+#define S_N(x) (__builtin_clrsbg ((typeof (x)) -1) + 1)
+#define U_N(x) (__builtin_clzg ((typeof (x)) 1) + 1)
+#define CEIL(x,y) (((x) + (y) - 1) / (y))
+
+/* Promote a _BitInt type to include its padding bits.  */
+#if defined (__s390x__) || defined(__arm__)
+#define S_PROMOTED_SIZE(x) sizeof (x)
+#define U_PROMOTED_SIZE(x) sizeof (x)
+#elif defined(__loongarch__)
+#define S_PROMOTED_SIZE(x) (sizeof (x) > 8 ? CEIL (S_N (x), 64) * 8: sizeof 
(x))
+#define U_PROMOTED_SIZE(x) (sizeof (x) > 8 ? CEIL (U_N (x), 64) * 8: sizeof 
(x))
+#endif
+
+#define S_PROMOTED_TYPE(x) _BitInt (S_PROMOTED_SIZE (x) * __CHAR_BIT__)
+#define U_PROMOTED_TYPE(x) unsigned _BitInt (U_PROMOTED_SIZE (x) * 
__CHAR_BIT__)
+
 /* 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__)
-#define BEXTC(x) \
+#define BEXTC_U(x) \
   do {                                                         \
-    if ((typeof (x)) -1 < 0)                                   \
-      {                                                                \
-       _BitInt(sizeof (x) * __CHAR_BIT__) __x;                 \
-       do_copy (&__x, &(x), sizeof (__x));                     \
-       if (__x != (x))                                         \
-         __builtin_abort ();                                   \
-      }                                                                \
-    else                                                       \
-      {                                                                \
-       unsigned _BitInt(sizeof (x) * __CHAR_BIT__) __x;        \
-       do_copy (&__x, &(x), sizeof (__x));                     \
-       if (__x != (x))                                         \
-         __builtin_abort ();                                   \
-      }                                                                \
+    U_PROMOTED_TYPE (x) __x;                                   \
+    do_copy (&__x, &(x), U_PROMOTED_SIZE (x));                 \
+    if (__x != (x))                                            \
+      __builtin_abort ();                                      \
   } while (0)
+
+#define BEXTC_S(x) \
+  do {                                                         \
+    S_PROMOTED_TYPE (x) __x;                                   \
+    do_copy (&__x, &(x), S_PROMOTED_SIZE (x));                 \
+    if (__x != (x))                                            \
+      __builtin_abort ();                                      \
+  } while (0)
+
 #else
-#define BEXTC(x) do { (void) (x); } while (0)
+#define BEXTC_S(x) do { (void) (x); } while (0)
+#define BEXTC_U(x) do { (void) (x); } while (0)
 #endif
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-82.c 
b/gcc/testsuite/gcc.dg/torture/bitint-82.c
index 851d57a5598..72210956197 100644
--- a/gcc/testsuite/gcc.dg/torture/bitint-82.c
+++ b/gcc/testsuite/gcc.dg/torture/bitint-82.c
@@ -23,9 +23,9 @@ f1 (_BitInt(9) a, unsigned _BitInt(12) b, _BitInt(36) c, 
unsigned _BitInt(105) d
     _BitInt(135) e, unsigned _BitInt(168) f, _BitInt(207) g, _BitInt(207) h,
     unsigned _BitInt(531) i, _BitInt(36) j)
 {
-  BEXTC (a); BEXTC (b); BEXTC (c); BEXTC (d);
-  BEXTC (e); BEXTC (f); BEXTC (g); BEXTC (h);
-  BEXTC (i); BEXTC (j);
+  BEXTC_S (a); BEXTC_U (b); BEXTC_S (c); BEXTC_U (d);
+  BEXTC_S (e); BEXTC_U (f); BEXTC_S (g); BEXTC_S (h);
+  BEXTC_U (i); BEXTC_S (j);
   _BitInt(9) k = a + 1;
   unsigned _BitInt(12) l = b - a;
   _BitInt(36) m = c * j;
@@ -35,18 +35,18 @@ f1 (_BitInt(9) a, unsigned _BitInt(12) b, _BitInt(36) c, 
unsigned _BitInt(105) d
   _BitInt(207) q = g * j;
   _BitInt(207) r = g + h;
   unsigned _BitInt(531) s = i / j;
-  BEXTC (k); BEXTC (l); BEXTC (m); BEXTC (n);
-  BEXTC (o); BEXTC (p); BEXTC (q); BEXTC (r);
-  BEXTC (s);
+  BEXTC_S (k); BEXTC_U (l); BEXTC_S (m); BEXTC_U (n);
+  BEXTC_S (o); BEXTC_U (p); BEXTC_S (q); BEXTC_S (r);
+  BEXTC_U (s);
   unsigned _BitInt(105) t = d << (38 - j);
-  BEXTC (t);
+  BEXTC_U (t);
   _Atomic _BitInt(5) u = 15;
   u += 8U;
-  BEXTC (u);
+  BEXTC_S (u);
   _BitInt(135) v = e << 28;
-  BEXTC (v);
+  BEXTC_S (v);
   unsigned _BitInt(475) w = z << (29 + j);
-  BEXTC (w);
+  BEXTC_U (w);
   return a + 4;
 }
 #endif
@@ -55,15 +55,15 @@ int
 main ()
 {
 #if __BITINT_MAXWIDTH__ >= 532
-  BEXTC (a); BEXTC (b);
-  BEXTC (c); BEXTC (d);
-  BEXTC (e); BEXTC (f);
-  BEXTC (g); BEXTC (h);
-  BEXTC (i);
-  BEXTC (j);
-  BEXTC (k);
-  BEXTC (l);
-  BEXTC (z);
+  BEXTC_S (a); BEXTC_S (b);
+  BEXTC_S (c); BEXTC_S (d);
+  BEXTC_S (e); BEXTC_S (f);
+  BEXTC_S (g); BEXTC_S (h);
+  BEXTC_U (i);
+  BEXTC_U (j);
+  BEXTC_U (k);
+  BEXTC_U (l);
+  BEXTC_U (z);
   {
     _BitInt(5) a = 2, b = -2;
     _BitInt(38) c = 12345, d = -12345;
@@ -73,14 +73,14 @@ main ()
     unsigned _BitInt(17) j = 49127uwb;
     unsigned _BitInt(60) k = 588141367522129848uwb;
     unsigned _BitInt(205) l = 
33991671979236490040668305838261113909013362173682935296620088uwb;
-    BEXTC (a); BEXTC (b);
-    BEXTC (c); BEXTC (d);
-    BEXTC (e); BEXTC (f);
-    BEXTC (g); BEXTC (h);
-    BEXTC (i);
-    BEXTC (j);
-    BEXTC (k);
-    BEXTC (l);
+    BEXTC_S (a); BEXTC_S (b);
+    BEXTC_S (c); BEXTC_S (d);
+    BEXTC_S (e); BEXTC_S (f);
+    BEXTC_S (g); BEXTC_S (h);
+    BEXTC_U (i);
+    BEXTC_U (j);
+    BEXTC_U (k);
+    BEXTC_U (l);
   }
   _BitInt(217) m = f1 (57wb, 3927uwb, 10625699364wb, 
23030359755638571619326514462579uwb,
                       20797625176303404170317957140841712396356wb,
@@ -89,6 +89,6 @@ main ()
                       
25108562626494976011700565632680191924545340440636663075662700wb,
                       
6366583146545926097709747296452085257498446783797668089081516596003270602920229800152065594152964557479773813310423759077951305431130758723519892452009351743676uwb,
                       -1);
-  BEXTC (m);
+  BEXTC_S (m);
 #endif
 }
-- 
2.46.0

Reply via email to