From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12024 invoked by alias); 7 Apr 2016 14:51:54 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 11948 invoked by uid 89); 7 Apr 2016 14:51:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=TST X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Apr 2016 14:51:43 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 29F6828; Thu, 7 Apr 2016 07:50:30 -0700 (PDT) Received: from [10.2.206.200] (e100706-lin.cambridge.arm.com [10.2.206.200]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B2AAD3F25E; Thu, 7 Apr 2016 07:51:40 -0700 (PDT) Message-ID: <570673FB.7020803@foss.arm.com> Date: Thu, 07 Apr 2016 14:51:00 -0000 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches CC: Ramana Radhakrishnan , Richard Earnshaw Subject: [PATCH][ARM] PR target/70566 Check that condition register is dead in tst-imm -> lsls-imm Thumb2 peepholes Content-Type: multipart/mixed; boundary="------------040607030200040907080709" X-SW-Source: 2016-04/txt/msg00351.txt.bz2 This is a multi-part message in MIME format. --------------040607030200040907080709 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1471 Hi all, In this wrong-code PR we have a Thumb2 peephole transforming: tst r3, #2 bne .L3 beq .L6 into: lsls r3, r3, #30 // LSLS is shorter than TST in Thumb2 bmi .L3 beq .L6 that is, the branch following the extract+compare has its condition properly changed but the following branch doesn't get updated to check the opposite condition of MI (PL). Since the peepholes in thumb2.md only see the compare and a single branch the solution, suggested by Richard, is to guard those peepholes on the condition that the condition register is dead after the first branch. This patch does that and with it we no longer perform the transformation on the testcase. I've checked manually that we still perform the peephole when the condition register is indeed dead after the sequence. Bootstrapped and tested on on arm-none-linux-gnueabihf with --with-mode=thumb as this affects only Thumb2 codegen. Ok for trunk? This PR also affects GCC 5 and 4.9 so I'll be testing the patch there as well. Thanks, Kyrill 2016-04-07 Kyrylo Tkachov PR target/70566 * config/arm/thumb2.md (tst + branch-> lsls + branch peephole below *orsi_not_shiftsi_si): Require that condition register is dead after the peephole. (second peephole after the above): Likewise. 2016-04-07 Kyrylo Tkachov PR target/70566 * gcc.c-torture/execute/pr70566.c: New test. --------------040607030200040907080709 Content-Type: text/x-patch; name="arm-peepholes.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="arm-peepholes.patch" Content-length: 2024 diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 992536593d6c0a8b8fe5a324f32e279c69746157..ab08288413c3e64911e8d7a8199b9809e0282d8e 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -1550,7 +1550,8 @@ (define_peephole2 (match_operand 5 "" "") (match_operand 6 "" "")))] "TARGET_THUMB2 - && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)" + && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32) + && peep2_reg_dead_p (2, operands[0])" [(parallel [(set (match_dup 0) (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) (const_int 0))) @@ -1578,7 +1579,8 @@ (define_peephole2 (match_operand 5 "" "") (match_operand 6 "" "")))] "TARGET_THUMB2 - && (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 32)" + && (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 32) + && peep2_reg_dead_p (2, operands[0])" [(parallel [(set (match_dup 0) (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) (const_int 0))) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70566.c b/gcc/testsuite/gcc.c-torture/execute/pr70566.c new file mode 100644 index 0000000000000000000000000000000000000000..f47106e70c7d4d7f3623f9505c02445a63332a9d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr70566.c @@ -0,0 +1,47 @@ +/* PR target/70566. */ + +#define NULL 0 + +struct mystruct +{ + unsigned int f1 : 1; + unsigned int f2 : 1; + unsigned int f3 : 1; +}; + +__attribute__ ((noinline)) void +myfunc (int a, void *b) +{ +} +__attribute__ ((noinline)) int +myfunc2 (void *a) +{ + return 0; +} + +static void +set_f2 (struct mystruct *user, int f2) +{ + if (user->f2 != f2) + myfunc (myfunc2 (NULL), NULL); + else + __builtin_abort (); +} + +__attribute__ ((noinline)) void +foo (void *data) +{ + struct mystruct *user = data; + if (!user->f2) + set_f2 (user, 1); +} + +int +main (void) +{ + struct mystruct a; + a.f1 = 1; + a.f2 = 0; + foo (&a); + return 0; +} --------------040607030200040907080709--