mpz reuse test takes too much time

Torbjörn Granlund tg at gmplib.org
Fri Dec 2 22:50:30 UTC 2016


nisse at lysator.liu.se (Niels Möller) writes:

  > Shouldn't res1, res2, res3 be overwritten with some fixed garbage when
  > they are not also input operands?
  
  This remains to do, as well as updating the corresponding mini-gmp test.
  
I made additional changes.

Target operands which are not also input operands are now overwritten
with garbage via the CLOBBER macro.  (It would make sense to do this in
almost every other GMP test file.)

I split your gcdext check macros into 2-operand and 3-operand variants.
The old macros checked res3 even when it was not part of the
computation, exhibiting possibly undefined behaviour.

OK with you to commit?

*** /tmp/extdiff.v4HTq2/gmp-main.8f287aee0205/tests/mpz/reuse.c	Fri Dec  2 23:40:12 2016
--- /home/tege/prec/gmp-main/tests/mpz/reuse.c	Fri Dec  2 23:38:44 2016
***************
*** 198,201 ****
--- 198,208 ----
    } while (0)
  
+ #define CLOBBER(res)							\
+   do {									\
+     MPN_ZERO(PTR(res), ALLOC(res));					\
+     PTR(res)[0] = 0xDEADBEEF;						\
+     SIZ(res) = 0xDEFACE;						\
+   } while (0)
+ 
  int
  main (int argc, char **argv)
***************
*** 232,235 ****
--- 239,246 ----
    mpz_init (t);
  
+   mpz_set_ui (res1, 1);		/* force allocation */
+   mpz_set_ui (res2, 1);		/* force allocation */
+   mpz_set_ui (res3, 1);		/* force allocation */
+ 
    for (pass = 1; pass <= reps; pass++)
      {
***************
*** 308,311 ****
--- 319,323 ----
  
  	  mpz_set (res1, in1);
+ 	  CLOBBER(res2);
  	  INVOKE_RRSS (ddss_div[i], res1, res2, res1, in2);
  	  MPZ_CHECK_FORMAT (res1);
***************
*** 314,317 ****
--- 326,330 ----
  	    FAIL (ddss_div, i, in1, in2, NULL);
  
+ 	  CLOBBER(res1);
  	  mpz_set (res2, in1);
  	  INVOKE_RRSS (ddss_div[i], res1, res2, res2, in2);
***************
*** 322,325 ****
--- 335,339 ----
  
  	  mpz_set (res1, in2);
+ 	  CLOBBER(res2);
  	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res1);
  	  MPZ_CHECK_FORMAT (res1);
***************
*** 328,331 ****
--- 342,346 ----
  	    FAIL (ddss_div, i, in1, in2, NULL);
  
+ 	  CLOBBER(res1);
  	  mpz_set (res2, in2);
  	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res2);
***************
*** 388,391 ****
--- 403,407 ----
  
  	      mpz_set (res1, in1);
+ 	      CLOBBER(res2);
  	      r2 = (ddsi_div[i].fptr) (res1, res2, res1, in2i);
  	      MPZ_CHECK_FORMAT (res1);
***************
*** 393,396 ****
--- 409,413 ----
  		FAIL (ddsi_div, i, in1, in2, NULL);
  
+ 	      CLOBBER(res1);
  	      mpz_set (res2, in1);
  	      (ddsi_div[i].fptr) (res1, res2, res2, in2i);
***************
*** 468,473 ****
  	  MPZ_CHECK_FORMAT (ref3);
  
! #define GCDEXT_CHECK(t, i1,i2) do {					\
! 	    mpz_gcdext (res1, res2, t ? res3 : NULL, i1, i2);		\
  	    MPZ_CHECK_FORMAT (res1);					\
  	    MPZ_CHECK_FORMAT (res2);					\
--- 485,490 ----
  	  MPZ_CHECK_FORMAT (ref3);
  
! #define GCDEXT_CHECK3(i1, i2) do {					\
! 	    mpz_gcdext (res1, res2, res3, i1, i2);			\
  	    MPZ_CHECK_FORMAT (res1);					\
  	    MPZ_CHECK_FORMAT (res2);					\
