Hi,
(Another late-stage-1 effort)
This adds the compress autovec expander that just delegates to our
compress insn. It was tested on top of Raghesh's series (and doesn't
apply as-is) which still requires some work. I want to be prepared once
it's stable though :)
Regards
Robin
gcc/ChangeLog:
* config/riscv/autovec.md (vec_compress<mode>): New expander.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/rvv.exp:
* gcc.target/riscv/rvv/autovec/compress/compress_store-1.c: New test.
* gcc.target/riscv/rvv/autovec/compress/compress_store-2.c: New test.
* gcc.target/riscv/rvv/autovec/compress/compress_store-3.c: New test.
* gcc.target/riscv/rvv/autovec/compress/compress_store-4.c: New test.
* gcc.target/riscv/rvv/autovec/compress/compress_store_run-1.c: New
test.
---
gcc/config/riscv/autovec.md | 13 +++++++
.../rvv/autovec/compress/compress_store-1.c | 29 +++++++++++++++
.../rvv/autovec/compress/compress_store-2.c | 26 +++++++++++++
.../rvv/autovec/compress/compress_store-3.c | 17 +++++++++
.../rvv/autovec/compress/compress_store-4.c | 15 ++++++++
.../autovec/compress/compress_store_run-1.c | 37 +++++++++++++++++++
gcc/testsuite/gcc.target/riscv/rvv/rvv.exp | 2 +
7 files changed, 139 insertions(+)
create mode 100644
gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-1.c
create mode 100644
gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-2.c
create mode 100644
gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-3.c
create mode 100644
gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-4.c
create mode 100644
gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store_run-1.c
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 607b9891405..77d167e8687 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -3092,3 +3092,16 @@ (define_expand "mask_len_strided_store_<mode>"
riscv_vector::expand_strided_store (<MODE>mode, operands);
DONE;
})
+
+(define_expand "vec_compress<mode>"
+ [(set (match_operand:V_VLS 0 "register_operand")
+ (unspec:V_VLS
+ [(match_operand:V_VLS 1 "register_operand")
+ (match_operand:<VM> 2 "register_operand")] UNSPEC_VCOMPRESS))]
+ "TARGET_VECTOR"
+ {
+ riscv_vector::emit_vlmax_insn (code_for_pred_compress (<MODE>mode),
+ riscv_vector::COMPRESS_OP, operands);
+ DONE;
+ }
+)
diff --git
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-1.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-1.c
new file mode 100644
index 00000000000..e54fac6c482
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d
-mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *restrict q, const TYPE *restrict a) \
+ { \
+ int j = 0; \
+ for (int i = 0; i < 128; ++i) \
+ if (a[i])
\
+ q[j++] = a[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (int16_t) \
+ T (int32_t) \
+ T (int64_t)
+
+TEST_ALL (TEST)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "\\.VCOMPRESS \\(" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "\\.COUNT_ACTIVE \\(" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "\\.MASK_LEN_STORE \\(" 4 "vect" } } */
+/* { dg-final { scan-assembler-times {\tvcompress\.vm\t} 4 } } */
+/* { dg-final { scan-assembler-times {\tvcpop\.m\t} 4 } } */
diff --git
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-2.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-2.c
new file mode 100644
index 00000000000..04a02b3d3cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-2.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d
-mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *restrict q, const TYPE *restrict a, int n)
\
+ { \
+ int j = 0; \
+ for (int i = 0; i < n; ++i)
\
+ if (a[i])
\
+ q[j++] = a[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (int16_t) \
+ T (int32_t) \
+ T (int64_t)
+
+TEST_ALL (TEST)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "\\.VCOMPRESS \\(" 4 "vect" } } */
+/* { dg-final { scan-assembler-times {\tvcompress\.vm\t} 4 } } */
diff --git
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-3.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-3.c
new file mode 100644
index 00000000000..ecc36ac0e97
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d
-mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */
+
+void
+foo (int *restrict q, const int *restrict a)
+{
+ unsigned char j = 0;
+
+ for (int i = 0; i < 100; ++i)
+ if (a[i])
+ q[j++] = a[i];
+}
+
+/* { dg-final { scan-tree-dump "masked store, zero-extended 8-bit index"
"vect" } } */
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
+/* { dg-final { scan-tree-dump "\\.VCOMPRESS \\(" "vect" } } */
+/* { dg-final { scan-assembler {\tvcompress\.vm\t} } } */
diff --git
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-4.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-4.c
new file mode 100644
index 00000000000..e7ac813484b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store-4.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d
-mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */
+
+void
+foo (int *restrict q, const int *restrict a)
+{
+ unsigned char j = 0;
+
+ for (int i = 0; i < 300; ++i)
+ if (a[i])
+ q[j++] = a[i];
+}
+
+/* { dg-final { scan-tree-dump "store index can wrap" "vect" } } */
+/* { dg-final { scan-tree-dump-not "\\.VCOMPRESS \\(" "vect" } } */
diff --git
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store_run-1.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store_run-1.c
new file mode 100644
index 00000000000..f5719f3dfc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/compress/compress_store_run-1.c
@@ -0,0 +1,37 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-mrvv-vector-bits=scalable -fno-vect-cost-model" }
*/
+
+#include "compress_store-2.c"
+
+#define N 301
+
+#define RUN(TYPE) \
+ { \
+ TYPE a[N], q[N + 64], r[N + 64]; \
+ for (int t = 0; t < 32; ++t) \
+ for (int n = 0; n <= N; n += 1 + t) \
+ { \
+ for (int i = 0; i < N; ++i) \
+ a[i] = (i * 7 + t * 13) % (t % 5 + 2) ? (TYPE) (i + 1) : 0; \
+ for (int i = 0; i < N + 64; ++i) \
+ q[i] = r[i] = -1; \
+ int j = 0; \
+ for (int i = 0; i < n; ++i) \
+ { \
+ if (a[i]) \
+ r[j++] = a[i]; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (q, a, n); \
+ for (int i = 0; i < N + 64; ++i) \
+ if (q[i] != r[i]) \
+ __builtin_abort (); \
+ } \
+ }
+
+int
+main ()
+{
+ TEST_ALL (RUN)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
index cc9fa62d912..bf0c01f5e1f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
+++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
@@ -86,6 +86,8 @@ foreach op $AUTOVEC_TEST_OPTS {
"$op" ""
dg-runtest [lsort [glob -nocomplain
$srcdir/$subdir/autovec/builtin/*.\[cS\]]] \
"$op" ""
+ dg-runtest [lsort [glob -nocomplain
$srcdir/$subdir/autovec/compress/*.\[cS\]]] \
+ "$op" ""
}
# widening operation only test on LMUL < 8
--
2.56.0