From patchwork Tue Sep 20 02:12:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liu, Hongtao" X-Patchwork-Id: 57781 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EEFDC3858429 for ; Tue, 20 Sep 2022 02:15:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EEFDC3858429 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663640111; bh=sE4KsB8ZVnY8AX7U6f7nAYyHyPrWsT7mk1i2dVm/lbo=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=x0mD2ABMy1UOgoRyvffdRodV76htBoC8/p6Rh0S9Rgp5j01UbRbucIN+fBm96eI3U v5m7DwI8McpFcmrpbu+A5ztfAMTL1H6g6sX2hrBrBBnUu5bByrAx5BUfDJjYaqZcte aW4cIb96tMNA52PevMKX7cCdmET0yKHWpLCnKDLM= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by sourceware.org (Postfix) with ESMTPS id 6B8A03858D28 for ; Tue, 20 Sep 2022 02:14:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6B8A03858D28 X-IronPort-AV: E=McAfee;i="6500,9779,10475"; a="299562592" X-IronPort-AV: E=Sophos;i="5.93,329,1654585200"; d="scan'208";a="299562592" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Sep 2022 19:14:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,329,1654585200"; d="scan'208";a="614219721" Received: from shvmail03.sh.intel.com ([10.239.245.20]) by orsmga007.jf.intel.com with ESMTP; 19 Sep 2022 19:14:36 -0700 Received: from shliclel4051.sh.intel.com (shliclel4051.sh.intel.com [10.239.240.51]) by shvmail03.sh.intel.com (Postfix) with ESMTP id 4BE991005165; Tue, 20 Sep 2022 10:14:35 +0800 (CST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] Support 64-bit vectorization for single-precision floating rounding operation. Date: Tue, 20 Sep 2022 10:12:35 +0800 Message-Id: <20220920021235.2634748-1-hongtao.liu@intel.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: liuhongt via Gcc-patches From: "Liu, Hongtao" Reply-To: liuhongt Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Here's list the patch supported. rint/nearbyint/ceil/floor/trunc/lrint/lceil/lfloor/round/lround. Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,} Ok for trunk? gcc/ChangeLog: PR target/106910 * config/i386/mmx.md (nearbyintv2sf2): New expander. (rintv2sf2): Ditto. (ceilv2sf2): Ditto. (lceilv2sfv2si2): Ditto. (floorv2sf2): Ditto. (lfloorv2sfv2si2): Ditto. (btruncv2sf2): Ditto. (lrintv2sfv2si2): Ditto. (roundv2sf2): Ditto. (lroundv2sfv2si2): Ditto. (*mmx_roundv2sf2): New define_insn. gcc/testsuite/ChangeLog: * gcc.target/i386/pr106910-1.c: New test. --- gcc/config/i386/mmx.md | 154 +++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr106910-1.c | 77 +++++++++++ 2 files changed, 231 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr106910-1.c diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index dda4b43f5c1..222a041de58 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -1627,6 +1627,160 @@ (define_expand "vec_initv2sfsf" DONE; }) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Parallel single-precision floating point rounding operations. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_expand "nearbyintv2sf2" + [(set (match_operand:V2SF 0 "register_operand") + (unspec:V2SF + [(match_operand:V2SF 1 "register_operand") + (match_dup 2)] + UNSPEC_ROUND))] + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" + "operands[2] = GEN_INT (ROUND_MXCSR | ROUND_NO_EXC);") + +(define_expand "rintv2sf2" + [(set (match_operand:V2SF 0 "register_operand") + (unspec:V2SF + [(match_operand:V2SF 1 "register_operand") + (match_dup 2)] + UNSPEC_ROUND))] + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" + "operands[2] = GEN_INT (ROUND_MXCSR);") + +(define_expand "ceilv2sf2" + [(set (match_operand:V2SF 0 "register_operand") + (unspec:V2SF + [(match_operand:V2SF 1 "register_operand") + (match_dup 2)] + UNSPEC_ROUND))] + "TARGET_SSE4_1 && !flag_trapping_math + && TARGET_MMX_WITH_SSE" + "operands[2] = GEN_INT (ROUND_CEIL | ROUND_NO_EXC);") + +(define_expand "lceilv2sfv2si2" + [(match_operand:V2SI 0 "register_operand") + (match_operand:V2SF 1 "register_operand")] + "TARGET_SSE4_1 && !flag_trapping_math + && TARGET_MMX_WITH_SSE" +{ + rtx tmp = gen_reg_rtx (V2SFmode); + emit_insn (gen_ceilv2sf2 (tmp, operands[1])); + emit_insn (gen_fix_truncv2sfv2si2 (operands[0], tmp)); + DONE; +}) + +(define_expand "floorv2sf2" + [(set (match_operand:V2SF 0 "register_operand") + (unspec:V2SF + [(match_operand:V2SF 1 "vector_operand") + (match_dup 2)] + UNSPEC_ROUND))] + "TARGET_SSE4_1 && !flag_trapping_math + && TARGET_MMX_WITH_SSE" + "operands[2] = GEN_INT (ROUND_FLOOR | ROUND_NO_EXC);") + +(define_expand "lfloorv2sfv2si2" + [(match_operand:V2SI 0 "register_operand") + (match_operand:V2SF 1 "register_operand")] + "TARGET_SSE4_1 && !flag_trapping_math + && TARGET_MMX_WITH_SSE" +{ + rtx tmp = gen_reg_rtx (V2SFmode); + emit_insn (gen_floorv2sf2 (tmp, operands[1])); + emit_insn (gen_fix_truncv2sfv2si2 (operands[0], tmp)); + DONE; +}) + +(define_expand "btruncv2sf2" + [(set (match_operand:V2SF 0 "register_operand") + (unspec:V2SF + [(match_operand:V2SF 1 "register_operand") + (match_dup 2)] + UNSPEC_ROUND))] + "TARGET_SSE4_1 && !flag_trapping_math" + "operands[2] = GEN_INT (ROUND_TRUNC | ROUND_NO_EXC);") + +(define_insn "*mmx_roundv2sf2" + [(set (match_operand:V2SF 0 "register_operand" "=Yr,*x,v") + (unspec:V2SF + [(match_operand:V2SF 1 "register_operand" "Yr,x,v") + (match_operand:SI 2 "const_0_to_15_operand")] + UNSPEC_ROUND))] + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" + "%vroundps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "noavx,noavx,avx") + (set_attr "type" "ssecvt") + (set_attr "prefix_data16" "1,1,*") + (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "orig,orig,vex") + (set_attr "mode" "V4SF")]) + +(define_insn "lrintv2sfv2si2" + [(set (match_operand:V2SI 0 "register_operand" "=v") + (unspec:V2SI + [(match_operand:V2SF 1 "register_operand" "v")] + UNSPEC_FIX_NOTRUNC))] + "TARGET_MMX_WITH_SSE" + "%vcvtps2dq\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set (attr "prefix_data16") + (if_then_else + (match_test "TARGET_AVX") + (const_string "*") + (const_string "1"))) + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_expand "roundv2sf2" + [(set (match_dup 3) + (plus:V2SF + (match_operand:V2SF 1 "register_operand") + (match_dup 2))) + (set (match_operand:V2SF 0 "register_operand") + (unspec:V2SF + [(match_dup 3) (match_dup 4)] + UNSPEC_ROUND))] + "TARGET_SSE4_1 && !flag_trapping_math + && TARGET_MMX_WITH_SSE" +{ + const struct real_format *fmt; + REAL_VALUE_TYPE pred_half, half_minus_pred_half; + rtx half, vec_half; + + /* load nextafter (0.5, 0.0) */ + fmt = REAL_MODE_FORMAT (SFmode); + real_2expN (&half_minus_pred_half, -(fmt->p) - 1, SFmode); + real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half); + half = const_double_from_real_value (pred_half, SFmode); + + vec_half = ix86_build_const_vector (V2SFmode, true, half); + vec_half = force_reg (V2SFmode, vec_half); + + operands[2] = gen_reg_rtx (V2SFmode); + emit_insn (gen_copysignv2sf3 (operands[2], vec_half, operands[1])); + + operands[3] = gen_reg_rtx (V2SFmode); + operands[4] = GEN_INT (ROUND_TRUNC); +}) + +(define_expand "lroundv2sfv2si2" + [(match_operand:V2SI 0 "register_operand") + (match_operand:V2SF 1 "register_operand")] + "TARGET_SSE4_1 && !flag_trapping_math + && TARGET_MMX_WITH_SSE" +{ + rtx tmp = gen_reg_rtx (V2SFmode); + emit_insn (gen_roundv2sf2 (tmp, operands[1])); + emit_insn (gen_fix_truncv2sfv2si2 (operands[0], tmp)); + DONE; +}) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parallel half-precision floating point arithmetic diff --git a/gcc/testsuite/gcc.target/i386/pr106910-1.c b/gcc/testsuite/gcc.target/i386/pr106910-1.c new file mode 100644 index 00000000000..c7685a32183 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr106910-1.c @@ -0,0 +1,77 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-msse4.1 -O2 -Ofast" } */ +/* { dg-final { scan-assembler-times "roundps" 9 } } */ +/* { dg-final { scan-assembler-times "cvtps2dq" 1 } } */ +/* { dg-final { scan-assembler-times "cvttps2dq" 3 } } */ + +#include + +void +foo (float* p, float* __restrict q) +{ + p[0] = truncf (q[0]); + p[1] = truncf (q[1]); +} + +void +foo1 (float* p, float* __restrict q) +{ + p[0] = floorf (q[0]); + p[1] = floorf (q[1]); +} + +void +foo1i (int* p, float* __restrict q) +{ + p[0] = (int) floorf (q[0]); + p[1] = (int) floorf (q[1]); +} + +void +foo2 (float* p, float* __restrict q) +{ + p[0] = ceilf (q[0]); + p[1] = ceilf (q[1]); +} + +void +foo2i (int* p, float* __restrict q) +{ + p[0] = (int) ceilf (q[0]); + p[1] = (int) ceilf (q[1]); +} + +void +foo3 (float* p, float* __restrict q) +{ + p[0] = rintf (q[0]); + p[1] = rintf (q[1]); +} + +void +foo3i (int* p, float* __restrict q) +{ + p[0] = (int) rintf (q[0]); + p[1] = (int) rintf (q[1]); +} + +void +foo4 (float* p, float* __restrict q) +{ + p[0] = nearbyintf (q[0]); + p[1] = nearbyintf (q[1]); +} + +void +foo5(float* p, float* __restrict q) +{ + p[0] = roundf (q[0]); + p[1] = roundf (q[1]); +} + +void +foo5i(int* p, float* __restrict q) +{ + p[0] = (int) roundf (q[0]); + p[1] = (int) roundf (q[1]); +}