This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gfortran] Fix PR 17568: Shortcomings in ISHFT constant folder


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]