From patchwork Wed Sep 16 07:40:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Greenhalgh X-Patchwork-Id: 53714 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by patches.linaro.org (Postfix) with ESMTPS id 008AF22DB2 for ; Wed, 16 Sep 2015 07:41:17 +0000 (UTC) Received: by lamp12 with SMTP id p12sf69524329lam.2 for ; Wed, 16 Sep 2015 00:41:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mailing-list:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:sender :delivered-to:from:to:cc:subject:date:message-id:mime-version :content-type:x-original-sender:x-original-authentication-results; bh=HPmADYy64Ns4Wxse4FqNUmKfaXpt1zDqZajdscZYHQY=; b=jQxC18cSGm0ksBHDudCizg24us5ChI8pAN0S/zjeuAq3MPukoAHxIvgdb7MpTONoG9 JlizLhM7rEweTiNqobnlGagEXAvXbYdO/mYRH83BIDyXPIw4rHSo1LFDTCZm0a4/UtCn +hjO3IfL57EfI4u53ZO0Net9lXisIDEkfYmNcg1FFKX7bH4abKXJQxHNVLIfwSrG43X7 MunEGAKNc4K/2cQxaAS+EE035WxlboYwdNfz1a52Qp7Ksz0K5SBtYPT2LA3oCoGawG69 Sz040HJipB1ZTGRHDiGOlyKll1OzYMIlAQhVjEDKuTvDRxmGN36Frg1Ey9ragmfOve35 Libw== X-Gm-Message-State: ALoCoQn3xyVreRcqRtVNf2a8g7xsnoI1nuKMsmWjWZeX4yo03SqJPJ/3ysxvAkugogAX8YBbKBOc X-Received: by 10.180.99.196 with SMTP id es4mr1647422wib.1.1442389275938; Wed, 16 Sep 2015 00:41:15 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.22.137 with SMTP id d9ls944778laf.42.gmail; Wed, 16 Sep 2015 00:41:15 -0700 (PDT) X-Received: by 10.152.4.39 with SMTP id h7mr21654802lah.99.1442389275742; Wed, 16 Sep 2015 00:41:15 -0700 (PDT) Received: from mail-la0-x232.google.com (mail-la0-x232.google.com. [2a00:1450:4010:c03::232]) by mx.google.com with ESMTPS id da5si16487427lac.26.2015.09.16.00.41.15 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2015 00:41:15 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c03::232 as permitted sender) client-ip=2a00:1450:4010:c03::232; Received: by lanb10 with SMTP id b10so122674401lan.3 for ; Wed, 16 Sep 2015 00:41:15 -0700 (PDT) X-Received: by 10.152.236.12 with SMTP id uq12mr21628393lac.35.1442389275322; Wed, 16 Sep 2015 00:41:15 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp2264689lbq; Wed, 16 Sep 2015 00:41:13 -0700 (PDT) X-Received: by 10.66.147.104 with SMTP id tj8mr56581226pab.125.1442389273322; Wed, 16 Sep 2015 00:41:13 -0700 (PDT) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id qw9si38615543pbc.223.2015.09.16.00.41.12 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Sep 2015 00:41:13 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-407524-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 2440 invoked by alias); 16 Sep 2015 07:41:01 -0000 Mailing-List: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org Precedence: list 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 2427 invoked by uid 89); 16 Sep 2015 07:41:00 -0000 X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, 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) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 16 Sep 2015 07:40:58 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-29-BNSNthJ0TqCMa6YUVh1X0g-1; Wed, 16 Sep 2015 08:40:53 +0100 Received: from e107456-lin.cambridge.arm.com ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 16 Sep 2015 08:40:52 +0100 From: James Greenhalgh To: gcc-patches@gcc.gnu.org Cc: marcus.shawcroft@arm.com, richard.earnshaw@arm.com Subject: [AArch64] Implement copysign[ds]f3 Date: Wed, 16 Sep 2015 08:40:48 +0100 Message-Id: <1442389248-34153-1-git-send-email-james.greenhalgh@arm.com> MIME-Version: 1.0 X-MC-Unique: BNSNthJ0TqCMa6YUVh1X0g-1 X-IsSubscribed: yes X-Original-Sender: james.greenhalgh@arm.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c03::232 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=pass header.i=@gcc.gnu.org X-Google-Group-Id: 836684582541 Hi, This patch adds expanders for copysigndf3 and copysignsf3 to the AArch64 backend. These use the BSL/BIT/BIF insn to save us from the default expansion pattern. Bootstrapped on aarch64-none-linux-gnu with no issues, and checked the performance to show a slight improvement to FP routines using copysign or SIGN from fortran. OK? Thanks, James --- gcc/ 2015-09-16 James Greenhalgh * config/aarch64/aarch64.md (copysigndf3): New. (copysignsf3): Likewise. gcc/testsuite/ 2015-09-16 James Greenhalgh * gcc.target/aarch64/copysign_1.c: New. * gcc.target/aarch64/copysign_2.c: New. diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 88ba72e..925c6b1 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -4412,6 +4412,52 @@ [(set_attr "type" "f_minmax")] ) +;; For copysign (x, y), we want to generate: +;; +;; LDR d2, #(1 << 63) +;; BSL v2.8b, [y], [x] +;; +;; or another, equivalent, sequence using one of BSL/BIT/BIF. +;; aarch64_simd_bsldf will select the best suited of these instructions +;; to generate based on register allocation, and knows how to partially +;; constant fold based on the values of X and Y, so expand through that. + +(define_expand "copysigndf3" + [(match_operand:DF 0 "register_operand") + (match_operand:DF 1 "register_operand") + (match_operand:DF 2 "register_operand")] + "TARGET_FLOAT && TARGET_SIMD" +{ + rtx mask = gen_reg_rtx (DImode); + emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 63)); + emit_insn (gen_aarch64_simd_bsldf (operands[0], mask, + operands[2], operands[1])); + DONE; +} +) + +;; As above, but we must first get to a 64-bit value if we wish to use +;; aarch64_simd_bslv2sf. + +(define_expand "copysignsf3" + [(match_operand:SF 0 "register_operand") + (match_operand:SF 1 "register_operand") + (match_operand:SF 2 "register_operand")] + "TARGET_FLOAT && TARGET_SIMD" +{ + rtx mask = gen_reg_rtx (DImode); + + /* Juggle modes to get us in to a vector mode for BSL. */ + rtx op1 = lowpart_subreg (V2SFmode, operands[1], SFmode); + rtx op2 = lowpart_subreg (V2SFmode, operands[2], SFmode); + rtx tmp = gen_reg_rtx (V2SFmode); + emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 31)); + emit_insn (gen_aarch64_simd_bslv2sf (tmp, mask, op2, op1)); + emit_move_insn (operands[0], lowpart_subreg (SFmode, tmp, V2SFmode)); + DONE; +} +) + ;; ------------------------------------------------------------------- ;; Reload support ;; ------------------------------------------------------------------- diff --git a/gcc/testsuite/gcc.target/aarch64/copysign_1.c b/gcc/testsuite/gcc.target/aarch64/copysign_1.c new file mode 100644 index 0000000..27fb9ca --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/copysign_1.c @@ -0,0 +1,81 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ + +double fabs (double); + +double +check (double x, double y) +{ + return __builtin_copysign (x, y); +} + +double +check1 (double x) +{ + return __builtin_copysign (x, 1.0); +} + +double +check2 (double x) +{ + return __builtin_copysign (1.0, x); +} + +double +check3 (double x) +{ + return -__builtin_copysign (x, 1.0); +} + +double +check4 (double x, double y) +{ + return x * __builtin_copysign (x, y); +} + +double +check5 (double x, double y) +{ + return __builtin_copysign (-x, -y); +} + +int +main (int argc, char** argv) +{ + double x = 2.0; + double y = -5.0; + double epsilon = 0.00001; + + double expected = -2.0; + + if (fabs (check (x, y) - expected) >= epsilon) + __builtin_abort (); + + expected = 2.0; + + if (fabs (check1 (x) - expected) >= epsilon) + __builtin_abort (); + + expected = 1.0; + + if (fabs (check2 (x) - expected) >= epsilon) + __builtin_abort (); + + expected = -2.0; + + if (fabs (check3 (x) - expected) >= epsilon) + __builtin_abort (); + + expected = -4.0; + + if (fabs (check4 (x, y) - expected) >= epsilon) + __builtin_abort (); + + expected = 2.0; + + if (fabs (check5 (x, y) - expected) >= epsilon) + __builtin_abort (); +} + +/* { dg-final { scan-assembler-not "copysign\tw" } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/copysign_2.c b/gcc/testsuite/gcc.target/aarch64/copysign_2.c new file mode 100644 index 0000000..6eaa704 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/copysign_2.c @@ -0,0 +1,81 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ + +float fabsf (float); + +float +check (float x, float y) +{ + return __builtin_copysignf (x, y); +} + +float +check1 (float x) +{ + return __builtin_copysignf (x, 1.0); +} + +float +check2 (float x) +{ + return __builtin_copysignf (1.0, x); +} + +float +check3 (float x) +{ + return -__builtin_copysignf (x, 1.0); +} + +float +check4 (float x, float y) +{ + return x * __builtin_copysignf (x, y); +} + +float +check5 (float x, float y) +{ + return __builtin_copysignf (-x, -y); +} + +int +main (int argc, char** argv) +{ + float x = 2.0f; + float y = -5.0f; + float epsilon = 0.00001f; + + float expected = -2.0f; + + if (fabsf (check (x, y) - expected) >= epsilon) + __builtin_abort (); + + expected = 2.0f; + + if (fabsf (check1 (x) - expected) >= epsilon) + __builtin_abort (); + + expected = 1.0f; + + if (fabsf (check2 (x) - expected) >= epsilon) + __builtin_abort (); + + expected = -2.0f; + + if (fabsf (check3 (x) - expected) >= epsilon) + __builtin_abort (); + + expected = -4.0f; + + if (fabsf (check4 (x, y) - expected) >= epsilon) + __builtin_abort (); + + expected = 2.0f; + + if (fabsf (check5 (x, y) - expected) >= epsilon) + __builtin_abort (); +} + +/* { dg-final { scan-assembler-not "copysign\tw" } } */ +