Hi, in the ARM "casesi" expand pattern, when the table base index constant is 0x8000000, it is stored sign extended as an rtx (const_int 0xffffffff8000000) (assuming 64-bit HOST_WIDE_INT).
Subtraction by adding GEN_INT(-INTVAL(operands[1])) then creates (const_int 0x80000000), which is not sign-extended, and fails to match the nonmemory_operand predicate later, causing a extract_insn failure ICE. So the fix is to use gen_int_mode() instead of GEN_INT, which does the needed sign-extension. Cross-tested on QEMU without regressions, okay for trunk? Thanks, Chung-Lin
Index: config/arm/arm.md =================================================================== --- config/arm/arm.md (revision 171339) +++ config/arm/arm.md (working copy) @@ -8354,7 +8354,8 @@ rtx reg = gen_reg_rtx (SImode); emit_insn (gen_addsi3 (reg, operands[0], - GEN_INT (-INTVAL (operands[1])))); + gen_int_mode (-INTVAL (operands[1]), + SImode))); operands[0] = reg; } Index: testsuite/gcc.target/arm/pr46934.c =================================================================== --- testsuite/gcc.target/arm/pr46934.c (revision 0) +++ testsuite/gcc.target/arm/pr46934.c (revision 0) @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=armv5te -mthumb -Os" } */ +/* { dg-require-effective-target arm_thumb1_ok } */ + +int caller (unsigned int reg_type) +{ + switch (reg_type) + { + case 0x80000000: + return (int)foo(); + + case 0x80000003: + return (int) bar(); + + case 0x80000001: + return (int) baz(); + + case 0x80000004: + return (int) fooz(); + } +}