From: Kyrylo Tkachov <[email protected]>

The zero-vector insertion pattern requires its scalar input in an FP
register.  A scalar in a general register therefore produces two moves:

  fmov d0, x0
  fmov d0, d0

Add a general-register alternative that emits the first move directly.
It copies the scalar element and clears the remaining SVE lanes.  Use
the general-to-FP transfer instruction type for this alternative.

This removes the redundant self-move in the SVE256 filter handler.
Code-generation tests cover 16-, 32- and 64-bit elements, and runtime
checks cover the scalar value and all remaining lanes.  Tests at SVE
lengths from 128 through 2048 bits pass, including floating bit patterns.

Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill

Cc: Tamar Christina <[email protected]>
Cc: Wilco Dijkstra <wilco@[email protected]>

gcc/ChangeLog:

        * config/aarch64/aarch64-sve.md
        (*aarch64_vec_shl_insert_into_zero_<mode>): Add a general-register
        alternative and set its instruction type.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/sve/copsi.c (func_init3): Update expected assembly.
        * gcc.target/aarch64/sve/insr-zero-gpr.c: New test.
        * gcc.target/aarch64/sve/insr-zero-gpr-run.c: New test.

Signed-off-by: Kyrylo Tkachov <[email protected]>
---
 gcc/config/aarch64/aarch64-sve.md             |  3 +-
 gcc/testsuite/gcc.target/aarch64/sve/copsi.c  |  1 -
 .../aarch64/sve/insr-zero-gpr-run.c           | 47 +++++++++++
 .../gcc.target/aarch64/sve/insr-zero-gpr.c    | 80 +++++++++++++++++++
 4 files changed, 129 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/insr-zero-gpr-run.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/insr-zero-gpr.c

diff --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index dc92cef4d88..c2c2b905d6e 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -3031,8 +3031,9 @@
   "TARGET_SVE"
   {@ [ cons: =0 , 1  , 2 ]
      [ w        , Dz , w ] fmov\t%<Vetype>0, %<Vetype>2
+     [ w        , Dz , r ] fmov\t%<Vetype>0, %<vccore>2
   }
-  [(set_attr "type" "neon_move")]
+  [(set_attr "type" "neon_move,f_mcr")]
 )
 
 ;; Shift an SVE vector left and insert a scalar into element 0 of a zero
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/copsi.c 
b/gcc/testsuite/gcc.target/aarch64/sve/copsi.c
index d85403640b9..6bcbffe6446 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/copsi.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/copsi.c
@@ -20,7 +20,6 @@ func_init4 (int64_t a, int64_t b)
 /*
 ** func_init3:
 **     fmov    s0, w2
-**     fmov    s0, s0
 **     insr    z0\.s, w1
 **     insr    z0\.s, w0
 **     ret
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/insr-zero-gpr-run.c 
b/gcc/testsuite/gcc.target/aarch64/sve/insr-zero-gpr-run.c
new file mode 100644
index 00000000000..fff3abc6024
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/insr-zero-gpr-run.c
@@ -0,0 +1,47 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -march=armv8.2-a+sve" } */
+
+#include "insr-zero-gpr.c"
+#include <stdint.h>
+
+#define CHECK(BITS, COUNT) \
+static __attribute__ ((noinline, noclone)) void \
+check_##BITS (uint##BITS##_t value) \
+{ \
+  unsigned long count = COUNT; \
+  uint##BITS##_t input[count], output[count]; \
+  for (unsigned long i = 0; i < count; ++i) \
+    input[i] = (uint##BITS##_t) (i * 13 + 7); \
+  svst1_u##BITS (svptrue_b##BITS (), output, zero_##BITS (value)); \
+  if (output[0] != value) \
+    __builtin_abort (); \
+  for (unsigned long i = 1; i < count; ++i) \
+    if (output[i] != 0) \
+      __builtin_abort (); \
+  svuint##BITS##_t v = svld1_u##BITS (svptrue_b##BITS (), input); \
+  svst1_u##BITS (svptrue_b##BITS (), output, nonzero_##BITS (v, value)); \
+  if (output[0] != value) \
+    __builtin_abort (); \
+  for (unsigned long i = 1; i < count; ++i) \
+    if (output[i] != input[i - 1]) \
+      __builtin_abort (); \
+}
+
+CHECK (16, svcnth ())
+CHECK (32, svcntw ())
+CHECK (64, svcntd ())
+
+int
+main (void)
+{
+  const uint64_t values[] = { 0, 1, 0x80, 0x8000, 0x80000000ULL,
+                             0x8000000000000000ULL, UINT64_MAX,
+                             0x123456789abcdef0ULL };
+  for (unsigned int i = 0; i < sizeof (values) / sizeof (values[0]); ++i)
+    {
+      check_16 (values[i]);
+      check_32 (values[i]);
+      check_64 (values[i]);
+    }
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/insr-zero-gpr.c 
b/gcc/testsuite/gcc.target/aarch64/sve/insr-zero-gpr.c
new file mode 100644
index 00000000000..65e15551292
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/insr-zero-gpr.c
@@ -0,0 +1,80 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8.2-a+sve" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+/* Insert a scalar word from a general register into an otherwise zero
+   vector.  The scalar move also clears the rest of the SVE register.  */
+
+/*
+** zero_16:
+**     fmov    h0, w0
+**     ret
+*/
+__attribute__ ((noipa))
+svuint16_t
+zero_16 (uint16_t value)
+{
+  return svinsr_n_u16 (svdup_n_u16 (0), value);
+}
+
+/*
+** nonzero_16:
+**     insr    z0.h, w0
+**     ret
+*/
+__attribute__ ((noipa))
+svuint16_t
+nonzero_16 (svuint16_t vector, uint16_t value)
+{
+  return svinsr_n_u16 (vector, value);
+}
+
+/*
+** zero_32:
+**     fmov    s0, w0
+**     ret
+*/
+__attribute__ ((noipa))
+svuint32_t
+zero_32 (uint32_t value)
+{
+  return svinsr_n_u32 (svdup_n_u32 (0), value);
+}
+
+/*
+** nonzero_32:
+**     insr    z0.s, w0
+**     ret
+*/
+__attribute__ ((noipa))
+svuint32_t
+nonzero_32 (svuint32_t vector, uint32_t value)
+{
+  return svinsr_n_u32 (vector, value);
+}
+
+/*
+** zero_64:
+**     fmov    d0, x0
+**     ret
+*/
+__attribute__ ((noipa))
+svuint64_t
+zero_64 (uint64_t value)
+{
+  return svinsr_n_u64 (svdup_n_u64 (0), value);
+}
+
+/*
+** nonzero_64:
+**     insr    z0.d, x0
+**     ret
+*/
+__attribute__ ((noipa))
+svuint64_t
+nonzero_64 (svuint64_t vector, uint64_t value)
+{
+  return svinsr_n_u64 (vector, value);
+}
-- 
2.50.1 (Apple Git-155)

Reply via email to