]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Implement vec_widen_mult_{even,odd}_* for LSX and LASX modes
authorXi Ruoyao <xry111@xry111.site>
Mon, 20 Jan 2025 12:43:07 +0000 (20:43 +0800)
committerXi Ruoyao <xry111@xry111.site>
Wed, 19 Feb 2025 06:34:45 +0000 (14:34 +0800)
Since PR116142 has been fixed, now we can add the standard names so the
compiler will generate better code if the result of a widening
production is reduced.

gcc/ChangeLog:

* config/loongarch/simd.md (even_odd): New define_int_attr.
(vec_widen_<su>mult_<even_odd>_<mode>): New define_expand.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/wide-mul-reduc-1.c: New test.
* gcc.target/loongarch/wide-mul-reduc-2.c: New test.

gcc/config/loongarch/simd.md
gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-2.c [new file with mode: 0644]

index b7a28f7b3f225cbba1a37c241a8fc8624f2eaf43..661f5dc8ddafe19b1181f455340160bc63b12400 100644 (file)
 ;; Operations on elements at even/odd indices.
 (define_int_iterator zero_one [0 1])
 (define_int_attr ev_od [(0 "ev") (1 "od")])
+(define_int_attr even_odd [(0 "even") (1 "odd")])
 
 ;; Integer widening add/sub/mult.
 (define_insn "simd_<optab>w_evod_<mode>_<su>"
   DONE;
 })
 
+(define_expand "vec_widen_<su>mult_<even_odd>_<mode>"
+  [(match_operand:<WVEC_HALF> 0 "register_operand" "=f")
+   (match_operand:IVEC       1 "register_operand" " f")
+   (match_operand:IVEC       2 "register_operand" " f")
+   (any_extend (const_int 0))
+   (const_int zero_one)]
+  ""
+{
+  emit_insn (
+    gen_<simd_isa>_<x>vmulw<ev_od>_<simdfmt_w>_<simdfmt><u> (operands[0],
+                                                            operands[1],
+                                                            operands[2]));
+  DONE;
+})
+
 (define_insn "simd_<optab>w_evod_<mode>_hetero"
   [(set (match_operand:<WVEC_HALF> 0 "register_operand" "=f")
        (addsubmul:<WVEC_HALF>
diff --git a/gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-1.c b/gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-1.c
new file mode 100644 (file)
index 0000000..d6e0da5
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlasx -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump "WIDEN_MULT_EVEN_EXPR" "optimized" } } */
+/* { dg-final { scan-tree-dump "WIDEN_MULT_ODD_EXPR" "optimized" } } */
+
+typedef __INT32_TYPE__ i32;
+typedef __INT64_TYPE__ i64;
+
+i32 x[8], y[8];
+
+i64
+test (void)
+{
+  i64 ret = 0;
+  for (int i = 0; i < 8; i++)
+    ret ^= (i64) x[i] * y[i];
+  return ret;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-2.c b/gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-2.c
new file mode 100644 (file)
index 0000000..07a7601
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlasx" } */
+/* { dg-final { scan-assembler "xvmaddw(ev|od)\\.d\\.w" } } */
+
+typedef __INT32_TYPE__ i32;
+typedef __INT64_TYPE__ i64;
+
+i32 x[8], y[8];
+
+i64
+test (void)
+{
+  i64 ret = 0;
+  for (int i = 0; i < 8; i++)
+    ret += (i64) x[i] * y[i];
+  return ret;
+}