Hi, When I test MPFR with
./configure --with-mini-gmp=/home/vlefevre/software/gmp/mini-gmp CC=gcc-13 CFLAGS="-O2 -fsanitize=undefined -fno-sanitize-recover -DMINI_GMP_LIMB_TYPE=short" I get lots of failures in mini-gmp.c (I suspect that the errors were hidden by some optimization in GCC 12 and before). For instance: cventin:...ftware/mpfr/tests> ./texceptions mini-gmp.c:993:7: runtime error: signed integer overflow: 46604 * 61440 cannot be represented in type 'int' This is a call to gmp_udiv_qrnnd_preinv, which has #define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ do { \ mp_limb_t _qh, _ql, _r, _mask; \ gmp_umul_ppmm (_qh, _ql, (nh), (di)); \ gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \ _r = (nl) - _qh * (d); \ [...] Here, both _qh and d have type mp_limb_t, which is an unsigned short. Since this is a 16-bit type and int is on 32 bits, unsigned short is promoted to int, which is now a signed integer type, hence the error. Ditto in gmp_udiv_qr_3by2. I suppose that the simplest solution would be to add a cast to unsigned long, so that the multiplication is done in this type (and the subtraction too as a consequence), as this should be the largest MINI_GMP_LIMB_TYPE size... hoping that the compiler will optimize. I've attached a patch. On the following testcase, GCC generates the same code for i1 and i2 and for s1 and s2 (tested on 32-bit and 64-bit x86, on aarch64, and on ppc64le): unsigned int i1 (unsigned int a, unsigned int b, unsigned int c) { return a - b * c; } unsigned int i2 (unsigned int a, unsigned int b, unsigned int c) { return a - (unsigned long) b * c; } unsigned short s1 (unsigned short a, unsigned short b, unsigned short c) { return a - b * c; } unsigned short s2 (unsigned short a, unsigned short b, unsigned short c) { return a - (unsigned long) b * c; } Otherwise the sizes of the types could be checked like in gmp_umul_ppmm. -- Vincent Lefèvre <vinc...@vinc17.net> - Web: <https://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
diff -r 73d9ef70d14f mini-gmp/mini-gmp.c --- a/mini-gmp/mini-gmp.c Wed Jul 19 11:44:37 2023 +0200 +++ b/mini-gmp/mini-gmp.c Wed Jul 19 15:43:46 2023 +0200 @@ -177,7 +177,7 @@ mp_limb_t _qh, _ql, _r, _mask; \ gmp_umul_ppmm (_qh, _ql, (nh), (di)); \ gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \ - _r = (nl) - _qh * (d); \ + _r = (nl) - (unsigned long int) _qh * (d); \ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \ _qh += _mask; \ _r += _mask & (d); \ @@ -198,7 +198,7 @@ gmp_add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \ \ /* Compute the two most significant limbs of n - q'd */ \ - (r1) = (n1) - (d1) * (q); \ + (r1) = (n1) - (unsigned long int) (d1) * (q); \ gmp_sub_ddmmss ((r1), (r0), (r1), (n0), (d1), (d0)); \ gmp_umul_ppmm (_t1, _t0, (d0), (q)); \ gmp_sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \
_______________________________________________ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs