From patchwork Tue May 15 19:39:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Meador Inge X-Patchwork-Id: 159425 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 7BC76B6FAA for ; Wed, 16 May 2012 05:39:50 +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=1337715591; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=ezlwTgq S+QT2+zw75ooJoo7MqtQ=; b=E6+FKrnJyYV0ccjbK+UOsro3I2TjHTaReKZVurZ 3zKnf9tCRD9chuICVu7VmJ+tvp/fVsj2yyp/jL8FDi4hzhIwbFdkRtZVXCPsnYGi X8L4JdQpAPa4Ot53z/nkyHcP3e4+dw3NGjs3PyVPled0tAqCnOxZVvebXow8TloE q4r8= 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:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=lguR3sXi24i3pwMwPu42HLyhGbkVM+h87zKzkNSfqTUjVCCQMEiph1afbxcLOE jT4QdStYYpYxHijihx8OW6bGOczRzNIjqzNvotpUFkqgphhDyAUL7qJQeH87yjLV nw+JShOMQbOeKKJWsk1dOPsZJ3odjtEcUPRWos1LsWqPE=; Received: (qmail 26927 invoked by alias); 15 May 2012 19:39:46 -0000 Received: (qmail 26917 invoked by uid 22791); 15 May 2012 19:39:45 -0000 X-SWARE-Spam-Status: No, hits=-3.6 required=5.0 tests=AWL, BAYES_00, FROM_12LTRDOM, KHOP_RCVD_UNTRUST, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 15 May 2012 19:39:32 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1SUNal-0002qk-Ho from meador_inge@mentor.com for gcc-patches@gcc.gnu.org; Tue, 15 May 2012 12:39:31 -0700 Received: from SVR-ORW-FEM-05.mgc.mentorg.com ([147.34.97.43]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Tue, 15 May 2012 12:39:16 -0700 Received: from [IPv6:::1] (147.34.91.1) by svr-orw-fem-05.mgc.mentorg.com (147.34.97.43) with Microsoft SMTP Server id 14.1.289.1; Tue, 15 May 2012 12:39:30 -0700 Message-ID: <4FB2B0F1.40601@codesourcery.com> Date: Tue, 15 May 2012 14:39:29 -0500 From: Meador Inge User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120424 Thunderbird/12.0 MIME-Version: 1.0 To: Subject: [PATCH] PR rtl-optimization/53352 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 All, As reported in PR rtl-optimization/53352 CSE currently trips up on a paradoxical subreg case. When compiling for ARM GNU/Linux with -O3 the expanded RTL of interest looks like: (insn 12 11 13 3 (set (reg:SI 140) (lshiftrt:SI (reg/v:SI 135 [ tmp1 ]) (const_int 16 [0x10]))) (nil)) (insn 13 12 14 3 (set (reg:QI 141) (subreg:QI (reg:SI 140) 0)) (nil)) (insn 14 13 15 3 (set (reg:SI 142) (subreg:SI (reg:QI 141) 0)) (nil)) (insn 15 14 16 3 (set (reg:SI 134 [ tmp1$2 ]) (and:SI (reg:SI 142) (const_int 255 [0xff]))) (nil)) ... (insn 29 28 30 3 (set (reg:SI 0 r0) (const_int 0 [0])) (nil)) after "cse1" things look like: (insn 12 11 13 2 (set (reg:SI 140) (const_int 65280 [0xff00])) (nil)) (insn 13 12 14 2 (set (reg:QI 141) (subreg:QI (reg:SI 140) 0)) (expr_list:REG_EQUAL (const_int 0 [0]) (nil))) ;; This is *not* equal to zero because the upper ;; two bytes are undefined. (insn 14 13 15 2 (set (reg:SI 142) (subreg:SI (reg:QI 141) 0)) (expr_list:REG_EQUAL (const_int 0 [0]) (nil))) (insn 15 14 16 2 (set (reg:SI 134 [ tmp1$2 ]) (reg:SI 142)) (expr_list:REG_EQUAL (const_int 0 [0]) (nil))) ... (insn 29 28 30 2 (set (reg:SI 0 r0) (reg:SI 142)) (expr_list:REG_EQUAL (const_int 0 [0]) (nil))) I believe the REG_EQUAL note on the set involving a paradoxical subreg is incorrect. It eventually causes 0xFF00 to be passed to the function 'foo'. The attached patch fixes the issue by skipping the paradoxical subreg in 'equiv_constant'. Compiler bootstrapped for i686-pc-linux-gnu and full GCC test runs for i686-pc-linux-gnu and arm-none-linux-gnueabi (no regressions). OK? (If this is OK, then can someone commit for me. I don't have write access). gcc/ 2012-05-15 Meador Inge PR rtl-optimization/53352 * cse.c (equiv_constant): Ignore paradoxical subregs. gcc/testsuite/ 2012-05-15 Meador Inge PR rtl-optimization/53352 * gcc.dg/pr53352.c: New test. Index: gcc/testsuite/gcc.dg/pr53352.c =================================================================== --- gcc/testsuite/gcc.dg/pr53352.c (revision 0) +++ gcc/testsuite/gcc.dg/pr53352.c (revision 0) @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +#include + +typedef union +{ + struct + { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + } parts; + unsigned long whole; +} T; + +T *g_t; + +void bar (unsigned long x) +{ + if (x != 0) + abort (); +} + +int main () +{ + T one; + T two; + T tmp1, tmp2; + + one.whole = 0xFFE0E0E0; + two.whole = 0xFF000000; + tmp1.parts = two.parts; + tmp2.parts = one.parts; + tmp2.parts.c = tmp1.parts.c; + one.parts = tmp2.parts; + + g_t = &one; + bar (0); +} Index: gcc/cse.c =================================================================== --- gcc/cse.c (revision 187470) +++ gcc/cse.c (working copy) @@ -3786,8 +3786,11 @@ equiv_constant (rtx x) } } - /* Otherwise see if we already have a constant for the inner REG. */ + /* Otherwise see if we already have a constant for the inner REG. + Don't bother with paradoxical subregs because we have no way + of knowing what the upper bytes are. */ if (REG_P (SUBREG_REG (x)) + && (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (imode)) && (new_rtx = equiv_constant (SUBREG_REG (x))) != 0) return simplify_subreg (mode, new_rtx, imode, SUBREG_BYTE (x));