Patchwork PATCH RFA: Patch for GCC PR 47540 ARM -mthumb _Complex ICE

login
register
mail settings
Submitter Ian Taylor
Date Feb. 1, 2011, 9:43 p.m.
Message ID <mcrmxmfjurr.fsf@google.com>
Download mbox | patch
Permalink /patch/81384/
State New
Headers show

Comments

Ian Taylor - Feb. 1, 2011, 9:43 p.m.
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  <iant@google.com>

	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  <iant@google.com>

	PR target/47540
	* gcc.dg/complex-6.c: New test.

Patch

Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 169387)
+++ gcc/config/arm/arm.c	(working copy)
@@ -17576,12 +17576,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))
Index: gcc/testsuite/gcc.dg/complex-6.c
===================================================================
--- gcc/testsuite/gcc.dg/complex-6.c	(revision 0)
+++ gcc/testsuite/gcc.dg/complex-6.c	(revision 0)
@@ -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); }