Dear GMP developers,

I am forwarding a bug I already report to the Debian BTS 
(http://bugs.debian.org/708264) with libgmp 5.1.1 on IA64.

It seems the file mpn/ia64/divrem_2.asm do not restore f17 register
which sort of contradict mpn/ia64/README which says that only
f6-f15 f32-f127 are caller-save.

Thus programs calling e.g. mpn_sqrtrem might end up have having
corrupted registers (f16 to f18)

libgmp works fine when rebuild with the file removed. I did not test
libgmp 5.1.2 yet but the file mpn/ia64/divrem_2.asm is identical so it
is likely the bug is still there.

I attach a test case (which uses a lot of double in the hope the compiler
use f17). I tested gcc 4.6, gcc 4.7 and 4.8 (debian build).

The correct output (without call to mpn_sqrtrem)
%gcc gmptest.c -g -O1 -lgmp -o test && ./test
8.53996 1.56883 8.15584 44.3965
10.1088 6.97113 52.5523 -36.2406
3.142 2.718 0.5772 14.13
8.53996 1.56883 8.15584 44.3965
33.3916

The corrupted output (with a call to mpn_sqrtrem)
%gcc gmptest.c -g -O1 -lgmp -o test -DSQRTN && ./test
8.53996 1.56883 8.15584 44.3965
9.84742e-309 5.14474e-309 1.51044e+19 -36.2406
3.142 2.718 0.5772 14.13
8.53996 1.56883 8.15584 44.3965
33.3916

Cheers,
Bill.
#include <stdio.h>
#include <gmp.h>

double fun1(mpz_t n, double a, double b, double c, double d)
{
  mpz_init(n);
  mpz_fac_ui(n, 101);
#ifdef SQRTN
  mpz_sqrt(n,n);
#endif
  return a+b+c+d;
}

double fun2(mpz_t n, double a, double b, double c, double d)
{
  double a1=a+b, b1=a-b, c1=c+d, d1= c-d;
  double z = fun1(n,a1,b1,c1,d1);
  printf("%g %g %g %g\n",a,b,c,d);
  printf("%g %g %g %g\n",a1,b1,c1,d1);
  return z;
}

double fun3(mpz_t n, double a, double b, double c, double d)
{
  double a1=a*b, b1=b*c, c1=c*d, d1= d*a;
  double z = fun2(n,a1,b1,c1,d1);
  printf("%g %g %g %g\n",a,b,c,d);
  printf("%g %g %g %g\n",a1,b1,c1,d1);
  return z;
}

int
main(void)
{
  mpz_t n;
  double z = fun3(n, 3.142, 2.718, 0.5772, 14.13);
  printf("%g\n", z);
  mpz_out_str(stdout, 10, n);
  return 0;
}

Reply via email to