[backport from gcc-4.7/trunk ] Date: Wed, 23 Mar 2011 23:52:34 +0900 From: Chung-Lin Tang Subject: [patch, ARM] Fix PR46934, Thumb-1 ICE List-Archive: 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? gcc/ 2011-03-23 Chung-Lin Tang PR target/46934 * config/arm/arm.md (casesi): Use the gen_int_mode() function to subtract lower bound instead of GEN_INT(). gcc/testsuite/ 2011-03-23 Chung-Lin Tang * gcc.target/arm/pr46934.c: New. --- gcc-4.6.0/gcc/config/arm/arm.md.~1~ 2011-03-15 20:59:25.000000000 +0100 +++ gcc-4.6.0/gcc/config/arm/arm.md 2011-05-14 16:04:13.000000000 +0200 @@ -8354,7 +8354,8 @@ (define_expand "casesi" 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; } --- gcc-4.6.0/gcc/testsuite/gcc.target/arm/pr46934.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.0/gcc/testsuite/gcc.target/arm/pr46934.c 2011-05-14 16:04:13.000000000 +0200 @@ -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(); + } +}