From patchwork Mon Nov 4 16:16:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 288204 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 68FA52C00AD for ; Tue, 5 Nov 2013 03:17:21 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=Ip093AJhm4ouPTFW+DELO1xCgnDi88Lda2J5dIyUJGkEcR Tk100ijLVIjZZnG/3GnHU4Gv3eEbLIiD0yZg/1EaEDtOQ9dbvG88EnGxvDOY//VG gtpy6dhDWZ0y6jZuPtYVhkIsV41itjjjeHfdkdRGfBJW2POQ1JvJ3X6LiYcZM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=gTGegyzEZVk+zKykAXar6dUGZFk=; b=myzYyRzlvqoua4nSryg4 4t0xxV90spHAOWIj7U2nbYmgbFkAxo6Gus4lJ1CdS9OoZyhh2Upw56vCsyelqohV 6zdQXb1/2cLzfre5dRVHyfZG50D3zc8gUADh3QienioryVUnYCqwEtnpCLuE3BPq p1w47cf2tB86b2QBpTa3F9o= Received: (qmail 6236 invoked by alias); 4 Nov 2013 16:16:38 -0000 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 Received: (qmail 6144 invoked by uid 89); 4 Nov 2013 16:16:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=AWL, BAYES_00, RDNS_NONE, SPF_HELO_PASS, SPF_PASS, URIBL_BLOCKED autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 04 Nov 2013 16:16:35 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rA4GGQCo028735 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 4 Nov 2013 11:16:27 -0500 Received: from topor.usersys.redhat.com ([10.15.16.142]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rA4GGQmI007780 for ; Mon, 4 Nov 2013 11:16:26 -0500 Message-ID: <5277C859.9050407@redhat.com> Date: Mon, 04 Nov 2013 11:16:25 -0500 From: Vladimir Makarov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.1.0 MIME-Version: 1.0 To: gcc-patches Subject: patch to fix pr58968 X-IsSubscribed: yes The following patch fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58968 It is actually the 3rd try to fix the problem. Removing no-ops move may result in mode-switching crashes on x86/x86-64 as it expects a specific code (by the way reload has the same problem on x86/x86-64). The patch was successfully bootstrapped and tested on x86/x86-64 and ppc64 (with LRA). Committed as rev. 204353. 2013-11-04 Vladimir Makarov PR rtl-optimization/58968 * lra-spills.c (return_regno_p): New function. (lra_final_code_change): Use it. 2013-11-04 Vladimir Makarov PR rtl-optimization/58968 * gfortran.dg/pr58968.f: New Index: lra-spills.c =================================================================== --- lra-spills.c (revision 204352) +++ lra-spills.c (working copy) @@ -618,6 +618,33 @@ alter_subregs (rtx *loc, bool final_p) return res; } +/* Return true if REGNO is used for return in the current + function. */ +static bool +return_regno_p (unsigned int regno) +{ + rtx outgoing = crtl->return_rtx; + + if (! outgoing) + return false; + + if (REG_P (outgoing)) + return REGNO (outgoing) == regno; + else if (GET_CODE (outgoing) == PARALLEL) + { + int i; + + for (i = 0; i < XVECLEN (outgoing, 0); i++) + { + rtx x = XEXP (XVECEXP (outgoing, 0, i), 0); + + if (REG_P (x) && REGNO (x) == regno) + return true; + } + } + return false; +} + /* Final change of pseudos got hard registers into the corresponding hard registers and removing temporary clobbers. */ void @@ -625,7 +652,7 @@ lra_final_code_change (void) { int i, hard_regno; basic_block bb; - rtx insn, curr, set; + rtx insn, curr; int max_regno = max_reg_num (); for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) @@ -636,7 +663,6 @@ lra_final_code_change (void) FOR_BB_INSNS_SAFE (bb, insn, curr) if (INSN_P (insn)) { - bool change_p; rtx pat = PATTERN (insn); if (GET_CODE (pat) == CLOBBER && LRA_TEMP_CLOBBER_P (pat)) @@ -649,12 +675,24 @@ lra_final_code_change (void) continue; } - set = single_set (insn); - change_p = (set != NULL - && REG_P (SET_SRC (set)) && REG_P (SET_DEST (set)) - && REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER - && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER); - + /* IRA can generate move insns involving pseudos. It is + better remove them earlier to speed up compiler a bit. + It is also better to do it here as they might not pass + final RTL check in LRA, (e.g. insn moving a control + register into itself). So remove an useless move insn + unless next insn is USE marking the return reg (we should + save this as some subsequent optimizations assume that + such original insns are saved). */ + if (NONJUMP_INSN_P (insn) && GET_CODE (pat) == SET + && REG_P (SET_SRC (pat)) && REG_P (SET_DEST (pat)) + && REGNO (SET_SRC (pat)) == REGNO (SET_DEST (pat)) + && ! return_regno_p (REGNO (SET_SRC (pat)))) + { + lra_invalidate_insn_data (insn); + delete_insn (insn); + continue; + } + lra_insn_recog_data_t id = lra_get_insn_recog_data (insn); struct lra_static_insn_data *static_id = id->insn_static_data; bool insn_change_p = false; @@ -668,20 +706,5 @@ lra_final_code_change (void) } if (insn_change_p) lra_update_operator_dups (id); - - if (change_p && REGNO (SET_SRC (set)) == REGNO (SET_DEST (set))) - { - /* Remove an useless move insn but only involving - pseudos as some subsequent optimizations are based on - that move insns involving originally hard registers - are preserved. IRA can generate move insns involving - pseudos. It is better remove them earlier to speed - up compiler a bit. It is also better to do it here - as they might not pass final RTL check in LRA, - (e.g. insn moving a control register into - itself). */ - lra_invalidate_insn_data (insn); - delete_insn (insn); - } } } Index: testsuite/gfortran.dg/pr58968.f =================================================================== --- testsuite/gfortran.dg/pr58968.f (revision 0) +++ testsuite/gfortran.dg/pr58968.f (working copy) @@ -0,0 +1,96 @@ +C PR rtl-optimization/58968.f +C { dg-do compile { target powerpc*-*-*} } +C { dg-options "-mcpu=power7 -O3 -w -ffast-math -funroll-loops" } + SUBROUTINE MAKTABS(IW,SOME,LBOX1,LBOX2,LBOX3,NSPACE,NA,NB, + * LBST,X, + * NX,IAMA,IAMI,IBMA,IBMI,MNUM,IDIM,MSTA,IBO, + * IDSYM,ISYM1,NSYM, + * NACT,LWRK,KTAB,LGMUL, + * LCON,LCOA,LCOB, + * LANDET,LBNDET,NAST,NBST,LSYMA,LSYMB,LGCOM, + * MINI,MAXI,LSPA,LSPB,LDISB, + * LSAS,LSBS,LSAC,LSBC, + * ITGA,ITGB,IAST,IBST,NCI,NA1EX,NB1EX,FDIRCT) + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + LOGICAL SOME + DIMENSION LBOX1(NSPACE),LBOX2(NSPACE),LBOX3(NSPACE),LBST(NSPACE) + DIMENSION X(NX) + DIMENSION IAMA(NSPACE),IAMI(NSPACE),IBMA(NSPACE),IBMI(NSPACE) + DIMENSION MNUM(NSPACE),IDIM(NSPACE),MSTA(NSPACE+1),IBO(NACT) + DIMENSION LWRK(43),KTAB(NSYM),LGMUL(NSYM,NSYM) + DIMENSION LCON(NA) + DIMENSION LCOA(NSYM,ITGA),LCOB(NSYM,ITGB) + DIMENSION LANDET(NSPACE,ITGA),LBNDET(NSPACE,ITGB) + DIMENSION NAST(ITGA+1),NBST(ITGB+1) + DIMENSION LSYMA(IAST),LSYMB(IBST) + DIMENSION LGCOM(ITGB,ITGA) + DIMENSION MINI(NSPACE),MAXI(NSPACE) + DIMENSION LSPA(IAST),LSPB(IBST) + DIMENSION LDISB(NSYM,ITGB,ITGA) + DIMENSION LSAS(NSYM+1,ITGA),LSBS(NSYM+1,ITGB) + DIMENSION LSAC(IAST),LSBC(IBST) + LOGICAL FDIRCT + LCOA = 0 + LCOB = 0 + ISTA1 = LBST(1) + CALL RESETCO(LBOX1,NSPACE,NB,IBMA,IBMI,LBOX2) + NAST(1) = 0 + NBST(1) = 0 + DO II=1,ITGA + ITOT = 1 + DO JJ=1,NSPACE + ITOT = ITOT * LANDET(JJ,II) + ENDDO + NAST(II+1) = NAST(II) + ITOT + ENDDO + DO II=1,ITGB + ITOT = 1 + DO JJ=1,NSPACE + ITOT = ITOT * LBNDET(JJ,II) + ENDDO + NBST(II+1) = NBST(II) + ITOT + ENDDO + ICOMP = 0 + CALL RESETCO(LBOX1,NSPACE,NA,IAMA,IAMI,LBOX3) + NA1EX = 0 + NB1EX = 0 + CALL RESETCO(LBOX1,NSPACE,NB,IBMA,IBMI,LBOX3) + DO IIB = 1,ITGB + CALL RESETDE(LBOX1,NSPACE,NB,MSTA,LCON) + DO KKB=NBST(IIB)+1,NBST(IIB+1) + DO II=1,NSPACE + LBOX2(II) = LBOX1(II) + ENDDO + IEBS = NB+1 + DO ISPB1=NSPACE,1,-1 + IOC1 = LBOX1(ISPB1) + IEBE = IEBS - 1 + IEBS = IEBS - IOC1 + LBOX2(ISPB1) = LBOX2(ISPB1)-1 + DO IB1=IEBE,IEBS,-1 + IO1 = LCON(IB1) + IGBE = IEBE - LBOX1(ISPB1) + DO ISPB2=ISPB1,NSPACE + IGBS = IGBE + 1 + IGBE = IGBE + LBOX1(ISPB2) + LBOX2(ISPB2) = LBOX2(ISPB2) + 1 + IGBA = MAX(IB1+1,IGBS) + DO IGAP=IGBA,IGBE+1 + DO JJ=ISTA,IEND + NB1EX = NB1EX + 1 + ENDDO + ISTA = LCON(IGAP)+1 + IEND = LCON(IGAP+1)-1 + IF (IGAP.EQ.IGBE) IEND=MSTA(ISPB2+1)-1 + ENDDO + LBOX2(ISPB2) = LBOX2(ISPB2) - 1 + ENDDO + ENDDO + LBOX2(ISPB1) = LBOX2(ISPB1) + 1 + ENDDO + CALL MOVEUP2(LBOX1,NSPACE,NB,MSTA,LCON) + ENDDO + CALL PUSHCO(LBOX1,NSPACE,NB,IBMA,IBMI,LBOX3,IEND) + ENDDO + RETURN + END