This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[PATCH][RFH] Fix PR31169, bootstrap failure on SHIFT_COUNT_TRUNCATED targets


This fixes the bootstrap failure on hppa, sparc and alpha (and maybe other
SHIFT_COUNT_TRUNCATED targets).  It's not {r,l}shift_doubles business to
truncate the shift count on such targets (I believe).

Bootstrapped and tested on x86_64-unknown-linux-gnu, can someone test
this on any of the above targets please?

Thanks,
Richard.


2007-03-30  Richard Guenther  <rguenther@suse.de>

	PR middle-end/31169
	* fold-const.c (lshift_double): Do not truncate shift count
	for SHIFT_COUNT_TRUNCATED.
	(rshift_double): Likewise.

	* gcc.c-torture/execute/pr31169.c: New testcase.

Index: fold-const.c
===================================================================
*** fold-const.c	(revision 123358)
--- fold-const.c	(working copy)
*************** lshift_double (unsigned HOST_WIDE_INT l1
*** 446,454 ****
        return;
      }
  
-   if (SHIFT_COUNT_TRUNCATED)
-     count %= prec;
- 
    if (count >= 2 * HOST_BITS_PER_WIDE_INT)
      {
        /* Shifting by the host word size is undefined according to the
--- 446,451 ----
*************** rshift_double (unsigned HOST_WIDE_INT l1
*** 507,515 ****
  	      ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
  	      : 0);
  
-   if (SHIFT_COUNT_TRUNCATED)
-     count %= prec;
- 
    if (count >= 2 * HOST_BITS_PER_WIDE_INT)
      {
        /* Shifting by the host word size is undefined according to the
--- 504,509 ----
Index: testsuite/gcc.c-torture/execute/pr31169.c
===================================================================
*** testsuite/gcc.c-torture/execute/pr31169.c	(revision 0)
--- testsuite/gcc.c-torture/execute/pr31169.c	(revision 0)
***************
*** 0 ****
--- 1,51 ----
+ extern void abort();
+ 
+ #define HOST_WIDE_INT long
+ #define HOST_BITS_PER_WIDE_INT (sizeof(long)*8)
+ 
+ struct tree_type
+ {
+   unsigned int precision : 9;
+ };
+ 
+ int
+ sign_bit_p (struct tree_type *t, HOST_WIDE_INT val_hi, unsigned HOST_WIDE_INT val_lo)
+ {
+   unsigned HOST_WIDE_INT mask_lo, lo;
+   HOST_WIDE_INT mask_hi, hi;
+   int width = t->precision;
+ 
+   if (width > HOST_BITS_PER_WIDE_INT)
+     {
+       hi = (unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1);
+       lo = 0;
+ 
+       mask_hi = ((unsigned HOST_WIDE_INT) -1
+                  >> (2 * HOST_BITS_PER_WIDE_INT - width));
+       mask_lo = -1;
+     }
+   else
+     {
+       hi = 0;
+       lo = (unsigned HOST_WIDE_INT) 1 << (width - 1);
+     
+       mask_hi = 0;
+       mask_lo = ((unsigned HOST_WIDE_INT) -1
+                  >> (HOST_BITS_PER_WIDE_INT - width));
+     }
+ 
+   if ((val_hi & mask_hi) == hi
+       && (val_lo & mask_lo) == lo)
+     return 1;
+ 
+   return 0;
+ }
+ 
+ int main()
+ {
+   struct tree_type t;
+   t.precision = 1;
+   if (!sign_bit_p (&t, 0, -1))
+     abort ();
+   return 0;
+ }


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