On Thu, Jul 27, 2023 at 07:15:28PM +0200, Jakub Jelinek via Gcc-patches wrote:
> testcases, I've been using
> https://defuse.ca/big-number-calculator.htm
> tool, a randombitint tool I wrote (will post as a reply to this) plus
> LLVM trunk on godbolt and the WIP GCC support checking if both compilers
> agree on stuff (and in case of differences tried constant evaluation etc.).

So, the randombitint.c tool is attached, when invoked like
./randombitint 174
it prints pseudo random 174 bit integer in decimal, when invoked as
./randombitint 575 mask
it prints all ones number as decimal for the 575 bit precision, and
./randombitint 275 0x432445aebe435646567547567647
prints the given hexadecimal number as decimal (all using gmp).

In the tests I've often used
__attribute__((noipa)) void
printme (const void *p, int n)
{
  __builtin_printf ("0x");
  if ((n & 7) != 0)
    __builtin_printf ("%02x", ((const unsigned char *) p)[n / 8] & ((1 << (n & 
7)) - 1));
  for (int i = (n / 8) - 1; i >= 0; --i)
    __builtin_printf ("%02x", ((const unsigned char *) p)[i]);
  __builtin_printf ("\n");
}
function to print hexadecimal values (temporaries or finals) and then used
the third invocation of the tool to convert those to decimal.
For unsigned _BitInt just called the above like
  printme (&whatever, 575);
where 575 was the N from unsigned _BitInt(N) whatever, or
      _BitInt(575) x = ...
      if (x < 0)
        {
          __builtin_printf ("-");
          x = -x;
        }
      printme (&x, 575);
to print it signed.

        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