]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add floating-point to integer conversion RVV auto-vectorization support
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>
Tue, 30 May 2023 02:20:19 +0000 (10:20 +0800)
committerPan Li <pan2.li@intel.com>
Tue, 30 May 2023 02:20:19 +0000 (10:20 +0800)
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 <juzhe.zhong@rivai.ai>
gcc/ChangeLog:

* config/riscv/autovec.md (<optab><mode><vconvert>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.

gcc/config/riscv/autovec.md
gcc/config/riscv/iterators.md
gcc/config/riscv/vector-iterators.md
gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv32gcv.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-rv64gcv.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/conversions/vfcvt_rtz-template.h [new file with mode: 0644]

index d9b157140471cc5e5c4f74b22a07edf672733d1a..7109e143e65c028f0c61d4a77356f3774a437860 100644 (file)
   DONE;
 })
 
+;; =========================================================================
+;; == Conversions
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT<-FP] Conversions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfcvt.rtz.xu.f.v
+;; - vfcvt.rtz.x.f.v
+;; -------------------------------------------------------------------------
+
+(define_expand "<optab><mode><vconvert>2"
+  [(set (match_operand:<VCONVERT> 0 "register_operand")
+       (any_fix:<VCONVERT>
+         (match_operand:VF 1 "register_operand")))]
+  "TARGET_VECTOR"
+{
+  insn_code icode = code_for_pred (<CODE>, <MODE>mode);
+  riscv_vector::emit_vlmax_insn (icode, riscv_vector::RVV_UNOP, operands);
+  DONE;
+})
+
 ;; =========================================================================
 ;; == Unary arithmetic
 ;; =========================================================================
index 8afe98e44109cbeddc717f7523f67368cd01bb61..d374a10810c6ae4def7391f2092c1d2027ab9456 100644 (file)
                         (ss_minus "sssub")
                         (us_minus "ussub")
                         (sign_extend "extend")
-                        (zero_extend "zero_extend")])
+                        (zero_extend "zero_extend")
+                        (fix "fix_trunc")
+                        (unsigned_fix "fixuns_trunc")])
 
 ;; <or_optab> code attributes
 (define_code_attr or_optab [(ior "ior")
index 70fb5b80b1b96cda29f192bd82fd2a1e4966c994..937ec3c7f677a5dfa5fadda9b8aea9127969ae4e 100644 (file)
   (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 (file)
index 0000000..05f8d91
--- /dev/null
@@ -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 (file)
index 0000000..2f84631
--- /dev/null
@@ -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 (file)
index 0000000..40e3e7a
--- /dev/null
@@ -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 (file)
index 0000000..73bc1ad
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdint-gcc.h>
+
+#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 ()