From patchwork Tue Jul 17 09:50:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 171367 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 2C4A82C01DE for ; Tue, 17 Jul 2012 19:51:20 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1343123481; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Subject:Message-ID:Reply-To: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=yRtV0iyJLgo1d0wV6EZf e/KQrto=; b=Bd9e5x7q+nQLgpzuWXi+8wG6Sfk2B5J20isLj8p5jfSR0Lv13khu +jRgKuTi7yKPaS0Hg/gTWEk8wCZcrAoE69GKLc8hXbD5zKvk4WyPo1GXVrLel+UO 255eDpQysDS9AUUk2Au8OnOWVcQumLGWbqWRHZGoJ53d16SnwbjqNmM= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Subject:Message-ID:Reply-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=itNdx9V69vVyczekHbGNXRu8fN7o5WQVAqgFvIddbNdh6HzUzzTbIjQ88QdU/9 6InqLN334OegP9hE1/NnD+tN/uIapEs9BquOmfJfbRDMtmeMLeeubJiJ/iR378dn A+BRFxBuVMF6Nz8tY/jvkunMYNQgpNuUFpwK27rSZYbZc=; Received: (qmail 21434 invoked by alias); 17 Jul 2012 09:51:08 -0000 Received: (qmail 21392 invoked by uid 22791); 17 Jul 2012 09:51:04 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, SPF_HELO_PASS, TW_FW, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 17 Jul 2012 09:50:47 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q6H9okij000654 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 17 Jul 2012 05:50:46 -0400 Received: from zalov.redhat.com (vpn1-6-86.ams2.redhat.com [10.36.6.86]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q6H9ojFs001548 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 17 Jul 2012 05:50:46 -0400 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.redhat.com (8.14.5/8.14.5) with ESMTP id q6H9oiZd029625 for ; Tue, 17 Jul 2012 11:50:44 +0200 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id q6H9oiK2029624 for gcc-patches@gcc.gnu.org; Tue, 17 Jul 2012 11:50:44 +0200 Date: Tue, 17 Jul 2012 11:50:43 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [PATCH] Avoid zext/sext directly from hard registers during expansion (PR rtl-optimization/53942) Message-ID: <20120717095043.GA9077@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 Hi! The following testcase ICEs on i?86, because combiner sees a zero extension of the likely spilled cx register generated during expansion and as it is not a simple register move, propagates it into a use many insns later in the function, enlarging thus the lifetime of the hard register and causing RA failure on a register in between the two that needs to use that particular hard register. cant_combine_insn_p only special cases simple register moves out of or into likely spilled hard registers. The following patch fixes it by using roughly the same condition to decide if it is ok to emit a zero or sign extension directly from the hard register or if it is better to first copy the hard register into a pseudo (then combiner (and fwprop etc.) seem to do the right thing). Bootstrapped/regtested on x86_64-linux and i686-linux, on both I've verified it doesn't affect code generation for cc1plus (appart from function.o obviously), libstdc++.so and libgcj.so. Ok for trunk (and perhaps after a while for the 4.7 branch)? 2012-07-17 Jakub Jelinek PR rtl-optimization/53942 * function.c (assign_parm_setup_reg): Avoid zero/sign extension directly from likely spilled non-fixed hard registers, move them to pseudo first. * gcc.dg/pr53942.c: New test. Jakub --- gcc/function.c.jj 2012-06-25 08:38:26.000000000 +0200 +++ gcc/function.c 2012-07-16 13:41:52.847928315 +0200 @@ -2988,11 +2988,26 @@ assign_parm_setup_reg (struct assign_par && insn_operand_matches (icode, 1, op1)) { enum rtx_code code = unsignedp ? ZERO_EXTEND : SIGN_EXTEND; - rtx insn, insns; + rtx insn, insns, t = op1; HARD_REG_SET hardregs; start_sequence (); - insn = gen_extend_insn (op0, op1, promoted_nominal_mode, + /* If op1 is a hard register that is likely spilled, first + force it into a pseudo, otherwise combiner might extend + its lifetime too much. */ + if (GET_CODE (t) == SUBREG) + t = SUBREG_REG (t); + if (REG_P (t) + && HARD_REGISTER_P (t) + && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (t)) + && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (t)))) + { + t = gen_reg_rtx (GET_MODE (op1)); + emit_move_insn (t, op1); + } + else + t = op1; + insn = gen_extend_insn (op0, t, promoted_nominal_mode, data->passed_mode, unsignedp); emit_insn (insn); insns = get_insns (); --- gcc/testsuite/gcc.dg/pr53942.c.jj 2012-06-15 19:53:34.312404791 +0200 +++ gcc/testsuite/gcc.dg/pr53942.c 2012-07-17 11:26:48.863053287 +0200 @@ -0,0 +1,34 @@ +/* PR rtl-optimization/53942 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-mtune=pentium2" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */ + +struct S +{ + unsigned short w[3]; + unsigned int x, y; +}; + +struct S *baz (void); + +__attribute__ ((noinline)) +static unsigned char +foo (struct S *x, unsigned char y) +{ + unsigned char c = 0; + unsigned char v = x->w[0]; + c |= v; + v = ((x->w[1]) & (1 << y)) ? 1 : 0; + c |= v << 1; + v = ((x->w[2]) & 0xff) & (1 << y); + c |= v << 2; + return c; +} + +void +bar (void) +{ + struct S *s = baz (); + s->x = foo (s, 6); + s->y = foo (s, 7); +}