public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Robin Dapp <rdapp@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-2139] RISC-V: Add autovec FP widening/narrowing. Date: Tue, 27 Jun 2023 21:30:57 +0000 (GMT) [thread overview] Message-ID: <20230627213057.307943856604@sourceware.org> (raw) https://gcc.gnu.org/g:a9b40612baf2f936ac1d211fbc0b3e46404cefa7 commit r14-2139-ga9b40612baf2f936ac1d211fbc0b3e46404cefa7 Author: Robin Dapp <rdapp@ventanamicro.com> Date: Tue Jun 20 13:07:23 2023 +0200 RISC-V: Add autovec FP widening/narrowing. This patch adds FP widening and narrowing expanders as well as tests. Conceptually similar to integer extension/truncation, we emulate _Float16 -> double by two vfwcvts and double -> _Float16 by two vfncvts. gcc/ChangeLog: * config/riscv/autovec.md (extend<v_double_trunc><mode>2): New expander. (extend<v_quad_trunc><mode>2): Ditto. (trunc<mode><v_double_trunc>2): Ditto. (trunc<mode><v_quad_trunc>2): Ditto. * config/riscv/vector-iterators.md: Add VQEXTF and HF to V_QUAD_TRUNC and v_quad_trunc. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h: New test. * gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h: New test. * gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c: New test. Diff: --- gcc/config/riscv/autovec.md | 88 +++++++++++++++++++++- gcc/config/riscv/vector-iterators.md | 14 ++++ .../riscv/rvv/autovec/conversions/vfncvt-run.c | 33 ++++++++ .../riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c | 7 ++ .../riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c | 7 ++ .../rvv/autovec/conversions/vfncvt-template.h | 16 ++++ .../rvv/autovec/conversions/vfncvt-zvfh-run.c | 34 +++++++++ .../riscv/rvv/autovec/conversions/vfwcvt-run.c | 33 ++++++++ .../riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c | 6 ++ .../riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c | 6 ++ .../rvv/autovec/conversions/vfwcvt-template.h | 16 ++++ .../rvv/autovec/conversions/vfwcvt-zvfh-run.c | 34 +++++++++ 12 files changed, 292 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index b0e5950fb56..a7c8056a774 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -162,12 +162,12 @@ riscv_vector::emit_vlmax_insn (code_for_pred_scalar (<CODE>, <MODE>mode), riscv_vector::RVV_BINOP, operands); DONE; -} +} [(set_attr "type" "vshift") (set_attr "mode" "<MODE>")]) ;; ------------------------------------------------------------------------- -;; ---- [INT] Binary shifts by scalar. +;; ---- [INT] Binary shifts by vector. ;; ------------------------------------------------------------------------- ;; Includes: ;; - vsll.vv/vsra.vv/vsrl.vv @@ -428,6 +428,90 @@ DONE; }) +;; ------------------------------------------------------------------------- +;; ---- [FP] Widening. +;; ------------------------------------------------------------------------- +;; - vfwcvt.f.f.v +;; ------------------------------------------------------------------------- +(define_insn_and_split "extend<v_double_trunc><mode>2" + [(set (match_operand:VWEXTF_ZVFHMIN 0 "register_operand" "=&vr") + (float_extend:VWEXTF_ZVFHMIN + (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand" " vr")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] +{ + insn_code icode = code_for_pred_extend (<MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, operands); + DONE; +} + [(set_attr "type" "vfwcvtftof") + (set_attr "mode" "<MODE>")]) + +(define_expand "extend<v_quad_trunc><mode>2" + [(set (match_operand:VQEXTF 0 "register_operand") + (float_extend:VQEXTF + (match_operand:<V_QUAD_TRUNC> 1 "register_operand")))] + "TARGET_VECTOR && (TARGET_ZVFHMIN || TARGET_ZVFH)" +{ + rtx dblw = gen_reg_rtx (<V_DOUBLE_TRUNC>mode); + insn_code icode = code_for_pred_extend (<V_DOUBLE_TRUNC>mode); + rtx ops1[] = {dblw, operands[1]}; + riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ops1); + + icode = code_for_pred_extend (<MODE>mode); + rtx ops2[] = {operands[0], dblw}; + riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, ops2); + DONE; +}) + +;; ------------------------------------------------------------------------- +;; ---- [FP] Narrowing. +;; ------------------------------------------------------------------------- +;; - vfncvt.f.f.w +;; ------------------------------------------------------------------------- +(define_insn_and_split "trunc<mode><v_double_trunc>2" + [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vr") + (truncate:<V_DOUBLE_TRUNC> + (match_operand:VWEXTF_ZVFHMIN 1 "register_operand" " vr")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] +{ + insn_code icode = code_for_pred_trunc (<MODE>mode); + riscv_vector::emit_vlmax_fp_insn (icode, riscv_vector::RVV_UNOP, operands); + DONE; +} + [(set_attr "type" "vfncvtftof") + (set_attr "mode" "<MODE>")]) + +;; ------------------------------------------------------------------------- +;; Narrowing to a mode whose inner mode size is a quarter of mode's. +;; We emulate this with two consecutive vfncvts. +;; ------------------------------------------------------------------------- +(define_expand "trunc<mode><v_quad_trunc>2" + [(set (match_operand:<V_QUAD_TRUNC> 0 "register_operand") + (truncate:<V_QUAD_TRUNC> + (match_operand:VQEXTF 1 "register_operand")))] + "TARGET_VECTOR && (TARGET_ZVFHMIN || TARGET_ZVFH)" +{ + rtx half = gen_reg_rtx (<V_DOUBLE_TRUNC>mode); + rtx opshalf[] = {half, operands[1]}; + + /* According to the RISC-V V Spec 13.19. we need to use + vfncvt.rod.f.f.w for all steps but the last. */ + insn_code icode = code_for_pred_rod_trunc (<MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, opshalf); + + rtx ops[] = {operands[0], half}; + icode = code_for_pred_trunc (<V_DOUBLE_TRUNC>mode); + riscv_vector::emit_vlmax_fp_insn (icode, riscv_vector::RVV_UNOP, ops); + DONE; +}) + + ;; ========================================================================= ;; == Conversions ;; ========================================================================= diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 7893aa66a2b..8134bc0ddd6 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -547,6 +547,14 @@ (VNx16DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") ]) +(define_mode_iterator VQEXTF [ + (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128") + (VNx2DF "TARGET_VECTOR_ELEN_FP_64") + (VNx4DF "TARGET_VECTOR_ELEN_FP_64") + (VNx8DF "TARGET_VECTOR_ELEN_FP_64") + (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") +]) + (define_mode_iterator VOEXTI [ (VNx1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128") (VNx2DI "TARGET_VECTOR_ELEN_64") (VNx4DI "TARGET_VECTOR_ELEN_64") (VNx8DI "TARGET_VECTOR_ELEN_64") @@ -1305,6 +1313,9 @@ (VNx16SI "VNx16QI") (VNx32SI "VNx32QI") (VNx1DI "VNx1HI") (VNx2DI "VNx2HI") (VNx4DI "VNx4HI") (VNx8DI "VNx8HI") (VNx16DI "VNx16HI") + + (VNx1DF "VNx1HF") (VNx2DF "VNx2HF") (VNx4DF "VNx4HF") (VNx8DF "VNx8HF") + (VNx16DF "VNx16HF") ]) (define_mode_attr V_OCT_TRUNC [ @@ -1330,6 +1341,9 @@ (VNx16SI "vnx16qi") (VNx32SI "vnx32qi") (VNx1DI "vnx1hi") (VNx2DI "vnx2hi") (VNx4DI "vnx4hi") (VNx8DI "vnx8hi") (VNx16DI "vnx16hi") + + (VNx1DF "vnx1hf") (VNx2DF "vnx2hf") (VNx4DF "vnx4hf") (VNx8DF "vnx8hf") + (VNx16DF "vnx16hf") ]) (define_mode_attr v_oct_trunc [ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c new file mode 100644 index 00000000000..65d2826c8a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-run.c @@ -0,0 +1,33 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */ + +#include "vfncvt-template.h" + +#include <assert.h> + +#define SZ 512 +#define EPS 1e-4 + +#define RUN(TYPE1,TYPE2) \ + TYPE1 src##TYPE1##TYPE2[SZ]; \ + TYPE2 dst##TYPE1##TYPE2[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + src##TYPE1##TYPE2[i] = (i & 1) ? -i : i; \ + src##TYPE1##TYPE2[i] *= 3.141592; \ + dst##TYPE1##TYPE2[i] = -1; \ + } \ + vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2, \ + src##TYPE1##TYPE2, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (dst##TYPE1##TYPE2[i] \ + - ((i & 1) ? -i : i) * 3.141592) < EPS); \ + + +#define RUN_ALL() \ + RUN(double, float) \ + +int main () +{ + RUN_ALL() +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c new file mode 100644 index 00000000000..10fe75d2754 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv32gcv.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */ + +#include "vfncvt-template.h" + +/* { dg-final { scan-assembler-times {\tvfncvt\.f\.f\.w} 3 } } */ +/* { dg-final { scan-assembler-times {\tvfncvt\.rod\.f\.f\.w} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c new file mode 100644 index 00000000000..fd40fa242e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-rv64gcv.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */ + +#include "vfncvt-template.h" + +/* { dg-final { scan-assembler-times {\tvfncvt\.f\.f\.w} 3 } } */ +/* { dg-final { scan-assembler-times {\tvfncvt\.rod\.f\.f\.w} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h new file mode 100644 index 00000000000..221e8838d36 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-template.h @@ -0,0 +1,16 @@ +#include <stdint-gcc.h> + +#define TEST(TYPE1, TYPE2) \ + __attribute__((noipa)) \ + void vfncvt_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = (TYPE2)a[i]; \ + } + +#define TEST_ALL() \ + TEST(float, _Float16) \ + TEST(double, _Float16) \ + TEST(double, float) \ + +TEST_ALL() diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c new file mode 100644 index 00000000000..38e0d84b4e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfncvt-zvfh-run.c @@ -0,0 +1,34 @@ +/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */ + +#include "vfncvt-template.h" + +#include <assert.h> + +#define SZ 512 +#define EPS 1e-4 + +#define RUN(TYPE1,TYPE2) \ + TYPE1 src##TYPE1##TYPE2[SZ]; \ + TYPE2 dst##TYPE1##TYPE2[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + src##TYPE1##TYPE2[i] = (i & 1) ? -i : i; \ + src##TYPE1##TYPE2[i] *= 0.0003141592; \ + dst##TYPE1##TYPE2[i] = -1; \ + } \ + vfncvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2, \ + src##TYPE1##TYPE2, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (dst##TYPE1##TYPE2[i] \ + - ((i & 1) ? -i : i) * 0.0003141592) < EPS); \ + + +#define RUN_ALL() \ + RUN(float, _Float16) \ + RUN(double, _Float16) \ + +int main () +{ + RUN_ALL() +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c new file mode 100644 index 00000000000..9594909c4ee --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-run.c @@ -0,0 +1,33 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */ + +#include "vfwcvt-template.h" + +#include <assert.h> + +#define SZ 512 +#define EPS 1e-4 + +#define RUN(TYPE1,TYPE2) \ + TYPE1 src##TYPE1##TYPE2[SZ]; \ + TYPE2 dst##TYPE1##TYPE2[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + src##TYPE1##TYPE2[i] = (i & 1) ? -i : i; \ + src##TYPE1##TYPE2[i] *= 3.141592; \ + dst##TYPE1##TYPE2[i] = -1; \ + } \ + vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2, \ + src##TYPE1##TYPE2, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (dst##TYPE1##TYPE2[i] \ + - ((i & 1) ? -i : i) * 3.141592) < EPS); \ + + +#define RUN_ALL() \ + RUN(float, double) \ + +int main () +{ + RUN_ALL() +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c new file mode 100644 index 00000000000..006bdb24c41 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv32gcv.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */ + +#include "vfwcvt-template.h" + +/* { dg-final { scan-assembler-times {\tvfwcvt\.f\.f\.v} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c new file mode 100644 index 00000000000..7ec710702c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-rv64gcv.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */ + +#include "vfwcvt-template.h" + +/* { dg-final { scan-assembler-times {\tvfwcvt\.f\.f\.v} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h new file mode 100644 index 00000000000..b6ccf3ba2f5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-template.h @@ -0,0 +1,16 @@ +#include <stdint-gcc.h> + +#define TEST(TYPE1, TYPE2) \ + __attribute__((noipa)) \ + void vfwcvt_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = (TYPE2)a[i]; \ + } + +#define TEST_ALL() \ + TEST(_Float16, float) \ + TEST(_Float16, double) \ + TEST(float, double) \ + +TEST_ALL() diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c new file mode 100644 index 00000000000..77d653e256d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfwcvt-zvfh-run.c @@ -0,0 +1,34 @@ +/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */ + +#include "vfwcvt-template.h" + +#include <assert.h> + +#define SZ 512 +#define EPS 1e-4 + +#define RUN(TYPE1,TYPE2) \ + TYPE1 src##TYPE1##TYPE2[SZ]; \ + TYPE2 dst##TYPE1##TYPE2[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + src##TYPE1##TYPE2[i] = (i & 1) ? -i : i; \ + src##TYPE1##TYPE2[i] *= 0.0003141592; \ + dst##TYPE1##TYPE2[i] = -1; \ + } \ + vfwcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2, \ + src##TYPE1##TYPE2, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (dst##TYPE1##TYPE2[i] \ + - ((i & 1) ? -i : i) * 0.0003141592) < EPS); \ + + +#define RUN_ALL() \ + RUN(_Float16, float) \ + RUN(_Float16, double) \ + +int main () +{ + RUN_ALL() +}
reply other threads:[~2023-06-27 21:30 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230627213057.307943856604@sourceware.org \ --to=rdapp@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).