From patchwork Fri Dec 4 09:27:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrylo Tkachov X-Patchwork-Id: 57702 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp433540lbb; Fri, 4 Dec 2015 01:28:02 -0800 (PST) X-Received: by 10.98.2.197 with SMTP id 188mr19675453pfc.135.1449221281904; Fri, 04 Dec 2015 01:28:01 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id ht11si18275102pac.98.2015.12.04.01.28.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Dec 2015 01:28:01 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-416348-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-return-416348-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-416348-patch=linaro.org@gcc.gnu.org; dkim=pass header.i=@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=Y8nAkzrz1nUbXiwN+5FXYnU858PxeBoEyflwKqgLhLJ oHo+7YuVjcpEMAvfo3eOFhdeshhOirm40h3c+xOBBAFoQzXKNB3sVnh8S6d0rbxa d3ZeAGqeevlTUklFXDLcrKCIYRzCVr+75zty4n+tg2+gIHutj4WPGVkWEe2FixQU = 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 :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=r2Do/bjM++w+OqMrxKtCq5R2J2I=; b=WjJOZJamhs+4Ol8+w ulAgad0OoScqXg2OjQCpvc2682YnHYe0zEbJyfliR6ZvDdhM4ofYKAVxsXkf6Wnl pOuoZfzhhrpkPtBgYEIBV52CKLJMVlazzDURCSz9P6wX+jT71aed4b4vrT9xOMYG wA9f6DLwV4IDZckFTdAUEZvbFc= Received: (qmail 58081 invoked by alias); 4 Dec 2015 09:27:50 -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 58072 invoked by uid 89); 4 Dec 2015 09:27:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00, KAM_LOTSOFHASH, SPF_PASS autolearn=no version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 04 Dec 2015 09:27:48 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-10-RrBYIipiSZOM22CiLVmqZQ-1; Fri, 04 Dec 2015 09:27:43 +0000 Received: from [10.2.206.200] ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 4 Dec 2015 09:27:42 +0000 Message-ID: <56615C8E.8090307@arm.com> Date: Fri, 04 Dec 2015 09:27:42 +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/68214: Delete IP-reg-clobbering call-through-mem patterns X-MC-Unique: RrBYIipiSZOM22CiLVmqZQ-1 X-IsSubscribed: yes Hi all, The wrong-code in this PR occurs for pre-ARMv5 architectures with Thumb interworking when trying to use a static chain. Our output_call_mem function that outputs the assembly for the call explicitly clobbers the IP register, which is also used as the static chain register. Richard suggested offline that we can just remove the *call_mem and *call_value_mem patterns as they are of no use anymore and just cause us trouble such as this. The midend does a good enough job of figuring out it has to load the address to which we should branch. So this patch does that. It's an entirely negative diffstat :) For the failing testcase gcc.dg/cwsc1.c the bad code before this patch in the main function is: mov ip, r4 ldr r3, .L6 ldr ip, [r3] mov lr, pc bx ip and with this patch it is: ldr r3, .L6 ldr r3, [r3] mov ip, r4 mov lr, pc bx r3 As you can see it's correct and no less efficient than before. Bootstrapped and tested on arm-none-linux-gnueabihf and a test run with -mcpu=arm7tdmi didn't show any problems. Ok for trunk? Thanks, Kyrill 2015-12-04 Kyrylo Tkachov PR target/68214 * config/arm/arm.md (*call_mem): Delete pattern. (*call_value_mem): Likewise. * config/arm/arm.c (output_call_mem): Delete. * config/arm/arm-protos.h (output_call_mem): Delete prototype. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index e4b8fb3feda74d60e7f6628bb51b9d6d6a431e54..e7328e79650739fca1c3e21b10c194feaa697465 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -132,7 +132,6 @@ extern bool arm_const_double_by_parts (rtx); extern bool arm_const_double_by_immediates (rtx); extern void arm_emit_call_insn (rtx, rtx, bool); extern const char *output_call (rtx *); -extern const char *output_call_mem (rtx *); void arm_emit_movpair (rtx, rtx); extern const char *output_mov_long_double_arm_from_arm (rtx *); extern const char *output_move_double (rtx *, bool, int *count); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c1cfe83d3f0716837fd3f59399a0f6a92f33c67c..f822a92d2684030c60271cfd74a81772b096e151 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -18057,41 +18057,6 @@ output_call (rtx *operands) return ""; } -/* Output a 'call' insn that is a reference in memory. This is - disabled for ARMv5 and we prefer a blx instead because otherwise - there's a significant performance overhead. */ -const char * -output_call_mem (rtx *operands) -{ - gcc_assert (!arm_arch5); - if (TARGET_INTERWORK) - { - output_asm_insn ("ldr%?\t%|ip, %0", operands); - output_asm_insn ("mov%?\t%|lr, %|pc", operands); - output_asm_insn ("bx%?\t%|ip", operands); - } - else if (regno_use_in (LR_REGNUM, operands[0])) - { - /* LR is used in the memory address. We load the address in the - first instruction. It's safe to use IP as the target of the - load since the call will kill it anyway. */ - output_asm_insn ("ldr%?\t%|ip, %0", operands); - output_asm_insn ("mov%?\t%|lr, %|pc", operands); - if (arm_arch4t) - output_asm_insn ("bx%?\t%|ip", operands); - else - output_asm_insn ("mov%?\t%|pc, %|ip", operands); - } - else - { - output_asm_insn ("mov%?\t%|lr, %|pc", operands); - output_asm_insn ("ldr%?\t%|pc, %0", operands); - } - - return ""; -} - - /* Output a move from arm registers to arm registers of a long double OPERANDS[0] is the destination. OPERANDS[1] is the source. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 2dcd2ccf6dbc476dedeaacdd5bb906a040d1617c..2b48bbaf034b286d723536ec2aa6fe0f9b312911 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7709,23 +7709,6 @@ (define_insn "*call_reg_arm" ) -;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not -;; considered a function call by the branch predictor of some cores (PR40887). -;; Falls back to blx rN (*call_reg_armv5). - -(define_insn "*call_mem" - [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m")) - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)" - "* - return output_call_mem (operands); - " - [(set_attr "length" "12") - (set_attr "type" "call")] -) - (define_expand "call_value" [(parallel [(set (match_operand 0 "" "") (call (match_operand 1 "memory_operand" "") @@ -7789,23 +7772,6 @@ (define_insn "*call_value_reg_arm" (set_attr "type" "call")] ) -;; Note: see *call_mem - -(define_insn "*call_value_mem" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) - && !SIBLING_CALL_P (insn)" - "* - return output_call_mem (&operands[1]); - " - [(set_attr "length" "12") - (set_attr "type" "call")] -) - ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.