[patch][4.0] for PR 27003

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Thu May 11 16:08:00 GMT 2006


Hello,

this bug is caused by build_int_cst_type doing shift by number of bits
of HOST_WIDE_INT, which happens to be no-op on x86.  This problem was
fixed in 4.1 some time ago, but the fix was not commited to 4.0 branch.

Bootstrapped & regtested on i686.

Zdenek

	PR tree-optimization/27003
	* tree.c (build_int_cst_type): Avoid shift by size of type.

Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.474
diff -c -3 -p -r1.474 tree.c
*** tree.c	22 Apr 2005 10:56:57 -0000	1.474
--- tree.c	22 Apr 2005 21:23:04 -0000
*************** tree
*** 518,524 ****
  build_int_cst_type (tree type, HOST_WIDE_INT low)
  {
    unsigned HOST_WIDE_INT val = (unsigned HOST_WIDE_INT) low;
!   unsigned HOST_WIDE_INT hi;
    unsigned bits;
    bool signed_p;
    bool negative;
--- 518,524 ----
  build_int_cst_type (tree type, HOST_WIDE_INT low)
  {
    unsigned HOST_WIDE_INT val = (unsigned HOST_WIDE_INT) low;
!   unsigned HOST_WIDE_INT hi, mask;
    unsigned bits;
    bool signed_p;
    bool negative;
*************** build_int_cst_type (tree type, HOST_WIDE
*** 538,547 ****
        negative = ((val >> (bits - 1)) & 1) != 0;
  
        /* Mask out the bits outside of the precision of the constant.  */
        if (signed_p && negative)
! 	val = val | ((~(unsigned HOST_WIDE_INT) 0) << bits);
        else
! 	val = val & ~((~(unsigned HOST_WIDE_INT) 0) << bits);
      }
  
    /* Determine the high bits.  */
--- 538,549 ----
        negative = ((val >> (bits - 1)) & 1) != 0;
  
        /* Mask out the bits outside of the precision of the constant.  */
+       mask = (((unsigned HOST_WIDE_INT) 2) << (bits - 1)) - 1;
+ 
        if (signed_p && negative)
! 	val |= ~mask;
        else
! 	val &= mask;
      }
  
    /* Determine the high bits.  */
*************** build_int_cst_type (tree type, HOST_WIDE
*** 556,562 ****
        else
  	{
  	  bits -= HOST_BITS_PER_WIDE_INT;
! 	  hi = hi & ~((~(unsigned HOST_WIDE_INT) 0) << bits);
  	}
      }
  
--- 558,565 ----
        else
  	{
  	  bits -= HOST_BITS_PER_WIDE_INT;
! 	  mask = (((unsigned HOST_WIDE_INT) 2) << (bits - 1)) - 1;
! 	  hi &= mask;
  	}
      }
  



More information about the Gcc-patches mailing list