From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by sourceware.org (Postfix) with ESMTPS id 694743858D35 for ; Thu, 29 Jun 2023 01:40:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 694743858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1688002821; x=1719538821; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=oJpIIs6f7583/ob9IHqcz3A3vK9pVZ7Wk8rTIDyAkbQ=; b=a2qRu8P8q6B9BiPy3jEoeF2hftg+w3BzzDU4RRX/XS6tG7Chg98+c21S rLdIGxyH0r85W+sOtZXW6YKxoJTGXdF6YDVSX0JfHq8zGlh58io57g1+F 9WE9qGP0jx7RKnzCwfBGAVdsW6buftCMTJIwOspP5sNFM+B3YeGKBuETo JbQXFgTyX2JrJT0yTIUw4ixSqu+6RPtdQYarWPYh3UPsOoYAgmKopcGsh 4V3cKoqm1TKXAKy/sK+Oc9tLpkcl/fbscUO080uodNlDILYiOxpKozZ65 qgr/zgGOoubeYZsNeWWt6JkWSpjiB7mDtvXqt9jm31InUXNmbJOCatXx1 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10755"; a="428017244" X-IronPort-AV: E=Sophos;i="6.01,167,1684825200"; d="scan'208";a="428017244" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2023 18:40:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10755"; a="752477967" X-IronPort-AV: E=Sophos;i="6.01,167,1684825200"; d="scan'208";a="752477967" Received: from shvmail02.sh.intel.com ([10.239.244.9]) by orsmga001.jf.intel.com with ESMTP; 28 Jun 2023 18:40:17 -0700 Received: from pli-ubuntu.sh.intel.com (pli-ubuntu.sh.intel.com [10.239.159.47]) by shvmail02.sh.intel.com (Postfix) with ESMTP id 012AB10057F3; Thu, 29 Jun 2023 09:40:16 +0800 (CST) From: pan2.li@intel.com To: gcc-patches@gcc.gnu.org Cc: juzhe.zhong@rivai.ai, kito.cheng@sifive.com, pan2.li@intel.com, yanzhang.wang@intel.com, jeffreyalaw@gmail.com Subject: [PATCH v1] RISC-V: Support vfadd static rounding mode by mode switching Date: Thu, 29 Jun 2023 09:40:14 +0800 Message-Id: <20230629014014.3676175-1-pan2.li@intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_ASCII_DIVIDERS,KAM_SHORT,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Pan Li This patch would like to support the vfadd static round mode similar to the fixed-point. Then the related fsrm instructions will be inserted correlatively. Please *NOTE* this PATCH doesn't cover anything about FRM dynamic mode, it will be implemented in the underlying PATCH(s). Signed-off-by: Pan Li gcc/ChangeLog: * config/riscv/riscv.cc (riscv_emit_mode_set): Add emit for FRM. (riscv_mode_needed): Likewise. (riscv_entity_mode_after): Likewise. (riscv_mode_after): Likewise. (riscv_mode_entry): Likewise. (riscv_mode_exit): Likewise. * config/riscv/riscv.h (NUM_MODES_FOR_MODE_SWITCHING): Add number for FRM. * config/riscv/riscv.md: Add FRM register. * config/riscv/vector-iterators.md: Add FRM type. * config/riscv/vector.md (frm_mode): Define new attr for FRM mode. (fsrm): Define new insn for fsrm instruction. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-frm-insert-1.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-insert-2.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-insert-3.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-insert-4.c: New test. * gcc.target/riscv/rvv/base/float-point-frm-insert-5.c: New test. --- gcc/config/riscv/riscv.cc | 52 ++++++++++++++---- gcc/config/riscv/riscv.h | 4 +- gcc/config/riscv/riscv.md | 4 +- gcc/config/riscv/vector-iterators.md | 2 + gcc/config/riscv/vector.md | 53 +++++++++++++++++++ .../riscv/rvv/base/float-point-frm-insert-1.c | 31 +++++++++++ .../riscv/rvv/base/float-point-frm-insert-2.c | 14 +++++ .../riscv/rvv/base/float-point-frm-insert-3.c | 14 +++++ .../riscv/rvv/base/float-point-frm-insert-4.c | 23 ++++++++ .../riscv/rvv/base/float-point-frm-insert-5.c | 23 ++++++++ 10 files changed, 206 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 280aa0b33b9..e4dc8115e69 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7669,6 +7669,16 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode, if (mode != VXRM_MODE_NONE && mode != prev_mode) emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode))); break; + case RISCV_FRM: + if (mode != FRM_MODE_NONE && mode != prev_mode) + { + rtx scaler = gen_reg_rtx (SImode); + rtx imm = gen_int_mode (mode, SImode); + + emit_insn (gen_movsi (scaler, imm)); + emit_insn (gen_fsrm (scaler, scaler)); + } + break; default: gcc_unreachable (); } @@ -7680,11 +7690,14 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode, static int riscv_mode_needed (int entity, rtx_insn *insn) { + int code = recog_memoized (insn); + switch (entity) { case RISCV_VXRM: - return recog_memoized (insn) >= 0 ? get_attr_vxrm_mode (insn) - : VXRM_MODE_NONE; + return code >= 0 ? get_attr_vxrm_mode (insn) : VXRM_MODE_NONE; + case RISCV_FRM: + return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_NONE; default: gcc_unreachable (); } @@ -7715,6 +7728,21 @@ global_state_unknown_p (rtx_insn *insn, unsigned int regno) return false; } +static int +riscv_entity_mode_after (int regnum, rtx_insn *insn, int mode, + int (*get_attr_mode) (rtx_insn *), int default_mode) +{ + if (global_state_unknown_p (insn, regnum)) + return default_mode; + else if (recog_memoized (insn) < 0) + return mode; + + rtx reg = gen_rtx_REG (SImode, regnum); + bool mentioned_p = reg_mentioned_p (reg, PATTERN (insn)); + + return mentioned_p ? get_attr_mode (insn): mode; +} + /* Return the mode that an insn results in. */ static int @@ -7723,15 +7751,13 @@ riscv_mode_after (int entity, int mode, rtx_insn *insn) switch (entity) { case RISCV_VXRM: - if (global_state_unknown_p (insn, VXRM_REGNUM)) - return VXRM_MODE_NONE; - else if (recog_memoized (insn) >= 0) - return reg_mentioned_p (gen_rtx_REG (SImode, VXRM_REGNUM), - PATTERN (insn)) - ? get_attr_vxrm_mode (insn) - : mode; - else - return mode; + return riscv_entity_mode_after (VXRM_REGNUM, insn, mode, + (int (*)(rtx_insn *)) get_attr_vxrm_mode, + VXRM_MODE_NONE); + case RISCV_FRM: + return riscv_entity_mode_after (FRM_REGNUM, insn, mode, + (int (*)(rtx_insn *)) get_attr_frm_mode, + FRM_MODE_NONE); default: gcc_unreachable (); } @@ -7747,6 +7773,8 @@ riscv_mode_entry (int entity) { case RISCV_VXRM: return VXRM_MODE_NONE; + case RISCV_FRM: + return FRM_MODE_NONE; default: gcc_unreachable (); } @@ -7762,6 +7790,8 @@ riscv_mode_exit (int entity) { case RISCV_VXRM: return VXRM_MODE_NONE; + case RISCV_FRM: + return FRM_MODE_NONE; default: gcc_unreachable (); } diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index bfd9b7551bc..83dcac165b5 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -849,7 +849,7 @@ typedef struct { "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", \ "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", \ "fs8", "fs9", "fs10","fs11","ft8", "ft9", "ft10","ft11", \ - "arg", "frame", "vl", "vtype", "vxrm", "N/A", "N/A", "N/A", \ + "arg", "frame", "vl", "vtype", "vxrm", "frm", "N/A", "N/A", \ "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", \ "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", \ "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", \ @@ -1113,6 +1113,6 @@ extern void riscv_remove_unneeded_save_restore_calls (void); /* Mode switching (Lazy code motion) for RVV rounding mode instructions. */ #define OPTIMIZE_MODE_SWITCHING(ENTITY) (TARGET_VECTOR) -#define NUM_MODES_FOR_MODE_SWITCHING {VXRM_MODE_NONE} +#define NUM_MODES_FOR_MODE_SWITCHING {VXRM_MODE_NONE, FRM_MODE_NONE} #endif /* ! GCC_RISCV_H */ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 565e8cd27cd..4cd8b9d7c77 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -282,6 +282,7 @@ (define_attr "ext_enabled" "no,yes" ;; rdvlenb vector byte length vlenb csrr read ;; rdvl vector length vl csrr read ;; wrvxrm vector fixed-point rounding mode write +;; wrfrm vector floating-point rounding mode write ;; vsetvl vector configuration-setting instrucions ;; 7. Vector Loads and Stores ;; vlde vector unit-stride load instructions @@ -385,7 +386,8 @@ (define_attr "type" mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul, fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost,bitmanip,rotate, clmul,min,max,minu,maxu,clz,ctz,cpop, - atomic,condmove,crypto,rdvlenb,rdvl,wrvxrm,vsetvl,vlde,vste,vldm,vstm,vlds,vsts, + atomic,condmove,crypto,rdvlenb,rdvl,wrvxrm,wrfrm,vsetvl, + vlde,vste,vldm,vstm,vlds,vsts, vldux,vldox,vstux,vstox,vldff,vldr,vstr, vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,vssegtux,vssegtox,vlsegdff, vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,viminmax, diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 26c1bb7a3d6..50f39b84b24 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -82,6 +82,8 @@ (define_c_enum "unspec" [ UNSPEC_VCOMPRESS UNSPEC_VLEFF UNSPEC_MODIFY_VL + + UNSPEC_FSRM ]) (define_mode_iterator V [ diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 674e602dec6..fadd9071c6d 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -462,6 +462,38 @@ (define_attr "vxrm_mode" "rnu,rne,rdn,rod,none" (const_string "rod")] (const_string "none"))) +;; Defines rounding mode of an floating-point operation. +(define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,none" + (cond + [ + (eq_attr "type" "vfalu") + (cond + [ + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RNE") + (const_string "rne") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RTZ") + (const_string "rtz") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RDN") + (const_string "rdn") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RUP") + (const_string "rup") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RMM") + (const_string "rmm") + + (match_test "INTVAL (operands[9]) == riscv_vector::FRM_RDN") + (const_string "rdn") + ] + (const_string "none") + ) + ] + (const_string "none") + ) +) + ;; ----------------------------------------------------------------- ;; ---- Miscellaneous Operations ;; ----------------------------------------------------------------- @@ -538,6 +570,27 @@ (define_insn "vxrmsi" [(set_attr "type" "wrvxrm") (set_attr "mode" "SI")]) +;; Set FRM +(define_insn "fsrm" + [ + (set + (reg:SI FRM_REGNUM) + (unspec:SI + [ + (match_operand:SI 0 "register_operand" "=&r") + (match_operand:SI 1 "register_operand" "r") + ] UNSPEC_FSRM + ) + ) + ] + "TARGET_VECTOR" + "fsrm\t%0,%1" + [ + (set_attr "type" "wrfrm") + (set_attr "mode" "SI") + ] +) + ;; ----------------------------------------------------------------- ;; ---- Moves Operations ;; ----------------------------------------------------------------- diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c new file mode 100644 index 00000000000..732e0305a3d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +typedef float float32_t; + +vfloat32m1_t +test_riscv_vfadd_vv_f32m1_rm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { + return __riscv_vfadd_vv_f32m1_rm (op1, op2, 0, vl); +} + +vfloat32m1_t +test_vfadd_vv_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, vfloat32m1_t op2, + size_t vl) { + return __riscv_vfadd_vv_f32m1_m_rm(mask, op1, op2, 1, vl); +} + +vfloat32m1_t +test_vfadd_vf_f32m1_rm(vfloat32m1_t op1, float32_t op2, size_t vl) { + return __riscv_vfadd_vf_f32m1_rm(op1, op2, 2, vl); +} + +vfloat32m1_t +test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2, + size_t vl) { + return __riscv_vfadd_vf_f32m1_m_rm(mask, op1, op2, 3, vl); +} + +/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c new file mode 100644 index 00000000000..72e5d2084b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { + vfloat32m1_t v1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 0, vl); + vfloat32m1_t v2 = __riscv_vfmin_vv_f32m1 (op1, v1, vl); + return __riscv_vfadd_vv_f32m1_rm (v1, v2, 0, vl); +} + +/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c new file mode 100644 index 00000000000..c9e8d0a6eaf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { + vfloat32m1_t v1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 0, vl); + vfloat32m1_t v2 = __riscv_vfmin_vv_f32m1 (op1, v1, vl); + return __riscv_vfadd_vv_f32m1_rm (v1, v2, 1, vl); +} + +/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c new file mode 100644 index 00000000000..a288e0be628 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-4.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, + size_t count) { + vfloat32m1_t tmp = op1, result; + + result = __riscv_vfadd_vv_f32m1_rm (result, op1, 1, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + + for (int i = 0; i < count; i++) { + tmp = __riscv_vfadd_vv_f32m1_rm (op1, tmp, 1, vl + i); + result = __riscv_vfrsqrt7_v_f32m1 (tmp, vl + i); + } + + return __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); +} + +/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c new file mode 100644 index 00000000000..bb77a6efc62 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-5.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +vfloat32m1_t +test_float_point_frm_insert (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl, + size_t count) { + vfloat32m1_t tmp = op1, result; + + result = __riscv_vfadd_vv_f32m1_rm (result, op1, 1, vl); + result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); + + for (int i = 0; i < count; i++) { + tmp = __riscv_vfadd_vv_f32m1_rm (op1, tmp, 2, vl + i); + result = __riscv_vfrsqrt7_v_f32m1 (tmp, vl + i); + } + + return __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl); +} + +/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v+[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} 3 } } */ -- 2.34.1