From patchwork Mon Aug 1 17:10:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 107786 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 CB4BFB702E for ; Tue, 2 Aug 2011 03:11:14 +1000 (EST) Received: (qmail 11898 invoked by alias); 1 Aug 2011 17:11:11 -0000 Received: (qmail 11869 invoked by uid 22791); 1 Aug 2011 17:11:10 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_ZJ, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-pz0-f49.google.com (HELO mail-pz0-f49.google.com) (209.85.210.49) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 01 Aug 2011 17:10:56 +0000 Received: by pzk33 with SMTP id 33so12372948pzk.36 for ; Mon, 01 Aug 2011 10:10:55 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.42.131 with SMTP id o3mr8396764pbl.514.1312218655401; Mon, 01 Aug 2011 10:10:55 -0700 (PDT) Received: by 10.143.34.2 with HTTP; Mon, 1 Aug 2011 10:10:55 -0700 (PDT) Date: Mon, 1 Aug 2011 19:10:55 +0200 Message-ID: Subject: [PATCH, i386]: Fix PR49927, ice in spill_failure, at reload1.c:2120 From: Uros Bizjak To: gcc-patches@gcc.gnu.org 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 Hello! On a register starved i686, the relaxation that we allow DImode values in addresses can lead to register shortages and spill failures. Attached patch puts back the requirement that we allow subregs up to and including WORD_MODE width, nicely packed in a new function. 2011-08-01 Uros Bizjak PR target/49927 * config/i386/i386.c (ix86_address_subreg_operand): New. (ix86_decompose_address): Use ix86_address_subreg_operand. (ix86_legitimate_address_p): Do not assert that subregs satisfy register_no_elim_operand in DImode. testsuite/ChangeLog: 2011-08-01 Uros Bizjak PR target/49927 * gcc.target/i386/pr49927.c: New test. Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN. Uros. Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 177036) +++ config/i386/i386.c (working copy) @@ -11096,6 +11096,30 @@ ix86_live_on_entry (bitmap regs) } } +/* Determine if op is suitable SUBREG RTX for address. */ + +static bool +ix86_address_subreg_operand (rtx op) +{ + enum machine_mode mode; + + if (!REG_P (op)) + return false; + + mode = GET_MODE (op); + + if (GET_MODE_CLASS (mode) != MODE_INT) + return false; + + /* Don't allow SUBREGs that span more than a word. It can lead to spill + failures when the register is one word out of a two word structure. */ + if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) + return false; + + /* Allow only SUBREGs of non-eliminable hard registers. */ + return register_no_elim_operand (op, mode); +} + /* Extract the parts of an RTL expression that is a valid memory address for an instruction. Return 0 if the structure of the address is grossly off. Return -1 if the address contains ASHIFT, so it is not @@ -11116,8 +11140,7 @@ ix86_decompose_address (rtx addr, struct base = addr; else if (GET_CODE (addr) == SUBREG) { - /* Allow only subregs of DImode hard regs. */ - if (register_no_elim_operand (SUBREG_REG (addr), DImode)) + if (ix86_address_subreg_operand (SUBREG_REG (addr))) base = addr; else return 0; @@ -11175,8 +11198,7 @@ ix86_decompose_address (rtx addr, struct break; case SUBREG: - /* Allow only subregs of DImode hard regs in PLUS chains. */ - if (!register_no_elim_operand (SUBREG_REG (op), DImode)) + if (!ix86_address_subreg_operand (SUBREG_REG (op))) return 0; /* FALLTHRU */ @@ -11228,9 +11250,8 @@ ix86_decompose_address (rtx addr, struct { if (REG_P (index)) ; - /* Allow only subregs of DImode hard regs. */ else if (GET_CODE (index) == SUBREG - && register_no_elim_operand (SUBREG_REG (index), DImode)) + && ix86_address_subreg_operand (SUBREG_REG (index))) ; else return 0; @@ -11677,10 +11698,7 @@ ix86_legitimate_address_p (enum machine_ if (REG_P (base)) reg = base; else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base))) - { - reg = SUBREG_REG (base); - gcc_assert (register_no_elim_operand (reg, DImode)); - } + reg = SUBREG_REG (base); else /* Base is not a register. */ return false; @@ -11702,10 +11720,7 @@ ix86_legitimate_address_p (enum machine_ if (REG_P (index)) reg = index; else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index))) - { - reg = SUBREG_REG (index); - gcc_assert (register_no_elim_operand (reg, DImode)); - } + reg = SUBREG_REG (index); else /* Index is not a register. */ return false; Index: testsuite/gcc.target/i386/pr49927.c =================================================================== --- testsuite/gcc.target/i386/pr49927.c (revision 0) +++ testsuite/gcc.target/i386/pr49927.c (revision 0) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +char a[1][1]; +long long b; + +void +foo (void) +{ + --a[b][b]; +}