From patchwork Sat Jul 10 15:32:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 58487 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 6B3E6B6EF7 for ; Sun, 11 Jul 2010 01:32:54 +1000 (EST) Received: (qmail 5776 invoked by alias); 10 Jul 2010 15:32:51 -0000 Received: (qmail 5764 invoked by uid 22791); 10 Jul 2010 15:32:50 -0000 X-SWARE-Spam-Status: No, hits=-1.3 required=5.0 tests=AWL, BAYES_00, NO_DNS_FOR_FROM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 10 Jul 2010 15:32:46 +0000 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 10 Jul 2010 08:31:32 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([10.3.194.135]) by fmsmga001.fm.intel.com with ESMTP; 10 Jul 2010 08:32:37 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 500) id 636E021313; Sat, 10 Jul 2010 08:32:44 -0700 (PDT) Date: Sat, 10 Jul 2010 08:32:44 -0700 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Subject: [ix86/gcc-4_5-branch] PATCH: PR rtl-optimization/44659: Combiner fails to match QI cmp patterns with upper 8bit register Message-ID: <20100710153244.GA26276@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) 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, I backported this patch into ix86/gcc-4_5-branch. H.J. --- gcc/ 2010-07-09 H.J. Lu Backport from mainline 2010-06-29 Eric Botcazou PR rtl-optimization/44659 * combine.c (make_compound_operation) : Do not return the result of force_to_mode if it partially re-expanded the compound. gcc/testsuite/ 2010-07-09 H.J. Lu Backport from mainline 2010-06-29 H.J. Lu PR rtl-optimization/44659 * gcc.target/i386/extract-1.c: New. * gcc.target/i386/extract-2.c: Likewise. * gcc.target/i386/extract-3.c: Likewise. * gcc.target/i386/extract-4.c: Likewise. * gcc.target/i386/extract-5.c: Likewise. * gcc.target/i386/extract-6.c: Likewise. diff --git a/gcc/combine.c b/gcc/combine.c index a5240c9..bad2ff7 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7310,22 +7310,21 @@ make_compound_operation (rtx x, enum rtx_code in_code) /* Call ourselves recursively on the inner expression. If we are narrowing the object and it has a different RTL code from what it originally did, do this SUBREG as a force_to_mode. */ - - tem = make_compound_operation (SUBREG_REG (x), in_code); - { - rtx simplified = simplify_subreg (mode, tem, GET_MODE (SUBREG_REG (x)), - SUBREG_BYTE (x)); + rtx inner = SUBREG_REG (x), simplified; + + tem = make_compound_operation (inner, in_code); + simplified + = simplify_subreg (mode, tem, GET_MODE (inner), SUBREG_BYTE (x)); if (simplified) tem = simplified; - if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x)) - && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) + if (GET_CODE (tem) != GET_CODE (inner) + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner)) && subreg_lowpart_p (x)) { - rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0, - 0); + rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0, 0); /* If we have something other than a SUBREG, we might have done an expansion, so rerun ourselves. */ @@ -7333,9 +7332,16 @@ make_compound_operation (rtx x, enum rtx_code in_code) newer = make_compound_operation (newer, in_code); /* force_to_mode can expand compounds. If it just re-expanded the - compound use gen_lowpart instead to convert to the desired - mode. */ - if (rtx_equal_p (newer, x)) + compound, use gen_lowpart to convert to the desired mode. */ + if (rtx_equal_p (newer, x) + /* Likewise if it re-expanded the compound only partially. + This happens for SUBREG of ZERO_EXTRACT if they extract + the same number of bits. */ + || (GET_CODE (newer) == SUBREG + && (GET_CODE (SUBREG_REG (newer)) == LSHIFTRT + || GET_CODE (SUBREG_REG (newer)) == ASHIFTRT) + && GET_CODE (inner) == AND + && rtx_equal_p (SUBREG_REG (newer), XEXP (inner, 0)))) return gen_lowpart (GET_MODE (x), tem); return newer; diff --git a/gcc/testsuite/gcc.target/i386/extract-1.c b/gcc/testsuite/gcc.target/i386/extract-1.c new file mode 100644 index 0000000..102beb2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +int +foo (unsigned char x, unsigned char y) +{ + return (x % y) != 0; +} + +/* { dg-final { scan-assembler-not "test\[b\]?\[^\\n\]*%\[a-d\]l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-2.c b/gcc/testsuite/gcc.target/i386/extract-2.c new file mode 100644 index 0000000..3bb5f15 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +int +foo (unsigned char x, unsigned char y) +{ + return (x % y) > 4; +} + +/* { dg-final { scan-assembler-times "cmp\[b\]?\[^\\n\]*%\[a-d\]h" 1 } } */ +/* { dg-final { scan-assembler-not "cmp\[b\]?\[^\\n\]*%\[a-d\]l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-3.c b/gcc/testsuite/gcc.target/i386/extract-3.c new file mode 100644 index 0000000..520bf3b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-3.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +typedef struct +{ + unsigned char c1; + unsigned char c2; + unsigned char c3; + unsigned char c4; +} foo_t; + +int +#ifndef __x86_64__ +__attribute__((regparm(3))) +#endif +foo (foo_t x) +{ + return x.c2 != 0; +} + +/* { dg-final { scan-assembler-not "test\[b\]?\[^\\n\]*%\[a-z0-9\]+l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-4.c b/gcc/testsuite/gcc.target/i386/extract-4.c new file mode 100644 index 0000000..716ae22 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-4.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +typedef struct +{ + unsigned char c1; + unsigned char c2; + unsigned char c3; + unsigned char c4; +} foo_t; + +int +#ifndef __x86_64__ +__attribute__((regparm(3))) +#endif +foo (foo_t x) +{ + return x.c2 > 4; +} + +/* { dg-final { scan-assembler-times "cmp\[b\]?\[^\\n\]*%\[a-z0-9\]+h" 1 } } */ +/* { dg-final { scan-assembler-not "cmp\[b\]?\[^\\n\]*%\[a-z0-9\]+l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-5.c b/gcc/testsuite/gcc.target/i386/extract-5.c new file mode 100644 index 0000000..a488daf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-5.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +typedef struct +{ + unsigned int c1:8; + unsigned int c2:8; + unsigned int c3:8; + unsigned int c4:8; +} foo_t; + +int +#ifndef __x86_64__ +__attribute__((regparm(3))) +#endif +foo (foo_t x) +{ + return x.c2 != 0; +} + +/* { dg-final { scan-assembler-not "test\[b\]?\[^\\n\]*%\[a-z0-9\]+l" } } */ diff --git a/gcc/testsuite/gcc.target/i386/extract-6.c b/gcc/testsuite/gcc.target/i386/extract-6.c new file mode 100644 index 0000000..1440ec3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/extract-6.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +typedef struct +{ + unsigned int c1:8; + unsigned int c2:8; + unsigned int c3:8; + unsigned int c4:8; + +} foo_t; + +int +#ifndef __x86_64__ +__attribute__((regparm(3))) +#endif +foo (foo_t x) +{ + return x.c2 > 4; +} + +/* { dg-final { scan-assembler-times "cmp\[b\]?\[^\\n\]*%\[a-z0-9\]+h" 1 } } */ +/* { dg-final { scan-assembler-not "cmp\[b\]?\[^\\n\]*%\[a-z0-9\]+l" } } */