From: Juzhe-Zhong Date: Tue, 30 May 2023 02:20:19 +0000 (+0800) Subject: RISC-V: Add floating-point to integer conversion RVV auto-vectorization support X-Git-Tag: basepoints/gcc-15~8770 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=52577a301ef1b86d0a3fda9fed2477b4d46a124a;p=thirdparty%2Fgcc.git RISC-V: Add floating-point to integer conversion RVV auto-vectorization support Even though we can't support floating-point operations which are depending on FRM yet, (for example vfadd support is blocked) since the RVV intrinsic doc is not updated and we can't support mode switching for this. We can support floating-point to integer conversion now since it's not depending on FRM and we don't need mode switching support for this ('rtz' conversions independent FRM). Signed-off-by: Juzhe-Zhong gcc/ChangeLog: * config/riscv/autovec.md (2): New pattern. * config/riscv/iterators.md: New attribute. * config/riscv/vector-iterators.md: New attribute. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c: New test. * gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h: New test. --- diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index d9b157140471..7109e143e65c 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -478,6 +478,29 @@ DONE; }) +;; ========================================================================= +;; == Conversions +;; ========================================================================= + +;; ------------------------------------------------------------------------- +;; ---- [INT<-FP] Conversions +;; ------------------------------------------------------------------------- +;; Includes: +;; - vfcvt.rtz.xu.f.v +;; - vfcvt.rtz.x.f.v +;; ------------------------------------------------------------------------- + +(define_expand "2" + [(set (match_operand: 0 "register_operand") + (any_fix: + (match_operand:VF 1 "register_operand")))] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred (, mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, operands); + DONE; +}) + ;; ========================================================================= ;; == Unary arithmetic ;; ========================================================================= diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md index 8afe98e44109..d374a10810c6 100644 --- a/gcc/config/riscv/iterators.md +++ b/gcc/config/riscv/iterators.md @@ -225,7 +225,9 @@ (ss_minus "sssub") (us_minus "ussub") (sign_extend "extend") - (zero_extend "zero_extend")]) + (zero_extend "zero_extend") + (fix "fix_trunc") + (unsigned_fix "fixuns_trunc")]) ;; code attributes (define_code_attr or_optab [(ior "ior") diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 70fb5b80b1b9..937ec3c7f677 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -1208,6 +1208,11 @@ (VNx1DF "VNx1DI") (VNx2DF "VNx2DI") (VNx4DF "VNx4DI") (VNx8DF "VNx8DI") (VNx16DF "VNx16DI") ]) +(define_mode_attr vconvert [ + (VNx1SF "vnx1si") (VNx2SF "vnx2si") (VNx4SF "vnx4si") (VNx8SF "vnx8si") (VNx16SF "vnx16si") (VNx32SF "vnx32si") + (VNx1DF "vnx1di") (VNx2DF "vnx2di") (VNx4DF "vnx4di") (VNx8DF "vnx8di") (VNx16DF "vnx16di") +]) + (define_mode_attr VNCONVERT [ (VNx1SF "VNx1HI") (VNx2SF "VNx2HI") (VNx4SF "VNx4HI") (VNx8SF "VNx8HI") (VNx16SF "VNx16HI") (VNx32SF "VNx32HI") (VNx1DI "VNx1SF") (VNx2DI "VNx2SF") (VNx4DI "VNx4SF") (VNx8DI "VNx8SF") (VNx16DI "VNx16SF") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c new file mode 100644 index 000000000000..05f8d911ad79 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c @@ -0,0 +1,52 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */ + +#include "vfcvt_rtz-template.h" + +#define RUN(TYPE1, TYPE2, NUM) \ + TYPE1 src##TYPE1##TYPE2##NUM[NUM]; \ + TYPE2 dst##TYPE1##TYPE2##NUM[NUM]; \ + for (int i = 0; i < NUM; i++) \ + { \ + src##TYPE1##TYPE2##NUM[i] = i * 3.1315926 + 88932.947289; \ + } \ + vfcvt_##TYPE1##TYPE2 (dst##TYPE1##TYPE2##NUM, src##TYPE1##TYPE2##NUM, NUM); \ + for (int i = 0; i < NUM; i++) \ + if (dst##TYPE1##TYPE2##NUM[i] != (TYPE2) src##TYPE1##TYPE2##NUM[i]) \ + __builtin_abort (); + +int +main () +{ + RUN (float, int32_t, 3) + RUN (float, int32_t, 4) + RUN (float, int32_t, 7) + RUN (float, int32_t, 99) + RUN (float, int32_t, 119) + RUN (float, int32_t, 128) + RUN (float, int32_t, 256) + RUN (float, int32_t, 279) + RUN (float, int32_t, 555) + RUN (float, int32_t, 1024) + RUN (float, int32_t, 1389) + RUN (float, int32_t, 2048) + RUN (float, int32_t, 3989) + RUN (float, int32_t, 4096) + RUN (float, int32_t, 5975) + + RUN (double, int64_t, 3) + RUN (double, int64_t, 4) + RUN (double, int64_t, 7) + RUN (double, int64_t, 99) + RUN (double, int64_t, 119) + RUN (double, int64_t, 128) + RUN (double, int64_t, 256) + RUN (double, int64_t, 279) + RUN (double, int64_t, 555) + RUN (double, int64_t, 1024) + RUN (double, int64_t, 1389) + RUN (double, int64_t, 2048) + RUN (double, int64_t, 3989) + RUN (double, int64_t, 4096) + RUN (double, int64_t, 5975) +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c new file mode 100644 index 000000000000..2f84631775f3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */ + +#include "vfcvt_rtz-template.h" + +/* { dg-final { scan-assembler-times {\tvfcvt\.rtz} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c new file mode 100644 index 000000000000..40e3e7a450dd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=scalable" } */ + +#include "vfcvt_rtz-template.h" + +/* { dg-final { scan-assembler-times {\tvfcvt\.rtz} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h new file mode 100644 index 000000000000..73bc1ad5591f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h @@ -0,0 +1,15 @@ +#include + +#define TEST(TYPE1, TYPE2) \ + __attribute__ ((noipa)) void vfcvt_##TYPE1##TYPE2 (TYPE2 *dst, TYPE1 *a, \ + int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = (TYPE1) a[i]; \ + } + +#define TEST_ALL() \ + TEST (float, int32_t) \ + TEST (double, int64_t) + +TEST_ALL ()