From patchwork Thu Jan 4 13:58:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Richard Earnshaw \(lists\)" X-Patchwork-Id: 123425 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp11461356qgn; Thu, 4 Jan 2018 05:59:58 -0800 (PST) X-Google-Smtp-Source: ACJfBouxyjy5q9yVUkAw3gwP40kTfBVkww3Q2qMHSFb74OSMSxBWKa2ggvu2APHVHnGPvz3FKxQq X-Received: by 10.98.133.155 with SMTP id m27mr4847389pfk.69.1515074397901; Thu, 04 Jan 2018 05:59:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515074397; cv=none; d=google.com; s=arc-20160816; b=sSWWKntNkVwzstzLroJx/V8u4Y/DSGufTRhPU3n28MnAA6cYkeFOUi6XE/2ZVEpNaW fcHRT7aHpptPxrxjGGs4Qn8c3utdgqBF6LLklFFCthshECJWyShsr7X2BNaWe08cSXVH 65QFT02RH8dhrxVSU1rYMjuLfeU+/ZzlcCBhLfbZ3zKcMq4tI7Iqrq/ecdlKsPnhkQ7/ 1tymbzSv8kGo4cuyKjfGm0ITXL/nU+tp9J0go1u3arHXf0LakxHKEeBWdgD9WUYUNQHx Fd9PdL1i/GAn73AI79wLGQiphbvQMkNijMxegtsqIyBKFSR3P/3W5oQTwGF+k0KYtT+q hy5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:references:in-reply-to:references:in-reply-to :message-id:date:subject:cc:to:from:delivered-to:sender:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=Rhfez/b+dKlnElHxDMHZSrMCRxnT7i2n9tDWK6/eM5w=; b=L8zdClWhE1/U8v0UCkXhatyxZsGMUEhk+g//d8IgGhzNcGesuV/dkMCnP0M0PDL0aH BZbfbL5liHWWcPs20THbhK0Qhjptf8oQoVx9KJTHi8fc3IE4EALHCocXhWn/bU0gRFQp bosFysdnspZH4q6fFU9JSG8Ms9yNhoG+x+0K7dsGSZ4lh6uLRbmtLSe0yqDKn7sKSqi4 wTD1bZq+amsR3+9uMke9S8NYi8X7yzhjASSZkIgw2La/AEU2IZGn8pN/0y1+5NgN1A3J P7OsCG59pAcRnyF8mcUpoZVur6SduqTmi4cq67kwOYDxTyUJ7kDa/JEZfZRqKQDB4IOw Ne/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=ZL+spZLk; spf=pass (google.com: domain of gcc-patches-return-470137-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-470137-patch=linaro.org@gcc.gnu.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id a10si2093518pgq.278.2018.01.04.05.59.57 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 04 Jan 2018 05:59:57 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-470137-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; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=ZL+spZLk; spf=pass (google.com: domain of gcc-patches-return-470137-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-470137-patch=linaro.org@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:from :to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references:mime-version:content-type; q=dns; s= default; b=kaBXRa7huvqyPblF2CHLNmUI6FXV0A8TGfZ1yukhGv0Z35NAwTKJU ZA6SLlLf2x4o0Twg4z1ECnO7uBA3b4z9JMvYw3FA+XPAAbJZhbNTFvKaxgwfJcgc ht1HxrW5sXg2js8L8am4H3hdH/Mb08cSCfL+4s201Y4nBTH/bTYuxg= 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:from :to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references:mime-version:content-type; s=default; bh=oOfvSiRzhd2Mna63x8qBWucNTZc=; b=ZL+spZLk8fC23Ihoa/Bn3hzMaY+K 2DhTNOEumYY68Pm+WQCpr1ZbFPz8eXtbM8GuucCsoSRksWIxswa0Z8Bxu4VNbXLu LMV6VulgFoUfcFXDUr4dRStcYcqr+ldLtLz0qHNaXDTxS+97XyDykdvr0M8Ea5Tq P7kUV8MHzmYoqy0= Received: (qmail 88286 invoked by alias); 4 Jan 2018 13:59:01 -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 88036 invoked by uid 89); 4 Jan 2018 13:58:59 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=multimedia, Multimedia, vec-common.md, UD:vec-common.md 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, 04 Jan 2018 13:58:56 +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 AD1FE15BE; Thu, 4 Jan 2018 05:58:55 -0800 (PST) Received: from e105689-lin.cambridge.arm.com (e105689-lin.cambridge.arm.com [10.2.207.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E507E3F581; Thu, 4 Jan 2018 05:58:54 -0800 (PST) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 3/3] [arm] Implement support for the de-speculation intrinsic Date: Thu, 4 Jan 2018 13:58:43 +0000 Message-Id: <26f1fd261a467d6b43e1d77085dfb0e169782cf7.1515072356.git.Richard.Earnshaw@arm.com> In-Reply-To: References: In-Reply-To: References: MIME-Version: 1.0 This patch implements despeculation on ARM. We only support it when generating ARM or Thumb2 code (we need conditional execution); and we only support it for sizes up to DImode. For unsupported cases we fall back to the generic code generation sequence so that a suitable failure warning is emitted. * config/arm/arm.c (arm_inhibit_load_speculation): New function (TARGET_INHIBIT_LOAD_SPECULATION): Redefine. * config/arm/unspec.md (VUNSPEC_NOSPECULATE): New unspec_volatile code. * config/arm/arm.md (cmp_ior): Make this pattern callable. (nospeculate, nospeculatedi): New patterns. --- gcc/config/arm/arm.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/config/arm/arm.md | 40 ++++++++++++++++- gcc/config/arm/unspecs.md | 1 + 3 files changed, 147 insertions(+), 1 deletion(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 11e35ad..d1fc0b9 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -321,6 +321,8 @@ static unsigned int arm_hard_regno_nregs (unsigned int, machine_mode); static bool arm_hard_regno_mode_ok (unsigned int, machine_mode); static bool arm_modes_tieable_p (machine_mode, machine_mode); static HOST_WIDE_INT arm_constant_alignment (const_tree, HOST_WIDE_INT); +static rtx arm_inhibit_load_speculation (machine_mode, rtx, rtx, rtx, rtx, + rtx, rtx); /* Table of machine attributes. */ static const struct attribute_spec arm_attribute_table[] = @@ -804,6 +806,9 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_CONSTANT_ALIGNMENT #define TARGET_CONSTANT_ALIGNMENT arm_constant_alignment + +#undef TARGET_INHIBIT_LOAD_SPECULATION +#define TARGET_INHIBIT_LOAD_SPECULATION arm_inhibit_load_speculation /* Obstack for minipool constant handling. */ static struct obstack minipool_obstack; @@ -31523,6 +31528,108 @@ arm_constant_alignment (const_tree exp, HOST_WIDE_INT align) return align; } +static rtx +arm_inhibit_load_speculation (machine_mode mode, rtx result, rtx mem, + rtx lower_bound, rtx upper_bound, + rtx fail_result, rtx cmpptr) +{ + rtx cond, comparison; + + /* We can't support this for Thumb1 as we have no suitable conditional + move operations. Nor do we support it for TImode. For both + these cases fall back to the generic code sequence which will emit + a suitable warning for us. */ + if (mode == TImode || TARGET_THUMB1) + return default_inhibit_load_speculation (mode, result, mem, lower_bound, + upper_bound, fail_result, cmpptr); + + + rtx target = gen_reg_rtx (mode); + rtx tgt2 = result; + + if (!register_operand (tgt2, mode)) + tgt2 = gen_reg_rtx (mode); + +if (!register_operand (cmpptr, ptr_mode)) + cmpptr = force_reg (ptr_mode, cmpptr); + + if (upper_bound == NULL) + { + if (!register_operand (lower_bound, ptr_mode)) + lower_bound = force_reg (ptr_mode, lower_bound); + + cond = arm_gen_compare_reg (LTU, cmpptr, lower_bound, NULL); + comparison = gen_rtx_LTU (VOIDmode, cond, const0_rtx); + } + else if (lower_bound == NULL) + { + if (!register_operand (upper_bound, ptr_mode)) + upper_bound = force_reg (ptr_mode, upper_bound); + + cond = arm_gen_compare_reg (GEU, cmpptr, upper_bound, NULL); + comparison = gen_rtx_GEU (VOIDmode, cond, const0_rtx); + } + else + { + /* We want to generate code for + result = (cmpptr < lower || cmpptr >= upper) ? 0 : *ptr; + Which can be recast to + result = (cmpptr < lower || upper <= cmpptr) ? 0 : *ptr; + which can be implemented as + cmp cmpptr, lower + cmpcs upper, cmpptr + bls 1f + ldr result, [ptr] + 1: + movls result, #0 + with suitable IT instructions as needed for thumb2. Later + optimization passes may make the load conditional. */ + + if (!register_operand (lower_bound, ptr_mode)) + lower_bound = force_reg (ptr_mode, lower_bound); + + if (!register_operand (upper_bound, ptr_mode)) + upper_bound = force_reg (ptr_mode, upper_bound); + + rtx comparison1 = gen_rtx_LTU (SImode, cmpptr, lower_bound); + rtx comparison2 = gen_rtx_LEU (SImode, upper_bound, cmpptr); + cond = gen_rtx_REG (arm_select_dominance_cc_mode (comparison1, + comparison2, + DOM_CC_X_OR_Y), + CC_REGNUM); + emit_insn (gen_cmp_ior (cmpptr, lower_bound, upper_bound, cmpptr, + comparison1, comparison2, cond)); + comparison = gen_rtx_NE (SImode, cond, const0_rtx); + } + + rtx_code_label *label = gen_label_rtx (); + emit_jump_insn (gen_arm_cond_branch (label, comparison, cond)); + emit_move_insn (target, mem); + emit_label (label); + + insn_code icode; + + switch (mode) + { + case E_QImode: icode = CODE_FOR_nospeculateqi; break; + case E_HImode: icode = CODE_FOR_nospeculatehi; break; + case E_SImode: icode = CODE_FOR_nospeculatesi; break; + case E_DImode: icode = CODE_FOR_nospeculatedi; break; + default: + gcc_unreachable (); + } + + if (! insn_operand_matches (icode, 4, fail_result)) + fail_result = force_reg (mode, fail_result); + + emit_insn (GEN_FCN (icode) (tgt2, comparison, cond, target, fail_result)); + + if (tgt2 != result) + emit_move_insn (result, tgt2); + + return result; +} + #if CHECKING_P namespace selftest { diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index d60c5af..e700fdf 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -9488,7 +9488,7 @@ (set_attr "type" "multiple")] ) -(define_insn "*cmp_ior" +(define_insn "cmp_ior" [(set (match_operand 6 "dominant_cc_register" "") (compare (ior:SI @@ -12015,6 +12015,44 @@ [(set_attr "length" "4") (set_attr "type" "coproc")]) +(define_insn "nospeculate" + [(set (match_operand:QHSI 0 "s_register_operand" "=l,l,r") + (unspec_volatile:QHSI + [(match_operator 1 "arm_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)]) + (match_operand:QHSI 3 "s_register_operand" "0,0,0") + (match_operand:QHSI 4 "arm_not_operand" "I,K,r")] + VUNSPEC_NOSPECULATE))] + "TARGET_32BIT" + { + if (TARGET_THUMB) + return \"it\\t%d1\;mov%d1\\t%0, %4\;.inst 0xf3af8014\t%@ CSDB\"; + return \"mov%d1\\t%0, %4\;.inst 0xe320f014\t%@ CSDB\"; + } + [(set_attr "type" "mov_imm,mvn_imm,mov_reg") + (set_attr "conds" "use") + (set_attr "length" "8")] +) + +(define_insn "nospeculatedi" + [(set (match_operand:DI 0 "s_register_operand" "=r") + (unspec_volatile:DI + [(match_operator 1 "arm_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)]) + (match_operand:DI 3 "s_register_operand" "0") + (match_operand:DI 4 "arm_rhs_operand" "rI")] + VUNSPEC_NOSPECULATE))] + "TARGET_32BIT" + { + if (TARGET_THUMB) + return \"it\\t%d1\;mov%d1\\t%Q0, %Q4\;it\\t%d1\;mov%d1\\t%R0, %R4\;.inst 0xf3af8014\t%@ CSDB\"; + return \"mov%d1\\t%Q0, %Q4\;mov%d1\\t%R0, %R4\;.inst 0xe320f014\t%@ CSDB\"; + } + [(set_attr "type" "mov_reg") + (set_attr "conds" "use") + (set_attr "length" "12")] +) + ;; Vector bits common to IWMMXT and Neon (include "vec-common.md") ;; Load the Intel Wireless Multimedia Extension patterns diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index c474f4b..727a5ab 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -168,6 +168,7 @@ VUNSPEC_MCRR2 ; Represent the coprocessor mcrr2 instruction. VUNSPEC_MRRC ; Represent the coprocessor mrrc instruction. VUNSPEC_MRRC2 ; Represent the coprocessor mrrc2 instruction. + VUNSPEC_NOSPECULATE ; Represent a despeculation sequence. ]) ;; Enumerators for NEON unspecs.