From patchwork Mon Jan 31 12:08:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 81097 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 43F8AB70A9 for ; Mon, 31 Jan 2011 23:08:28 +1100 (EST) Received: (qmail 23646 invoked by alias); 31 Jan 2011 12:08:24 -0000 Received: (qmail 23620 invoked by uid 22791); 31 Jan 2011 12:08:22 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-bw0-f47.google.com (HELO mail-bw0-f47.google.com) (209.85.214.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 31 Jan 2011 12:08:16 +0000 Received: by bwz10 with SMTP id 10so5642450bwz.20 for ; Mon, 31 Jan 2011 04:08:14 -0800 (PST) Received: by 10.204.103.205 with SMTP id l13mr5130321bko.160.1296475694254; Mon, 31 Jan 2011 04:08:14 -0800 (PST) Received: from richards-thinkpad (gbibp9ph1--blueice3n2.emea.ibm.com [195.212.29.84]) by mx.google.com with ESMTPS id rc9sm8767754bkb.2.2011.01.31.04.08.13 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 31 Jan 2011 04:08:13 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [ARM] PR 47551: neon-related spill faliure Date: Mon, 31 Jan 2011 12:08:12 +0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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); +}