http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56470
Bug #: 56470
Summary: [4.8 Regression] ICE output_operand: invalid shift
operand
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: [email protected]
ReportedBy: [email protected]
Target: arm
int w[5];
void
foo (int x, unsigned y)
{
long long r = 0;
long long s;
int i;
switch (x)
{
case 1:
for (i = 0; i < 4; i++)
{
if (!y)
s = (w[9] << (10 - 2 * i)) >> (32 - 5 * i + 5 * i);
r |= (s & 0xffffffff) << (i * 5);
}
break;
case 3:
r = w[x] >> y;
}
w[x] = r;
}
ICEs at -O2 on arm-linux-gnuabi. This reduced testcase ICEs also in 4.7, but
the unreduced one at https://bugzilla.redhat.com/show_bug.cgi?id=915830#c1
only ICEs in 4.8 and not in 4.7.
I wonder why arm backend uses constraints (N) to enfore the shift count in the
range, rather than e.g. masking the operand & 31 if CONST_INT before printing.
Shift counts >= 32 for SImode are of course undefined behavior, so it really
doesn't matter what gets emitted, but we shouldn't ICE on it.