From patchwork Wed Aug 25 17:09:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 62726 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 22A16B70CC for ; Thu, 26 Aug 2010 03:08:41 +1000 (EST) Received: (qmail 8367 invoked by alias); 25 Aug 2010 17:08:36 -0000 Received: (qmail 8288 invoked by uid 22791); 25 Aug 2010 17:08:35 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, 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; Wed, 25 Aug 2010 17:08:28 +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.13.8/8.13.8) with ESMTP id o7PH8QAM000578 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 25 Aug 2010 13:08:27 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7PH8PwZ024440 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 25 Aug 2010 13:08:26 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id o7PH99Ac031125; Wed, 25 Aug 2010 19:09:09 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id o7PH99Vd031123; Wed, 25 Aug 2010 19:09:09 +0200 Date: Wed, 25 Aug 2010 19:09:09 +0200 From: Jakub Jelinek To: Ian Lance Taylor , Richard Guenther Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix combiner when optimizing 3 insns into 2 (PR rtl-optimization/44858) Message-ID: <20100825170909.GX702@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) 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! When recog_for_combine needs to add some clobbers to newi2pat here, it might prevent the insns from being emitted in that order, if newpat depends on the content of the clobbered registers. On the testcase we have: (parallel [ (set (reg:SI 71) (ne:SI (reg:CCZ 17 flags) (const_int 0 [0]))) (set (reg/v:SI 62 [ c ]) (and:SI (reg:SI 68) (const_int 2 [0x2]))) ]) which doesn't match, so we try to split it into 2 insns. The comment says, except for HAVE_cc0 targets it usually doesn't matter much in which order we emit the two insns and thus it tries to emit the and in i2 and != in i3. But for the and it adds flags CLOBBER, so the != which depends on flags sees a clobbered value. The patch below in that case tries to swap the two insns if possible (it is in this case) and only gives up if neither order works. Bootstrapped/regtested on x86_64-linux and i686-linux. Ok for trunk/4.5? 2010-08-25 Jakub Jelinek PR rtl-optimization/44858 * combine.c (try_combine): If recog_for_combine added CLOBBERs to newi2pat, make sure they don't affect newpat. * gcc.c-torture/execute/pr44858.c: New test. Jakub --- gcc/combine.c.jj 2010-08-20 16:05:41.000000000 +0200 +++ gcc/combine.c 2010-08-25 15:40:07.000000000 +0200 @@ -3725,7 +3725,58 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); if (i2_code_number >= 0) - insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); + { + /* recog_for_combine might have added CLOBBERs to newi2pat. + Make sure NEWPAT does not depend on the clobbered regs. */ + if (GET_CODE (newi2pat) == PARALLEL) + { + for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--) + if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER) + { + rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0); + if (reg_overlap_mentioned_p (reg, newpat)) + break; + } + + if (i >= 0) + { + /* CLOBBERs on newi2pat prevent it going first. + Try the other order of the insns if possible. */ + temp = newpat; + newpat = XVECEXP (newi2pat, 0, 0); + newi2pat = temp; +#ifdef HAVE_cc0 + if (reg_referenced_p (cc0_rtx, newpat)) + { + undo_all (); + return 0; + } +#endif + + i2_code_number = recog_for_combine (&newi2pat, i2, + &new_i2_notes); + if (i2_code_number < 0) + { + undo_all (); + return 0; + } + + if (GET_CODE (newi2pat) == PARALLEL) + for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--) + if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER) + { + rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0); + if (reg_overlap_mentioned_p (reg, newpat)) + { + undo_all (); + return 0; + } + } + } + } + + insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); + } } /* If it still isn't recognized, fail and change things back the way they --- gcc/testsuite/gcc.c-torture/execute/pr44858.c.jj 2010-08-25 15:10:01.000000000 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr44858.c 2010-08-25 15:09:06.000000000 +0200 @@ -0,0 +1,28 @@ +/* PR rtl-optimization/44858 */ + +extern void abort (void); +int a = 3; +int b = 1; + +__attribute__((noinline)) long long +foo (int x, int y) +{ + return x / y; +} + +__attribute__((noinline)) int +bar (void) +{ + int c = 2; + c &= foo (1, b) > b; + b = (a != 0) | c; + return c; +} + +int +main (void) +{ + if (bar () != 0 || b != 1) + abort (); + return 0; +}