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); }