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; }