[PATCH][RFH] Fix PR31169, bootstrap failure on SHIFT_COUNT_TRUNCATED targets
Richard Guenther
rguenther@suse.de
Fri Mar 30 13:13:00 GMT 2007
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;
+ }
More information about the Gcc-patches
mailing list