Hello,
I am tracking a bug and find the lshift_value function in 
expmed.c questionable (both head and gcc 4.4).

Suppose HOST_BITS_PER_WIDE_INT = 32,  bitpos = 0
and bitsize = 33, the following expression is wrong

        high =  (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) 
                & ((1 << (bitpos + bitsize - HOST_BITS_PER_WIDE_INT)) - 1);

v >> 32 bits on a 32-bit machine is undefined. On i386, 
v >> 32 results in v, which is not intention of the function.

Cheers,
Bingfeng Mei



static rtx
lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize)
{
  unsigned HOST_WIDE_INT v = INTVAL (value);
 
  HOST_WIDE_INT low, high;
 
  if (bitsize < HOST_BITS_PER_WIDE_INT)
    v &= ~((HOST_WIDE_INT) -1 << bitsize);
 
  if (bitpos < HOST_BITS_PER_WIDE_INT)
    {
      low = v << bitpos;
      /* Obtain value by shifting and set zeros for remaining part*/
      if((bitpos + bitsize) > HOST_BITS_PER_WIDE_INT)
        high =  (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) 
                & ((1 << (bitpos + bitsize - HOST_BITS_PER_WIDE_INT)) - 1);
      else
        high = 0;          
    }
  else
    {
      low = 0;
      high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
    }
 
  return immed_double_const (low, high, mode);
}

Reply via email to