For the vec_{shr/shl} standard instruction template, on the LA, the optimization
can be achieved through instructions such as vbsll.v and vslli.d. For 256-bit
operations, it is not possible to directly implement them using tools like
xvbsll.v. The reason is that if the processing is divided into the high and low
128 bits, additional processing is required, which actually does not achieve the
optimization effect.

//test.c
void foo (v16i8 *a)
{
  *a = __builtin_shufflevector((v16i8){0},*a,
          1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
}

before asm:
    la.local    $r12,.LC0 //{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
    vld         $vr0,$r4,0
    vldi        $vr1,0
    vld         $vr2,$r12,0
    vshuf.b     $vr0,$vr0,$vr1,$vr2
    vst         $vr0,$r4,0
    jr  $r1

after asm:
    vld         $vr0,$r4,0
    vbsll.v     $vr0,$vr0,15
    vst         $vr0,$r4,0
    jr    $r1

gcc/ChangeLog:

        * config/loongarch/lsx.md (vec_shr_<mode>): Add template.
        (vec_shl_<mode>): Dito.

gcc/testsuite/ChangeLog:

        * gcc.target/loongarch/vector/lsx/lsx-vec-shl.c: New test.
        * gcc.target/loongarch/vector/lsx/lsx-vec-shr.c: New test.
---
 gcc/config/loongarch/lsx.md                   | 26 ++++++++++++++++
 .../loongarch/vector/lsx/lsx-vec-shl.c        | 30 +++++++++++++++++++
 .../loongarch/vector/lsx/lsx-vec-shr.c        | 30 +++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-shl.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-shr.c

diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index 0baaf156ec6..53eba3ffe6b 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -32,6 +32,8 @@ (define_c_enum "unspec" [
   UNSPEC_LSX_VBITSETI
   UNSPEC_LSX_BRANCH_V
   UNSPEC_LSX_BRANCH
+  UNSPEC_LSX_VEC_SHR
+  UNSPEC_LSX_VEC_SHL
   UNSPEC_LSX_VFCLASS
   UNSPEC_LSX_VFCVT
   UNSPEC_LSX_VFCVTH
@@ -529,6 +531,30 @@ (define_expand "vec_perm<mode>"
    operands[5] = gen_const_vec_duplicate (<VIMODE>mode, GEN_INT (0x1f));
  })
 
+(define_expand "vec_shr_<mode>"
+  [(set (match_operand:ILSX 0 "register_operand")
+       (unspec:ILSX[(match_operand:ILSX 1 "register_operand")
+                   (match_operand 2 "const_uimm7_operand")]
+                   UNSPEC_LSX_VEC_SHR))]
+  "ISA_HAS_LSX"
+  {
+    rtx index = GEN_INT (INTVAL (operands[2]) >> 3);
+    emit_insn (gen_lsx_vbsrl_<lsxfmt> (operands[0], operands[1], index));
+    DONE;
+  })
+
+(define_expand "vec_shl_<mode>"
+  [(set (match_operand:ILSX 0 "register_operand")
+       (unspec:ILSX[(match_operand:ILSX 1 "register_operand")
+                   (match_operand 2 "const_uimm7_operand")]
+                   UNSPEC_LSX_VEC_SHL))]
+  "ISA_HAS_LSX"
+  {
+    rtx index = GEN_INT (INTVAL (operands[2]) >> 3);
+    emit_insn (gen_lsx_vbsll_<lsxfmt> (operands[0], operands[1], index));
+    DONE;
+  })
+
 ;; Integer operations
 (define_insn "add<mode>3"
   [(set (match_operand:ILSX 0 "register_operand" "=f,f,f")
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-shl.c 
b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-shl.c
new file mode 100644
index 00000000000..c797c1cc271
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-shl.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-mlsx -O2" } */
+/* { dg-final { scan-assembler-times "vbsll.v" 4 } } */
+
+#include <lsxintrin.h>
+
+void
+foo1 (v16i8 *a)
+{
+  *a = __builtin_shufflevector ((v16i8){ 0 }, *a, 15, 16, 17, 18, 19, 20, 21,
+                                22, 23, 24, 25, 26, 27, 28, 29, 30);
+}
+
+void
+foo2 (v8i16 *a)
+{
+  *a = __builtin_shufflevector ((v8i16){ 0 }, *a, 7, 8, 9, 10, 11, 12, 13, 14);
+}
+
+void
+foo3 (v4i32 *a)
+{
+  *a = __builtin_shufflevector ((v4i32){ 0 }, *a, 3, 4, 5, 6);
+}
+
+void
+foo4 (v2i64 *a)
+{
+  *a = __builtin_shufflevector ((v2i64){ 0 }, *a, 1, 2);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-shr.c 
b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-shr.c
new file mode 100644
index 00000000000..4e8d5758d56
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-shr.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-mlsx -O2" } */
+/* { dg-final { scan-assembler-times "vbsrl.v" 4 } } */
+
+#include <lsxintrin.h>
+
+void
+foo1 (v16i8 *a)
+{
+  *a = __builtin_shufflevector (*a, (v16i8){ 0 }, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                                10, 11, 12, 13, 14, 15, 16);
+}
+
+void
+foo2 (v8i16 *a)
+{
+  *a = __builtin_shufflevector (*a, (v8i16){ 0 }, 1, 2, 3, 4, 5, 6, 7, 8);
+}
+
+void
+foo3 (v4i32 *a)
+{
+  *a = __builtin_shufflevector (*a, (v4i32){ 0 }, 1, 2, 3, 4);
+}
+
+void
+foo4 (v2i64 *a)
+{
+  *a = __builtin_shufflevector (*a, (v2i64){ 0 }, 1, 2);
+}
-- 
2.20.1

Reply via email to