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: unassig...@gcc.gnu.org ReportedBy: ja...@gcc.gnu.org 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.