From patchwork Thu May 2 17:35:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 241044 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id CC66C2C00B1 for ; Fri, 3 May 2013 03:36:16 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=fRLV1HWJ+lcBmEm79/vMbdiO0YNVR PIFimt/zcDMd22tIEcR5g/2uECJ1Y1jDbBiDNXKjVAvkypiaZ0HM8wuH+4buSqbL ws8sBQAJqMvoaPwRrjXj755e/hHfS8bcumlcQRndl+oj/zUAlkJhd42kfey1t/08 yiVRX8xHFIH7Yk= 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:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=KpQvQmYvEOvDnnJKWQczvepsm6U=; b=RSz BGgkJuqgy6McGOeA6571nabS6wVxAmpCElqH9uHmCgB55J4TXZmHhSk4tA5o+m07 9zjOFiOEVG9uEb7beKL9Eh0gClFsX9xlrgo0GNqc4QGed2SUTI5OPT3u95ZWWLJk i1A3sZLBZF07FQOjxTFzwZlVb9QL1OhX+1hVo+aE= Received: (qmail 1750 invoked by alias); 2 May 2013 17:36:09 -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 1737 invoked by uid 89); 2 May 2013 17:36:08 -0000 X-Spam-SWARE-Status: No, score=-5.5 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 02 May 2013 17:36:07 +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 r42Ha3uO013354 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 2 May 2013 13:36:03 -0400 Received: from zalov.cz (vpn-58-7.rdu2.redhat.com [10.10.58.7]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r42Ha1JB020072 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 2 May 2013 13:36:03 -0400 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.cz (8.14.5/8.14.5) with ESMTP id r42Ha01d015475; Thu, 2 May 2013 19:36:00 +0200 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id r42HZwcm015474; Thu, 2 May 2013 19:35:58 +0200 Date: Thu, 2 May 2013 19:35:56 +0200 From: Jakub Jelinek To: Eric Botcazou Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix up make_compound_operation (PR rtl-optimization/57130) Message-ID: <20130502173556.GX28963@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi! As described in the PR, in some cases it is unsafe for make_compound_operation, if called with in_code == COMPARE, to pass through that value to make_compound_operation on the SUBREG_REG of a SUBREG. My understanding is that in_code == COMPARE (as opposed to in_code == SET) is mostly harmless, just tells make_extraction to no longer special case zero extraction at position 0, but there is one exception - AND with constant power of two CONST_INT. If we have make_compound_operation ( (subreg:SI (and:DI (reg:DI) (const_int 0x800000000)) 0), COMPARE) then make_compound_operation ( (and:DI (reg:DI) (const_int 0x800000000)), COMPARE) returns extraction of the 35th bit, and subreg of that is again either zero or one, but the original subreg is always 0. Fixed by passing through SET instead of in_code to the recursive invocation, if 1) the subreg isn't lowpart 2) nested SUBREGs (should be usually simplified, but just in case it hasn't been yet) 3) if subreg's operand is AND with power of two CONST_INT above the bitsize of the outer mode Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8? 2013-05-02 Jakub Jelinek PR rtl-optimization/57130 * combine.c (make_compound_operation): For SUBREG, pass SET instead of COMPARE as in_code to the recursive call if needed. * gcc.c-torture/execute/pr57130.c: New test. Jakub --- gcc/combine.c.jj 2013-04-11 09:09:39.000000000 +0200 +++ gcc/combine.c 2013-05-02 12:46:07.540196281 +0200 @@ -7697,8 +7697,24 @@ make_compound_operation (rtx x, enum rtx what it originally did, do this SUBREG as a force_to_mode. */ { rtx inner = SUBREG_REG (x), simplified; - - tem = make_compound_operation (inner, in_code); + enum rtx_code subreg_code = in_code; + + /* If in_code is COMPARE, it isn't always safe to pass it through + to the recursive make_compound_operation call. */ + if (subreg_code == COMPARE + && (!subreg_lowpart_p (x) + || GET_CODE (inner) == SUBREG + /* (subreg:SI (and:DI (reg:DI) (const_int 0x800000000)) 0) + is (const_int 0), rather than + (subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0). */ + || (GET_CODE (inner) == AND + && CONST_INT_P (XEXP (inner, 1)) + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner)) + && exact_log2 (UINTVAL (XEXP (inner, 1))) + >= GET_MODE_BITSIZE (mode)))) + subreg_code = SET; + + tem = make_compound_operation (inner, subreg_code); simplified = simplify_subreg (mode, tem, GET_MODE (inner), SUBREG_BYTE (x)); --- gcc/testsuite/gcc.c-torture/execute/pr57130.c.jj 2013-05-02 10:52:00.389263977 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr57130.c 2013-05-02 10:51:45.000000000 +0200 @@ -0,0 +1,21 @@ +/* PR rtl-optimization/57130 */ + +struct S { int a, b, c, d; } s[2] = { { 6, 8, -8, -5 }, { 0, 2, -1, 2 } }; + +__attribute__((noinline, noclone)) void +foo (struct S r) +{ + static int cnt; + if (__builtin_memcmp (&r, &s[cnt++], sizeof r) != 0) + __builtin_abort (); +} + +int +main () +{ + struct S r = { 6, 8, -8, -5 }; + foo (r); + r = (struct S) { 0, 2, -1, 2 }; + foo (r); + return 0; +}