http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55838
Steven Bosscher <steven at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|ASSIGNED |NEW
AssignedTo|steven at gcc dot gnu.org |unassigned at gcc dot
| |gnu.org
--- Comment #9 from Steven Bosscher <steven at gcc dot gnu.org> 2013-01-01
21:02:55 UTC ---
In general_operand, the following check fails:
951 if (CONST_INT_P (op)
952 && mode != VOIDmode
953 && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
954 return 0;
with op=(const_int 129) and trunc_int_for_mode (129, QImode)=-127.
This happens because trunc_int_for_mode sign-extends 129 (0b10000001):
65 if (width < HOST_BITS_PER_WIDE_INT)
66 {
67 HOST_WIDE_INT sign = 1;
68 sign <<= width - 1;
69 c &= (sign << 1) - 1;
70 c ^= sign;
71 c -= sign;
72 }
with width=8 for QImode and HOST_BITS_PER_WIDE_INT is 64 in my case. So:
sign=128 (0b10000000), c=129 (0b10000001)
c &= (sign << 1) - 1 = 129
c ^= sign = 1
c -= sign = 1 - 128 = -127 (0b11111111)
???
For someone with better RTL-fu than me...