This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: [gfortran] Fix PR 17568: Shortcomings in ISHFT constant folder
- From: Tobias Schlüter <tobias dot schlueter at physik dot uni-muenchen dot de>
- To: Paul Brook <paul at codesourcery dot com>
- Cc: fortran at gcc dot gnu dot org, patch <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 05 Oct 2004 02:22:36 +0200
- Subject: Re: [gfortran] Fix PR 17568: Shortcomings in ISHFT constant folder
- References: <415F024E.9040602@physik.uni-muenchen.de> <200410041835.15371.paul@codesourcery.com>
Paul Brook wrote:
> You twos_complement routine is flawed:
>
>
>>+ static void
>>+ twos_complement (mpz_t x, int bitsize)
>>+ {
>>+ mpz_t mask;
>>+ unsigned long mask_i;
>>+
>>+ if (mpz_tstbit (x, bitsize - 1) == 1)
>>+ {
>>+ mask_i = (bitsize == sizeof(long) * 8) ? ~0 : (1 << bitsize) - 1;
>
>
> Doesn't work when bitsize > sizeof(long)*8.
Oops, for some reason I assumed that long would be the largest type.
I will commit with twos_complement replaced by the following modulo the
question I ask below, once the compiler has rebuilt (arg, why did I have to
change lang.opt), and I verified that this does what I think it does:
+/* Checks if X, which is assumed to represent a two's complement
+ integer of binary width BITSIZE, has the signbit set. If so, makes
+ X the corresponding negative number. */
+
+static void
+twos_complement (mpz_t x, int bitsize)
+{
+ mpz_t mask;
+ char *mask_s;
+
+ if (mpz_tstbit (x, bitsize - 1) == 1)
+ {
+ /* The mpz_init_set_{u|s}i functions take a long argument, but
+ the widest integer the target supports might be wider, so we
+ have to go via an intermediate string. */
+ mask_s = alloca (bitsize + 1);
+ memset (mask_s, '1', bitsize);
+ mask_s[bitsize] = '\0';
+ mpz_init_set_str (mask, mask_s, 2);
+
+ /* We negate the number by hand, zeroing the high bits, and then
+ have it negated by GMP. */
+ mpz_com (x, x);
+ mpz_add_ui (x, x, 1);
+ mpz_and (x, x, mask);
+
+ mpz_neg (x, x);
+
+ mpz_clear (mask);
+ }
+}
+
There was some discussion previously about using alloca in the library where
this was fixed by using a compiler builtin. Is alloca appropriate here, or
should I use a fixed length string? Using a C99 VLA array is also discouraged,
as gcc 2.95 might not support it, right?
Thanks,
- Tobi