xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/reuse.c (revision 154bfe8e089c1a0a4e9ed8414f08d3da90949162)
1 /* Test that routines allow reusing a source variable as destination.
2 
3    Test all relevant functions except:
4 	mpz_bin_ui
5 	mpz_nextprime
6 	mpz_mul_si
7 	mpz_addmul_ui (should this really allow a+=a*c?)
8 
9 Copyright 1996, 1999-2002, 2009, 2012, 2013 Free Software Foundation, Inc.
10 
11 This file is part of the GNU MP Library test suite.
12 
13 The GNU MP Library test suite is free software; you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 3 of the License,
16 or (at your option) any later version.
17 
18 The GNU MP Library test suite is distributed in the hope that it will be
19 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
21 Public License for more details.
22 
23 You should have received a copy of the GNU General Public License along with
24 the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 
31 #include "gmp.h"
32 #include "gmp-impl.h"
33 #include "tests.h"
34 
35 #if __GMP_LIBGMP_DLL
36 
37 /* FIXME: When linking to a DLL libgmp, mpz_add etc can't be used as
38    initializers for global variables because they're effectively global
39    variables (function pointers) themselves.  Perhaps calling a test
40    function successively with mpz_add etc would be better.  */
41 
42 int
43 main (void)
44 {
45   printf ("Test suppressed for windows DLL\n");
46   exit (0);
47 }
48 
49 
50 #else /* ! DLL_EXPORT */
51 
52 void dump (const char *, mpz_t, mpz_t, mpz_t);
53 
54 typedef void (*dss_func) (mpz_ptr, mpz_srcptr, mpz_srcptr);
55 typedef void (*dsi_func) (mpz_ptr, mpz_srcptr, unsigned long int);
56 typedef unsigned long int (*dsi_div_func) (mpz_ptr, mpz_srcptr, unsigned long int);
57 typedef unsigned long int (*ddsi_div_func) (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int);
58 typedef void (*ddss_div_func) (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
59 typedef void (*ds_func) (mpz_ptr, mpz_srcptr);
60 
61 
62 void
63 mpz_xinvert (mpz_ptr r, mpz_srcptr a, mpz_srcptr b)
64 {
65   int res;
66   res = mpz_invert (r, a, b);
67   if (res == 0)
68     mpz_set_ui (r, 0);
69 }
70 
71 struct {
72   dss_func fptr;
73   const char *fname;
74   int isdivision;
75   int isslow;
76 } static dss[] =
77   { { mpz_add,     "mpz_add",	  0, 0 },
78     { mpz_sub,     "mpz_sub",	  0, 0 },
79     { mpz_mul,     "mpz_mul",	  0, 0 },
80     { mpz_cdiv_q,  "mpz_cdiv_q",  1, 0 },
81     { mpz_cdiv_r,  "mpz_cdiv_r",  1, 0 },
82     { mpz_fdiv_q,  "mpz_fdiv_q",  1, 0 },
83     { mpz_fdiv_r,  "mpz_fdiv_r",  1, 0 },
84     { mpz_tdiv_q,  "mpz_tdiv_q",  1, 0 },
85     { mpz_tdiv_r,  "mpz_tdiv_r",  1, 0 },
86     { mpz_mod,     "mpz_mod",	  1, 0 },
87     { mpz_xinvert, "mpz_xinvert", 1, 1 },
88     { mpz_gcd,     "mpz_gcd",	  0, 1 },
89     { mpz_lcm,     "mpz_lcm",	  0, 1 },
90     { mpz_and,     "mpz_and",	  0, 0 },
91     { mpz_ior,     "mpz_ior",	  0, 0 },
92     { mpz_xor,     "mpz_xor",     0, 0 }
93   };
94 
95 
96 struct {
97   dsi_func fptr;
98   const char *fname;
99   int mod;
100 } static dsi[] =
101 {
102   /* Don't change order here without changing the code in main(). */
103   { mpz_add_ui,         "mpz_add_ui",	     0 },
104   { mpz_mul_ui,		"mpz_mul_ui",	     0 },
105   { mpz_sub_ui,		"mpz_sub_ui",	     0 },
106   { mpz_fdiv_q_2exp,    "mpz_fdiv_q_2exp",   0x1000 },
107   { mpz_fdiv_r_2exp,    "mpz_fdiv_r_2exp",   0x1000 },
108   { mpz_cdiv_q_2exp,    "mpz_cdiv_q_2exp",   0x1000 },
109   { mpz_cdiv_r_2exp,    "mpz_cdiv_r_2exp",   0x1000 },
110   { mpz_tdiv_q_2exp,    "mpz_tdiv_q_2exp",   0x1000 },
111   { mpz_tdiv_r_2exp,    "mpz_tdiv_r_2exp",   0x1000 },
112   { mpz_mul_2exp,	"mpz_mul_2exp",      0x100 },
113   { mpz_pow_ui,		"mpz_pow_ui",        0x10 }
114 };
115 
116 struct {
117   dsi_div_func fptr;
118   const char *fname;
119 } static dsi_div[] =
120 {
121   { mpz_cdiv_q_ui,       "mpz_cdiv_q_ui" },
122   { mpz_cdiv_r_ui,       "mpz_cdiv_r_ui" },
123   { mpz_fdiv_q_ui,       "mpz_fdiv_q_ui" },
124   { mpz_fdiv_r_ui,       "mpz_fdiv_r_ui" },
125   { mpz_tdiv_q_ui,       "mpz_tdiv_q_ui" },
126   { mpz_tdiv_r_ui,       "mpz_tdiv_r_ui" }
127 };
128 
129 struct {
130   ddsi_div_func fptr;
131   const char *fname;
132   int isslow;
133 } static ddsi_div[] =
134 {
135   { mpz_cdiv_qr_ui,     "mpz_cdiv_qr_ui",    0 },
136   { mpz_fdiv_qr_ui,     "mpz_fdiv_qr_ui",    0 },
137   { mpz_tdiv_qr_ui,     "mpz_tdiv_qr_ui",    0 },
138 };
139 
140 
141 struct {
142   ddss_div_func fptr;
143   const char *fname;
144   int isslow;
145 } static ddss_div[] =
146 {
147   { mpz_cdiv_qr,  "mpz_cdiv_qr",    0 },
148   { mpz_fdiv_qr,  "mpz_fdiv_qr",    0 },
149   { mpz_tdiv_qr,  "mpz_tdiv_qr",    0 },
150 };
151 
152 struct {
153   ds_func fptr;
154   const char *fname;
155   int nonneg;
156 } static ds[] =
157 {
158   { mpz_abs,    "mpz_abs",    0 },
159   { mpz_com,    "mpz_com",    0 },
160   { mpz_neg,    "mpz_neg",    0 },
161   { mpz_sqrt,   "mpz_sqrt",   1 },
162 };
163 
164 #define FAIL(class,indx,op1,op2,op3)					\
165   do {									\
166     dump (class[indx].fname, op1, op2, op3);				\
167     exit (1);								\
168   } while (0)
169 
170 #define FAIL2(fname,op1,op2,op3)					\
171   do {									\
172     dump (#fname, op1, op2, op3);					\
173     exit (1);								\
174   } while (0)
175 
176 
177 #define INVOKE_RRS(desc,r1,r2,i1)					\
178   do {									\
179     if (pass & 1) _mpz_realloc (r1, ABSIZ(r1));				\
180     if (pass & 2) _mpz_realloc (r2, ABSIZ(r2));				\
181     (desc).fptr (r1, r2, i1);						\
182   } while (0)
183 #define INVOKE_RS(desc,r1,i1)						\
184   do {									\
185     if (pass & 1) _mpz_realloc (r1, ABSIZ(r1));				\
186     (desc).fptr (r1, i1);						\
187   } while (0)
188 #define INVOKE_RRSS(desc,r1,r2,i1,i2)					\
189   do {									\
190     if (pass & 1) _mpz_realloc (r1, ABSIZ(r1));				\
191     if (pass & 2) _mpz_realloc (r2, ABSIZ(r2));				\
192     (desc).fptr (r1, r2, i1, i2);					\
193   } while (0)
194 #define INVOKE_RSS(desc,r1,i1,i2)					\
195   do {									\
196     if (pass & 1) _mpz_realloc (r1, ABSIZ(r1));				\
197     (desc).fptr (r1, i1, i2);						\
198   } while (0)
199 
200 int
201 main (int argc, char **argv)
202 {
203   int i;
204   int pass, reps = 400;
205   mpz_t in1, in2, in3;
206   unsigned long int in2i;
207   mp_size_t size;
208   mpz_t res1, res2, res3;
209   mpz_t ref1, ref2, ref3;
210   mpz_t t;
211   unsigned long int r1, r2;
212   gmp_randstate_ptr rands;
213   mpz_t bs;
214   unsigned long bsi, size_range;
215 
216   tests_start ();
217   TESTS_REPS (reps, argv, argc);
218 
219   rands = RANDS;
220 
221   mpz_init (bs);
222 
223   mpz_init (in1);
224   mpz_init (in2);
225   mpz_init (in3);
226   mpz_init (ref1);
227   mpz_init (ref2);
228   mpz_init (ref3);
229   mpz_init (res1);
230   mpz_init (res2);
231   mpz_init (res3);
232   mpz_init (t);
233 
234   for (pass = 1; pass <= reps; pass++)
235     {
236       if (isatty (fileno (stdout)))
237 	{
238 	  printf ("\r%d/%d passes", pass, reps);
239 	  fflush (stdout);
240 	}
241 
242       mpz_urandomb (bs, rands, 32);
243       size_range = mpz_get_ui (bs) % 21 + 2;
244 
245       if ((pass & 1) == 0)
246 	{
247 	  /* Make all input operands have quite different sizes */
248 	  mpz_urandomb (bs, rands, 32);
249 	  size = mpz_get_ui (bs) % size_range;
250 	  mpz_rrandomb (in1, rands, size);
251 
252 	  mpz_urandomb (bs, rands, 32);
253 	  size = mpz_get_ui (bs) % size_range;
254 	  mpz_rrandomb (in2, rands, size);
255 
256 	  mpz_urandomb (bs, rands, 32);
257 	  size = mpz_get_ui (bs) % size_range;
258 	  mpz_rrandomb (in3, rands, size);
259 	}
260       else
261 	{
262 	  /* Make all input operands have about the same size */
263 	  mpz_urandomb (bs, rands, size_range);
264 	  size = mpz_get_ui (bs);
265 	  mpz_rrandomb (in1, rands, size);
266 
267 	  mpz_urandomb (bs, rands, size_range);
268 	  size = mpz_get_ui (bs);
269 	  mpz_rrandomb (in2, rands, size);
270 
271 	  mpz_urandomb (bs, rands, size_range);
272 	  size = mpz_get_ui (bs);
273 	  mpz_rrandomb (in3, rands, size);
274 	}
275 
276       mpz_urandomb (bs, rands, 3);
277       bsi = mpz_get_ui (bs);
278       if ((bsi & 1) != 0)
279 	mpz_neg (in1, in1);
280       if ((bsi & 2) != 0)
281 	mpz_neg (in2, in2);
282       if ((bsi & 4) != 0)
283 	mpz_neg (in3, in3);
284 
285       for (i = 0; i < numberof (dss); i++)
286 	{
287 	  if (dss[i].isdivision && mpz_sgn (in2) == 0)
288 	    continue;
289 	  if (dss[i].isslow && size_range > 19)
290 	    continue;
291 
292 	  (dss[i].fptr) (ref1, in1, in2);
293 	  MPZ_CHECK_FORMAT (ref1);
294 
295 	  mpz_set (res1, in1);
296 	  INVOKE_RSS (dss[i], res1, res1, in2);
297 	  MPZ_CHECK_FORMAT (res1);
298 	  if (mpz_cmp (ref1, res1) != 0)
299 	    FAIL (dss, i, in1, in2, NULL);
300 
301 	  mpz_set (res1, in2);
302 	  INVOKE_RSS (dss[i], res1, in1, res1);
303 	  MPZ_CHECK_FORMAT (res1);
304 	  if (mpz_cmp (ref1, res1) != 0)
305 	    FAIL (dss, i, in1, in2, NULL);
306 	}
307 
308       for (i = 0; i < numberof (ddss_div); i++)
309 	{
310 	  if (mpz_sgn (in2) == 0)
311 	    continue;
312 
313 	  (ddss_div[i].fptr) (ref1, ref2, in1, in2);
314 	  MPZ_CHECK_FORMAT (ref1);
315 	  MPZ_CHECK_FORMAT (ref2);
316 
317 	  mpz_set (res1, in1);
318 	  INVOKE_RRSS (ddss_div[i], res1, res2, res1, in2);
319 	  MPZ_CHECK_FORMAT (res1);
320 	  MPZ_CHECK_FORMAT (res2);
321 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
322 	    FAIL (ddss_div, i, in1, in2, NULL);
323 
324 	  mpz_set (res2, in1);
325 	  INVOKE_RRSS (ddss_div[i], res1, res2, res2, in2);
326 	  MPZ_CHECK_FORMAT (res1);
327 	  MPZ_CHECK_FORMAT (res2);
328 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
329 	    FAIL (ddss_div, i, in1, in2, NULL);
330 
331 	  mpz_set (res1, in2);
332 	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res1);
333 	  MPZ_CHECK_FORMAT (res1);
334 	  MPZ_CHECK_FORMAT (res2);
335 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
336 	    FAIL (ddss_div, i, in1, in2, NULL);
337 
338 	  mpz_set (res2, in2);
339 	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res2);
340 	  MPZ_CHECK_FORMAT (res1);
341 	  MPZ_CHECK_FORMAT (res2);
342 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
343 	    FAIL (ddss_div, i, in1, in2, NULL);
344 	}
345 
346       for (i = 0; i < numberof (ds); i++)
347 	{
348 	  if (ds[i].nonneg && mpz_sgn (in1) < 0)
349 	    continue;
350 
351 	  (ds[i].fptr) (ref1, in1);
352 	  MPZ_CHECK_FORMAT (ref1);
353 
354 	  mpz_set (res1, in1);
355 	  INVOKE_RS (ds[i], res1, res1);
356 	  MPZ_CHECK_FORMAT (res1);
357 	  if (mpz_cmp (ref1, res1) != 0)
358 	    FAIL (ds, i, in1, in2, NULL);
359 	}
360 
361       in2i = mpz_get_ui (in2);
362 
363       for (i = 0; i < numberof (dsi); i++)
364 	{
365 	  if (dsi[i].mod != 0)
366 	    in2i = mpz_get_ui (in2) % dsi[i].mod;
367 
368 	  (dsi[i].fptr) (ref1, in1, in2i);
369 	  MPZ_CHECK_FORMAT (ref1);
370 
371 	  mpz_set (res1, in1);
372 	  INVOKE_RRS (dsi[i], res1, res1, in2i);
373 	  MPZ_CHECK_FORMAT (res1);
374 	  if (mpz_cmp (ref1, res1) != 0)
375 	    FAIL (dsi, i, in1, in2, NULL);
376 	}
377 
378       if (in2i != 0)	  /* Don't divide by 0.  */
379 	{
380 	  for (i = 0; i < numberof (dsi_div); i++)
381 	    {
382 	      r1 = (dsi_div[i].fptr) (ref1, in1, in2i);
383 	      MPZ_CHECK_FORMAT (ref1);
384 
385 	      mpz_set (res1, in1);
386 	      r2 = (dsi_div[i].fptr) (res1, res1, in2i);
387 	      MPZ_CHECK_FORMAT (res1);
388 	      if (mpz_cmp (ref1, res1) != 0 || r1 != r2)
389 		FAIL (dsi_div, i, in1, in2, NULL);
390 	    }
391 
392 	  for (i = 0; i < numberof (ddsi_div); i++)
393 	    {
394 	      r1 = (ddsi_div[i].fptr) (ref1, ref2, in1, in2i);
395 	      MPZ_CHECK_FORMAT (ref1);
396 
397 	      mpz_set (res1, in1);
398 	      r2 = (ddsi_div[i].fptr) (res1, res2, res1, in2i);
399 	      MPZ_CHECK_FORMAT (res1);
400 	      if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
401 		FAIL (ddsi_div, i, in1, in2, NULL);
402 
403 	      mpz_set (res2, in1);
404 	      (ddsi_div[i].fptr) (res1, res2, res2, in2i);
405 	      MPZ_CHECK_FORMAT (res1);
406 	      if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
407 		FAIL (ddsi_div, i, in1, in2, NULL);
408 	    }
409 	}
410 
411       if (mpz_sgn (in1) >= 0)
412 	{
413 	  mpz_sqrtrem (ref1, ref2, in1);
414 	  MPZ_CHECK_FORMAT (ref1);
415 	  MPZ_CHECK_FORMAT (ref2);
416 
417 	  mpz_set (res1, in1);
418 	  mpz_sqrtrem (res1, res2, res1);
419 	  MPZ_CHECK_FORMAT (res1);
420 	  MPZ_CHECK_FORMAT (res2);
421 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
422 	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
423 
424 	  mpz_set (res2, in1);
425 	  mpz_sqrtrem (res1, res2, res2);
426 	  MPZ_CHECK_FORMAT (res1);
427 	  MPZ_CHECK_FORMAT (res2);
428 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
429 	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
430 
431 	  mpz_set (res1, in1);
432 	  mpz_sqrtrem (res1, res1, res1);
433 	  MPZ_CHECK_FORMAT (res1);
434 	  if (mpz_cmp (ref2, res1) != 0)
435 	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
436 	}
437 
438       if (mpz_sgn (in1) >= 0)
439 	{
440 	  mpz_root (ref1, in1, in2i % 0x100 + 1);
441 	  MPZ_CHECK_FORMAT (ref1);
442 
443 	  mpz_set (res1, in1);
444 	  mpz_root (res1, res1, in2i % 0x100 + 1);
445 	  MPZ_CHECK_FORMAT (res1);
446 	  if (mpz_cmp (ref1, res1) != 0)
447 	    FAIL2 (mpz_root, in1, in2, NULL);
448 	}
449 
450       if (mpz_sgn (in1) >= 0)
451 	{
452 	  mpz_rootrem (ref1, ref2, in1, in2i % 0x100 + 1);
453 	  MPZ_CHECK_FORMAT (ref1);
454 	  MPZ_CHECK_FORMAT (ref2);
455 
456 	  mpz_set (res1, in1);
457 	  mpz_rootrem (res1, res2, res1, in2i % 0x100 + 1);
458 	  MPZ_CHECK_FORMAT (res1);
459 	  MPZ_CHECK_FORMAT (res2);
460 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
461 	    FAIL2 (mpz_rootrem, in1, in2, NULL);
462 
463 	  mpz_set (res2, in1);
464 	  mpz_rootrem (res1, res2, res2, in2i % 0x100 + 1);
465 	  MPZ_CHECK_FORMAT (res1);
466 	  MPZ_CHECK_FORMAT (res2);
467 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
468 	    FAIL2 (mpz_rootrem, in1, in2, NULL);
469 	}
470 
471       if (size_range < 18)	/* run fewer tests since gcdext is slow */
472 	{
473 	  mpz_gcdext (ref1, ref2, ref3, in1, in2);
474 	  MPZ_CHECK_FORMAT (ref1);
475 	  MPZ_CHECK_FORMAT (ref2);
476 	  MPZ_CHECK_FORMAT (ref3);
477 
478 	  mpz_set (res1, in1);
479 	  mpz_gcdext (res1, res2, res3, res1, in2);
480 	  MPZ_CHECK_FORMAT (res1);
481 	  MPZ_CHECK_FORMAT (res2);
482 	  MPZ_CHECK_FORMAT (res3);
483 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
484 	      || mpz_cmp (ref3, res3) != 0)
485 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
486 
487 	  mpz_set (res2, in1);
488 	  mpz_gcdext (res1, res2, res3, res2, in2);
489 	  MPZ_CHECK_FORMAT (res1);
490 	  MPZ_CHECK_FORMAT (res2);
491 	  MPZ_CHECK_FORMAT (res3);
492 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
493 	      || mpz_cmp (ref3, res3) != 0)
494 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
495 
496 	  mpz_set (res3, in1);
497 	  mpz_gcdext (res1, res2, res3, res3, in2);
498 	  MPZ_CHECK_FORMAT (res1);
499 	  MPZ_CHECK_FORMAT (res2);
500 	  MPZ_CHECK_FORMAT (res3);
501 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
502 	      || mpz_cmp (ref3, res3) != 0)
503 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
504 
505 	  mpz_set (res1, in2);
506 	  mpz_gcdext (res1, res2, res3, in1, res1);
507 	  MPZ_CHECK_FORMAT (res1);
508 	  MPZ_CHECK_FORMAT (res2);
509 	  MPZ_CHECK_FORMAT (res3);
510 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
511 	      || mpz_cmp (ref3, res3) != 0)
512 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
513 
514 	  mpz_set (res2, in2);
515 	  mpz_gcdext (res1, res2, res3, in1, res2);
516 	  MPZ_CHECK_FORMAT (res1);
517 	  MPZ_CHECK_FORMAT (res2);
518 	  MPZ_CHECK_FORMAT (res3);
519 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
520 	      || mpz_cmp (ref3, res3) != 0)
521 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
522 
523 	  mpz_set (res3, in2);
524 	  mpz_gcdext (res1, res2, res3, in1, res3);
525 	  MPZ_CHECK_FORMAT (res1);
526 	  MPZ_CHECK_FORMAT (res2);
527 	  MPZ_CHECK_FORMAT (res3);
528 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
529 	      || mpz_cmp (ref3, res3) != 0)
530 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
531 
532 	  mpz_set (res1, in1);
533 	  mpz_gcdext (res1, res2, NULL, res1, in2);
534 	  MPZ_CHECK_FORMAT (res1);
535 	  MPZ_CHECK_FORMAT (res2);
536 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
537 	      || mpz_cmp (ref3, res3) != 0)
538 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
539 
540 	  mpz_set (res2, in1);
541 	  mpz_gcdext (res1, res2, NULL, res2, in2);
542 	  MPZ_CHECK_FORMAT (res1);
543 	  MPZ_CHECK_FORMAT (res2);
544 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
545 	      || mpz_cmp (ref3, res3) != 0)
546 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
547 
548 	  mpz_set (res1, in2);
549 	  mpz_gcdext (res1, res2, NULL, in1, res1);
550 	  MPZ_CHECK_FORMAT (res1);
551 	  MPZ_CHECK_FORMAT (res2);
552 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
553 	      || mpz_cmp (ref3, res3) != 0)
554 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
555 
556 	  mpz_set (res2, in2);
557 	  mpz_gcdext (res1, res2, NULL, in1, res2);
558 	  MPZ_CHECK_FORMAT (res1);
559 	  MPZ_CHECK_FORMAT (res2);
560 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
561 	      || mpz_cmp (ref3, res3) != 0)
562 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
563 	}
564 
565       /* Don't run mpz_powm for huge exponents or when undefined.  */
566       if (size_range < 17 && mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0
567 	  && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3)))
568 	{
569 	  mpz_powm (ref1, in1, in2, in3);
570 	  MPZ_CHECK_FORMAT (ref1);
571 
572 	  mpz_set (res1, in1);
573 	  mpz_powm (res1, res1, in2, in3);
574 	  MPZ_CHECK_FORMAT (res1);
575 	  if (mpz_cmp (ref1, res1) != 0)
576 	    FAIL2 (mpz_powm, in1, in2, in3);
577 
578 	  mpz_set (res1, in2);
579 	  mpz_powm (res1, in1, res1, in3);
580 	  MPZ_CHECK_FORMAT (res1);
581 	  if (mpz_cmp (ref1, res1) != 0)
582 	    FAIL2 (mpz_powm, in1, in2, in3);
583 
584 	  mpz_set (res1, in3);
585 	  mpz_powm (res1, in1, in2, res1);
586 	  MPZ_CHECK_FORMAT (res1);
587 	  if (mpz_cmp (ref1, res1) != 0)
588 	    FAIL2 (mpz_powm, in1, in2, in3);
589 	}
590 
591       /* Don't run mpz_powm_ui when undefined.  */
592       if (size_range < 17 && mpz_sgn (in3) != 0)
593 	{
594 	  mpz_powm_ui (ref1, in1, in2i, in3);
595 	  MPZ_CHECK_FORMAT (ref1);
596 
597 	  mpz_set (res1, in1);
598 	  mpz_powm_ui (res1, res1, in2i, in3);
599 	  MPZ_CHECK_FORMAT (res1);
600 	  if (mpz_cmp (ref1, res1) != 0)
601 	    FAIL2 (mpz_powm_ui, in1, in2, in3);
602 
603 	  mpz_set (res1, in3);
604 	  mpz_powm_ui (res1, in1, in2i, res1);
605 	  MPZ_CHECK_FORMAT (res1);
606 	  if (mpz_cmp (ref1, res1) != 0)
607 	    FAIL2 (mpz_powm_ui, in1, in2, in3);
608 	}
609 
610       {
611 	r1 = mpz_gcd_ui (ref1, in1, in2i);
612 	MPZ_CHECK_FORMAT (ref1);
613 
614 	mpz_set (res1, in1);
615 	r2 = mpz_gcd_ui (res1, res1, in2i);
616 	MPZ_CHECK_FORMAT (res1);
617 	if (mpz_cmp (ref1, res1) != 0)
618 	  FAIL2 (mpz_gcd_ui, in1, in2, NULL);
619       }
620 
621       if (mpz_sgn (in2) != 0)
622 	{
623 	  /* Test mpz_remove */
624 	  mp_bitcnt_t refretval, retval;
625 	  refretval = mpz_remove (ref1, in1, in2);
626 	  MPZ_CHECK_FORMAT (ref1);
627 
628 	  mpz_set (res1, in1);
629 	  retval = mpz_remove (res1, res1, in2);
630 	  MPZ_CHECK_FORMAT (res1);
631 	  if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
632 	    FAIL2 (mpz_remove, in1, in2, NULL);
633 
634 	  mpz_set (res1, in2);
635 	  retval = mpz_remove (res1, in1, res1);
636 	  MPZ_CHECK_FORMAT (res1);
637 	  if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
638 	    FAIL2 (mpz_remove, in1, in2, NULL);
639 	}
640 
641       if (mpz_sgn (in2) != 0)
642 	{
643 	  /* Test mpz_divexact */
644 	  mpz_mul (t, in1, in2);
645 	  mpz_divexact (ref1, t, in2);
646 	  MPZ_CHECK_FORMAT (ref1);
647 
648 	  mpz_set (res1, t);
649 	  mpz_divexact (res1, res1, in2);
650 	  MPZ_CHECK_FORMAT (res1);
651 	  if (mpz_cmp (ref1, res1) != 0)
652 	    FAIL2 (mpz_divexact, t, in2, NULL);
653 
654 	  mpz_set (res1, in2);
655 	  mpz_divexact (res1, t, res1);
656 	  MPZ_CHECK_FORMAT (res1);
657 	  if (mpz_cmp (ref1, res1) != 0)
658 	    FAIL2 (mpz_divexact, t, in2, NULL);
659 	}
660 
661       if (mpz_sgn (in2) > 0)
662 	{
663 	  /* Test mpz_divexact_gcd, same as mpz_divexact */
664 	  mpz_mul (t, in1, in2);
665 	  mpz_divexact_gcd (ref1, t, in2);
666 	  MPZ_CHECK_FORMAT (ref1);
667 
668 	  mpz_set (res1, t);
669 	  mpz_divexact_gcd (res1, res1, in2);
670 	  MPZ_CHECK_FORMAT (res1);
671 	  if (mpz_cmp (ref1, res1) != 0)
672 	    FAIL2 (mpz_divexact_gcd, t, in2, NULL);
673 
674 	  mpz_set (res1, in2);
675 	  mpz_divexact_gcd (res1, t, res1);
676 	  MPZ_CHECK_FORMAT (res1);
677 	  if (mpz_cmp (ref1, res1) != 0)
678 	    FAIL2 (mpz_divexact_gcd, t, in2, NULL);
679 	}
680     }
681 
682   if (isatty (fileno (stdout)))
683     printf ("\r%20s", "");
684 
685   mpz_clear (bs);
686   mpz_clear (in1);
687   mpz_clear (in2);
688   mpz_clear (in3);
689   mpz_clear (ref1);
690   mpz_clear (ref2);
691   mpz_clear (ref3);
692   mpz_clear (res1);
693   mpz_clear (res2);
694   mpz_clear (res3);
695   mpz_clear (t);
696 
697   if (isatty (fileno (stdout)))
698     printf ("\r");
699 
700   tests_end ();
701   exit (0);
702 }
703 
704 void
705 dump (const char *name, mpz_t in1, mpz_t in2, mpz_t in3)
706 {
707   printf ("failure in %s (", name);
708   0 && mpz_out_str (stdout, -16, in1);
709   if (in2 != NULL)
710     {
711       printf (" ");
712       0 && mpz_out_str (stdout, -16, in2);
713     }
714   if (in3 != NULL)
715     {
716       printf (" ");
717       0 && mpz_out_str (stdout, -16, in3);
718     }
719   printf (")\n");
720 }
721 
722 #endif /* ! DLL_EXPORT */
723