[proposed fix for PR47540 _Complex ICE on thumb1, may possibly also fix PR37440 ] From: Ian Lance Taylor Subject: PATCH RFA: Patch for GCC PR 47540 ARM -mthumb _Complex ICE Date: Tue, 01 Feb 2011 13:43:20 -0800 List-Archive: This patch to the ARM backend fixes PR 47540, an ICE when compiling code using _Complex double with -mthumb. I think this patch is correct but I have not actually tested it, as I am not set up to test an ARM target. In comment #7 of http://gcc.gnu.org/PR47540 Richard more or less approved an earlier variant of this patch, but I really would feel more comfortable if somebody did a testsuite run on ARM. So, given that, OK for mainline? Thanks. Ian gcc/ChangeLog: 2011-02-01 Ian Lance Taylor PR target/47540 * config/arm/arm.c (arm_hard_regno_mode_ok): For a value larger than SImode on Thumb1 require that all registers be lo registers. gcc/testsuite/ChangeLog: 2011-02-01 Ian Lance Taylor PR target/47540 * gcc.dg/complex-6.c: New test. --- gcc-4.7-20110514/gcc/config/arm/arm.c.~1~ 2011-05-03 09:46:10.000000000 +0200 +++ gcc-4.7-20110514/gcc/config/arm/arm.c 2011-05-19 21:28:47.000000000 +0200 @@ -17604,12 +17604,12 @@ arm_hard_regno_mode_ok (unsigned int reg && regno == VFPCC_REGNUM)); if (TARGET_THUMB1) - /* For the Thumb we only allow values bigger than SImode in - registers 0 - 6, so that there is always a second low - register available to hold the upper part of the value. - We probably we ought to ensure that the register is the - start of an even numbered register pair. */ - return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM); + /* For the Thumb we only allow a value bigger than SImode in the + lo registers, and we require that the entire value fit in the + lo registers. We probably ought to ensure that the register is + the start of an even numbered register pair. */ + return (ARM_NUM_REGS (mode) < 2 + || regno + ARM_NUM_REGS (mode) - 1 <= LAST_LO_REGNUM); if (TARGET_HARD_FLOAT && TARGET_MAVERICK && IS_CIRRUS_REGNUM (regno)) --- gcc-4.7-20110514/gcc/testsuite/gcc.dg/complex-6.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7-20110514/gcc/testsuite/gcc.dg/complex-6.c 2011-05-19 21:28:47.000000000 +0200 @@ -0,0 +1,6 @@ +/* PR target/47540 */ +/* { dg-options "-O2 -std=gnu99" } */ + +extern double f1 (_Complex double); +extern _Complex double f2 (_Complex double); +_Complex double f (_Complex double x) { return f1 (x) == 0 ? 0 : f2 (x); }