LoongArch: Fix pattern vec_concatz<mode>

Message ID 20240116022417.51862-1-xujiahao@loongson.cn
State Unresolved
Headers
Series LoongArch: Fix pattern vec_concatz<mode> |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Jiahao Xu Jan. 16, 2024, 2:24 a.m. UTC
  In r14-7022-34d339bbd0c1f5b4ad9587e7ae8387c912cb028b I implement pattern
vec_concatz<mode>, the reg+reg addressing mode is not supported in
vec_concatz<mode>. This patch fixes that.

gcc/ChangeLog:

	* config/loongarch/lasx.md (vec_concatz<mode>): Fix pattern to
	support reg+reg addressing mode.

gcc/testsuite/ChangeLog:

	* gcc.target/loongarch/vect-concatz.c: New test.
  

Patch

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 90f66ee4d24..77ab754fa9e 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -589,10 +589,8 @@  (define_insn "@vec_concatz<mode>"
       (match_operand:<VHMODE256_ALL> 2 "const_0_operand")))]
   "ISA_HAS_LASX"
 {
-  if (MEM_P (operands[1]))
-    return "vld\t%w0,%1";
-  else
-    return "vori.b\t%w0,%w1,0";
+  return loongarch_output_move (gen_lowpart (<VHMODE256_ALL>mode,
+                                operands[0]), operands[1]);
 }
   [(set_attr "type" "simd_splat")
    (set_attr "mode" "<MODE>")])
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-concatz.c b/gcc/testsuite/gcc.target/loongarch/vect-concatz.c
new file mode 100644
index 00000000000..45aa776c11b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vect-concatz.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run } */                                                             
+/* { dg-options "-O3 -mlasx -fno-vect-cost-model" } */
+
+#include <stddef.h>
+
+typedef struct
+{
+  int *rect;
+  float *rect_float;
+  unsigned int x;
+  unsigned int y;
+} ImBuf;
+
+ImBuf *
+IMB_double_fast_x(ImBuf *ibuf1, ImBuf *ibuf2)
+{
+  int *p1, *dest, i, col, do_rect, do_float;
+  float *p1f, *destf;
+
+  if (ibuf1 == NULL) return (NULL);
+  if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
+
+  do_rect = (ibuf1->rect != NULL);
+  do_float = (ibuf1->rect_float != NULL);
+
+
+  p1 = (int *) ibuf1->rect;
+  dest = (int *) ibuf2->rect;
+  p1f = (float *)ibuf1->rect_float;
+  destf = (float *)ibuf2->rect_float;
+
+  for (i = ibuf1->y * ibuf1->x; i > 0; i--) {
+      if (do_rect) {
+	  col = *p1++;
+	  *dest++ = col;
+	  *dest++ = col;
+      }
+      if (do_float) {
+	  destf[0] = destf[4] = p1f[0];
+	  destf[1] = destf[5] = p1f[1];
+	  destf[2] = destf[6] = p1f[2];
+	  destf[3] = destf[7] = p1f[3];
+	  destf += 8;
+	  p1f += 4;
+      }
+  }
+
+  return (ibuf2);
+}
+
+int
+main()
+{
+  return 0;
+}