[ARM] PR 47551: neon-related spill faliure
Richard Sandiford
richard.sandiford@linaro.org
Mon Jan 31 12:34:00 GMT 2011
This patch fixes a reload failure that occurs if (a) a register with
a "structure" mode such as CImode is spilled to the stack and (b) the
stack slot is out of the neon load/store range.
For structure and vector modes, the only legitimate addresses are
those that neon supports. This means that, when (b) occurs, reload will
rightly decide to reload the address into a temporary reload register.
The problem is that the ARM backend also says that the load must go
through a GENERAL_REGS reload register:
Reloads for insn # 1817
Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 11 fp)
(const_int -7548 [0xffffffffffffe284]))
CORE_REGS, RELOAD_FOR_OUTPUT_ADDRESS (opnum = 0), can't combine
reload_in_reg: (plus:SI (reg/f:SI 11 fp)
(const_int -7548 [0xffffffffffffe284]))
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 11 fp)
(const_int -7548 [0xffffffffffffe284]))
CORE_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0), can't combine
reload_in_reg: (plus:SI (reg/f:SI 11 fp)
(const_int -7548 [0xffffffffffffe284]))
Reload 2: GENERAL_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0), can't combine, secondary_reload_p
Reload 3: GENERAL_REGS, RELOAD_FOR_OUTPUT_ADDRESS (opnum = 0), can't combine, secondary_reload_p
Reload 4: reload_in (CI) = (mem/c:CI (plus:SI (reg/f:SI 11 fp)
(const_int -7548 [0xffffffffffffe284])) [0 %sfp+-7496 S48 A64])
reload_out (CI) = (mem/c:CI (plus:SI (reg/f:SI 11 fp)
(const_int -7548 [0xffffffffffffe284])) [0 %sfp+-7496 S48 A64])
VFP_REGS, RELOAD_OTHER (opnum = 0), can't combine
reload_in_reg: (reg:CI 303 [ D.14795 ])
reload_out_reg: (reg:CI 303 [ D.14795 ])
secondary_in_reload = 2, secondary_out_reload = 3
where secondary reloads 2 and 3 are bogus.
This comes from two related problems in coproc_secondary_reload_class:
it doesn't handle structure modes like CImode, and it checks whether
the MEM is already legitimate. The latter is wrong because the memory
is still in its unreloaded form. The structure and vector move patterns
handle all valid addresses, and reload will take care of invalid
addresses for us, so we should simply check for a MEM.
Tested on arm-linux-gnueabi (-marm and -mthumb). I don't think this
is a regression, so: OK to install once 4.7 is open?
Richard
gcc/
PR target/47551
* config/arm/arm.c (coproc_secondary_reload_class): Handle
structure modes. Don't check neon_vector_mem_operand for
vector or structure modes.
gcc/testsuite/
PR target/47551
* gcc.target/arm/neon-modes-2.c: New test.
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c 2011-01-31 11:13:20.000000000 +0000
+++ gcc/config/arm/arm.c 2011-01-31 11:27:45.000000000 +0000
@@ -9083,11 +9083,14 @@ coproc_secondary_reload_class (enum mach
return GENERAL_REGS;
}
+ /* The neon move patterns handle all legitimate vector and struct
+ addresses. */
if (TARGET_NEON
+ && MEM_P (x)
&& (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
- && neon_vector_mem_operand (x, 0))
- return NO_REGS;
+ || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
+ || VALID_NEON_STRUCT_MODE (mode)))
+ return NO_REGS;
if (arm_coproc_mem_operand (x, wb) || s_register_operand (x, mode))
return NO_REGS;
Index: gcc/testsuite/gcc.target/arm/neon-modes-2.c
===================================================================
--- /dev/null 2011-01-26 10:43:14.268819722 +0000
+++ gcc/testsuite/gcc.target/arm/neon-modes-2.c 2011-01-31 11:28:42.000000000 +0000
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-O1" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+
+#define SETUP(A) x##A = vld3_u32 (ptr + A * 0x20)
+#define MODIFY(A) x##A = vld3_lane_u32 (ptr + A * 0x20 + 0x10, x##A, 1)
+#define STORE(A) vst3_u32 (ptr + A * 0x20, x##A)
+
+#define MANY(A) A (0), A (1), A (2), A (3), A (4), A (5)
+
+void
+bar (uint32_t *ptr, int y)
+{
+ uint32x2x3_t MANY (SETUP);
+ int *x = __builtin_alloca (y);
+ int z[0x1000];
+ foo (x, z);
+ MANY (MODIFY);
+ foo (x, z);
+ MANY (STORE);
+}
More information about the Gcc-patches
mailing list