]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Implement [su]dot_prod* for LSX and LASX modes
authorXi Ruoyao <xry111@xry111.site>
Mon, 20 Jan 2025 15:13:19 +0000 (23:13 +0800)
committerXi Ruoyao <xry111@xry111.site>
Wed, 19 Feb 2025 06:34:45 +0000 (14:34 +0800)
Despite it's just a special case of "a widening product of which the
result used for reduction," having these standard names allows to
recognize the dot product pattern earlier and it may be beneficial to
optimization.  Also fix some test failures with the test cases:

- gcc.dg/vect/vect-reduc-chain-2.c
- gcc.dg/vect/vect-reduc-chain-3.c
- gcc.dg/vect/vect-reduc-chain-dot-slp-3.c
- gcc.dg/vect/vect-reduc-chain-dot-slp-4.c

gcc/ChangeLog:

* config/loongarch/simd.md (wvec_half): New define_mode_attr.
(<su>dot_prod<wvec_half><mode>): New define_expand.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/wide-mul-reduc-2.c (dg-final): Scan
DOT_PROD_EXPR in optimized tree.

gcc/config/loongarch/simd.md
gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-2.c

index 661f5dc8ddafe19b1181f455340160bc63b12400..45d2bcaec2ea91fb3028c341154ba28eec898bf6 100644 (file)
                             (V8HI "V4SI") (V16HI "V8SI")
                             (V16QI "V8HI") (V32QI "V16HI")])
 
+;; Lower-case version.
+(define_mode_attr wvec_half [(V2DI "v1ti") (V4DI "v2ti")
+                            (V4SI "v2di") (V8SI "v4di")
+                            (V8HI "v4si") (V16HI "v8si")
+                            (V16QI "v8hi") (V32QI "v16hi")])
+
 ;; Integer vector modes with the same length and unit size as a mode.
 (define_mode_attr VIMODE [(V2DI "V2DI") (V4SI "V4SI")
                          (V8HI "V8HI") (V16QI "V16QI")
   DONE;
 })
 
+(define_expand "<su>dot_prod<wvec_half><mode>"
+  [(match_operand:<WVEC_HALF> 0 "register_operand" "=f,f")
+   (match_operand:IVEC       1 "register_operand" " f,f")
+   (match_operand:IVEC       2 "register_operand" " f,f")
+   (match_operand:<WVEC_HALF> 3 "reg_or_0_operand" " 0,YG")
+   (any_extend (const_int 0))]
+  ""
+{
+  auto [op0, op1, op2, op3] = operands;
+
+  if (op3 == CONST0_RTX (<WVEC_HALF>mode))
+    emit_insn (
+      gen_<simd_isa>_<x>vmulwev_<simdfmt_w>_<simdfmt><u> (op0, op1, op2));
+  else
+    emit_insn (
+      gen_<simd_isa>_<x>vmaddwev_<simdfmt_w>_<simdfmt><u> (op0, op3, op1,
+                                                          op2));
+
+  emit_insn (
+    gen_<simd_isa>_<x>vmaddwod_<simdfmt_w>_<simdfmt><u> (op0, op0, op1, op2));
+  DONE;
+})
+
 (define_insn "simd_maddw_evod_<mode>_hetero"
   [(set (match_operand:<WVEC_HALF> 0 "register_operand" "=f")
        (plus:<WVEC_HALF>
index 07a7601888aa9d8df70825b7a4760483e85bf500..61e92e58fc3eb0ea6ae6b05d38e50a059e4473c2 100644 (file)
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mlasx" } */
+/* { dg-options "-O2 -mlasx -fdump-tree-optimized" } */
 /* { dg-final { scan-assembler "xvmaddw(ev|od)\\.d\\.w" } } */
+/* { dg-final { scan-tree-dump "DOT_PROD_EXPR" "optimized" } } */
 
 typedef __INT32_TYPE__ i32;
 typedef __INT64_TYPE__ i64;