On Tue, May 20, 2025 at 03:44:09PM +0200, Jakub Jelinek wrote:
> The tests weren't included :(.

I'd like to see something along the lines of following as the test(s)
for the padding bits (if LoongArch will really have the weirdo psABI
then with some special version of that for it).
Though, this doesn't fail right now even on x86_64 if temporarily
enabled in the header, so really should be extended with all the cases
which are known to fail and with any extension fix that should be extended
(ideally for things changed at once in the same test file, for separate
fixes in different files, that is why the macro is in a header file
that can be included by multiple tests).

BTW, for _BitInt test creation, I'm using attached proglet to give me
pseudorandom unsigned _BitInt values of the desired precision.

2025-05-20  Jakub Jelinek  <ja...@redhat.com>

        * gcc.dg/bitintext.h: New file.
        * gcc.dg/torture/bitint-82.c: New test.

--- gcc/testsuite/gcc.dg/bitintext.h.jj 2025-05-20 16:45:26.017419463 +0200
+++ gcc/testsuite/gcc.dg/bitintext.h    2025-05-20 17:19:32.610605951 +0200
@@ -0,0 +1,23 @@
+/* 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) \
+  do {                                                         \
+    if ((typeof (x)) -1 < 0)                                   \
+      {                                                                \
+       _BitInt(sizeof (x) * __CHAR_BIT__) __x;                 \
+       __builtin_memcpy (&__x, &(x), sizeof (__x));            \
+       if (__x != (x))                                         \
+         __builtin_abort ();                                   \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       unsigned _BitInt(sizeof (x) * __CHAR_BIT__) __x;        \
+       __builtin_memcpy (&__x, &(x), sizeof (__x));            \
+       if (__x != (x))                                         \
+         __builtin_abort ();                                   \
+      }                                                                \
+  } while (0)
+#else
+#define BEXTC(x) do { (void) (x); } while (0)
+#endif
--- gcc/testsuite/gcc.dg/torture/bitint-82.c.jj 2025-05-20 16:53:31.380827655 
+0200
+++ gcc/testsuite/gcc.dg/torture/bitint-82.c    2025-05-20 17:16:38.715970734 
+0200
@@ -0,0 +1,85 @@
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 532
+_BitInt(5) a = 2, b = -2;
+_BitInt(38) c = 12345, d = -12345;
+_BitInt(129) e = 147090211948845388976606115811401318743wb, f = 
-147090211948845388976606115811401318743wb;
+_BitInt(532) g = 34476769918317100226195145251004381172591594205376273814wb, h 
= -102116935649428556311918486808926113041433456371844211259677321wb;
+unsigned _BitInt(1) i = 1;
+unsigned _BitInt(17) j = 49127uwb;
+unsigned _BitInt(60) k = 588141367522129848uwb;
+unsigned _BitInt(205) l = 
33991671979236490040668305838261113909013362173682935296620088uwb;
+#endif
+
+#include "../bitintext.h"
+
+#if __BITINT_MAXWIDTH__ >= 532
+[[gnu::noipa]] _BitInt(217)
+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);
+  _BitInt(9) k = a + 1;
+  unsigned _BitInt(12) l = b - a;
+  _BitInt(36) m = c * j;
+  unsigned _BitInt(105) n = d >> (-2 * j);
+  _BitInt(135) o = e | -j;
+  unsigned _BitInt(168) p = f & 101010101010101010101010uwb;
+  _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);
+  unsigned _BitInt(105) t = d << (38 - j);
+  BEXTC (t);
+  return a + 4;
+}
+#endif
+
+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);
+  {
+    _BitInt(5) a = 2, b = -2;
+    _BitInt(38) c = 12345, d = -12345;
+    _BitInt(129) e = 147090211948845388976606115811401318743wb, f = 
-147090211948845388976606115811401318743wb;
+    _BitInt(532) g = 
34476769918317100226195145251004381172591594205376273814wb, h = 
-102116935649428556311918486808926113041433456371844211259677321wb;
+    unsigned _BitInt(1) i = 1;
+    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);
+  }
+  _BitInt(217) m = f1 (57wb, 3927uwb, 10625699364wb, 
23030359755638571619326514462579uwb,
+                      20797625176303404170317957140841712396356wb,
+                      111831871006433449872067089878311637796827405335256uwb,
+                      
64853652491049541618437564623858346454131583900201311683495230wb,
+                      
25108562626494976011700565632680191924545340440636663075662700wb,
+                      
6366583146545926097709747296452085257498446783797668089081516596003270602920229800152065594152964557479773813310423759077951305431130758723519892452009351743676uwb,
+                      -1);
+  BEXTC (m);
+#endif
+}

        Jakub
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <gmp.h>

int
main (int argc, const char *argv[])
{
  int n = atoi (argv[1]);
  int m = (n + 7) / 8;
  char *p = __builtin_alloca (m * 2 + 1);
  const char *q;
  srandom (getpid ());
  for (int i = 0; i < m; ++i)
    {
      unsigned char v = random ();
      if (argc >= 3 && strcmp (argv[2], "mask") == 0)
        v = 0xff;
      if (i == 0 && (n & 7) != 0)
        v &= (1 << (n & 7)) - 1;
      sprintf (&p[2 * i], "%02x", v);
    }
  p[m * 2] = '\0';
  mpz_t a;
  if (argc >= 3 && strcmp (argv[2], "mask") != 0)
    {
      q = argv[2];
      if (q[0] == '0' && q[1] == 'x')
        q += 2;
    }
  else
    q = p;
  gmp_sscanf (q, "%Zx", a);
  gmp_printf ("0x%s\n%Zd\n", q, a);
  return 0;
}

Reply via email to