***************
*** 476,534 ****
  		|| mpz_cmp (ref3, res3) != 0)				\
  	      FAIL2 (mpz_gcdext, i1, i2, NULL);				\
! 	  } while(0)
  
  	  mpz_set (res1, in1);
! 	  GCDEXT_CHECK (1, res1, in2);
  
  	  mpz_set (res2, in1);
! 	  GCDEXT_CHECK (1, res2, in2);
  
  	  mpz_set (res3, in1);
! 	  GCDEXT_CHECK (1, res3, in2);
  
  	  mpz_set (res1, in2);
! 	  GCDEXT_CHECK (1, in1, res1);
  
  	  mpz_set (res2, in2);
! 	  GCDEXT_CHECK (1, in1, res2);
  
  	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK (1, in1, res3);
  
  	  mpz_set (res1, in1);
  	  mpz_set (res2, in2);
! 	  GCDEXT_CHECK (1, res1, res2);
  
  	  mpz_set (res1, in1);
  	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK (1, res1, res3);
  
  	  mpz_set (res2, in1);
  	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK (1, res2, res3);
  
- 	  mpz_set (res2, in1);
  	  mpz_set (res1, in2);
! 	  GCDEXT_CHECK (1, res2, res1);
  
- 	  mpz_set (res3, in1);
  	  mpz_set (res1, in2);
! 	  GCDEXT_CHECK (1, res3, res1);
! 
  	  mpz_set (res3, in1);
  	  mpz_set (res2, in2);
! 	  GCDEXT_CHECK(1, res3, res2);
  
  	  mpz_set (res1, in1);
! 	  GCDEXT_CHECK (0, res1, in2);
  
  	  mpz_set (res2, in1);
! 	  GCDEXT_CHECK (0, res2, in2);
  
  	  mpz_set (res1, in2);
! 	  GCDEXT_CHECK (0, in1, res1);
  
  	  mpz_set (res2, in2);
