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