! 	  GCDEXT_CHECK (0, in1, res2);
  #undef GCDEXT_CHECK
  	  /* Identical inputs, gcd(in1, in1). Then the result should be
--- 493,580 ----
  		|| mpz_cmp (ref3, res3) != 0)				\
  	      FAIL2 (mpz_gcdext, i1, i2, NULL);				\
! 	  } while (0)
! #define GCDEXT_CHECK2(i1, i2) do {					\
! 	    mpz_gcdext (res1, res2, NULL, i1, i2);			\
! 	    MPZ_CHECK_FORMAT (res1);					\
! 	    MPZ_CHECK_FORMAT (res2);					\
! 	    if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)	\
! 	      FAIL2 (mpz_gcdext, i1, i2, NULL);				\
! 	  } while (0)
  
  	  mpz_set (res1, in1);
! 	  CLOBBER(res2);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK3 (res1, in2);
  
+ 	  CLOBBER(res1);
  	  mpz_set (res2, in1);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK3 (res2, in2);
  
+ 	  CLOBBER(res1);
+ 	  CLOBBER(res2);
  	  mpz_set (res3, in1);
! 	  GCDEXT_CHECK3 (res3, in2);
  
  	  mpz_set (res1, in2);
! 	  CLOBBER(res2);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK3 (in1, res1);
  
+ 	  CLOBBER(res1);
  	  mpz_set (res2, in2);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK3 (in1, res2);
  
+ 	  CLOBBER(res1);
+ 	  CLOBBER(res2);
  	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK3 (in1, res3);
  
  	  mpz_set (res1, in1);
  	  mpz_set (res2, in2);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK3 (res1, res2);
  
  	  mpz_set (res1, in1);
+ 	  CLOBBER(res2);
  	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK3 (res1, res3);
  
+ 	  CLOBBER(res1);
  	  mpz_set (res2, in1);
  	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK3 (res2, res3);
  
  	  mpz_set (res1, in2);
! 	  mpz_set (res2, in1);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK3 (res2, res1);
  
  	  mpz_set (res1, in2);
! 	  CLOBBER(res2);
  	  mpz_set (res3, in1);
+ 	  GCDEXT_CHECK3 (res3, res1);
+ 
+ 	  CLOBBER(res1);
  	  mpz_set (res2, in2);
! 	  mpz_set (res3, in1);
! 	  GCDEXT_CHECK3(res3, res2);
  
  	  mpz_set (res1, in1);
! 	  CLOBBER(res2);
! 	  GCDEXT_CHECK2 (res1, in2);
  
+ 	  CLOBBER(res1);
  	  mpz_set (res2, in1);
! 	  GCDEXT_CHECK2 (res2, in2);
  
  	  mpz_set (res1, in2);
! 	  CLOBBER(res2);
! 	  GCDEXT_CHECK2 (in1, res1);
  
+ 	  CLOBBER(res1);
  	  mpz_set (res2, in2);
! 	  GCDEXT_CHECK2 (in1, res2);
  #undef GCDEXT_CHECK
  	  /* Identical inputs, gcd(in1, in1). Then the result should be
***************
*** 536,543 ****
  	  mpz_abs (ref1, in1);
  	  mpz_set_ui (ref2, 0);
! 	  mpz_set_si (ref3, mpz_sgn(in1));
  
! #define GCDEXT_CHECK_SAME(t, i) do {					\
! 	    mpz_gcdext(res1, res2, t ? res3 : NULL, i, i);		\
  	    MPZ_CHECK_FORMAT (res1);					\
  	    MPZ_CHECK_FORMAT (res2);					\
--- 582,589 ----
  	  mpz_abs (ref1, in1);
  	  mpz_set_ui (ref2, 0);
! 	  mpz_set_si (ref3, mpz_sgn (in1));
  
! #define GCDEXT_CHECK_SAME3(in) do {					\
! 	    mpz_gcdext (res1, res2, res3, in, in);			\
  	    MPZ_CHECK_FORMAT (res1);					\
  	    MPZ_CHECK_FORMAT (res2);					\
***************
*** 545,565 ****
  	    if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0	\
  		|| mpz_cmp (ref3, res3) != 0)				\
! 	      FAIL2 (mpz_gcdext, i, i, NULL);				\
! 	  } while(0)
  
  	  mpz_set (res1, in1);
! 	  GCDEXT_CHECK_SAME (1, res1);
  
! 	  mpz_set(res2, in1);
! 	  GCDEXT_CHECK_SAME (1, res2);
  
! 	  mpz_set(res3, in1);
! 	  GCDEXT_CHECK_SAME (1, res3);
  
  	  mpz_set (res1, in1);
! 	  GCDEXT_CHECK_SAME (0, res1);
  
! 	  mpz_set(res2, in1);
! 	  GCDEXT_CHECK_SAME (0, res2);
  #undef GCDEXT_CHECK_SAME
  	}
--- 591,628 ----
  	    if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0	\
  		|| mpz_cmp (ref3, res3) != 0)				\
! 	      FAIL2 (mpz_gcdext, in, in, NULL);				\
! 	  } while (0)
! #define GCDEXT_CHECK_SAME2(in) do {					\
! 	    mpz_gcdext (res1, res2, NULL, in, in);			\
! 	    MPZ_CHECK_FORMAT (res1);					\
! 	    MPZ_CHECK_FORMAT (res2);					\
! 	    if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)	\
! 	      FAIL2 (mpz_gcdext, in, in, NULL);				\
! 	  } while (0)
  
  	  mpz_set (res1, in1);
! 	  CLOBBER(res2);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK_SAME3 (res1);
  
! 	  CLOBBER(res1);
! 	  mpz_set (res2, in1);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK_SAME3 (res2);
  
! 	  CLOBBER(res1);
! 	  CLOBBER(res2);
! 	  mpz_set (res3, in1);
! 	  GCDEXT_CHECK_SAME3 (res3);
  
  	  mpz_set (res1, in1);
! 	  CLOBBER(res2);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK_SAME2 (res1);
  
! 	  CLOBBER(res1);
! 	  mpz_set (res2, in1);
! 	  CLOBBER(res3);
! 	  GCDEXT_CHECK_SAME2 (res2);
  #undef GCDEXT_CHECK_SAME
  	}


-- 
Torbjörn
Please encrypt, key id 0xC8601622


More information about the gmp-devel mailing list