aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorXi Ruoyao <xry111@xry111.site>2025-01-20 20:43:07 +0800
committerXi Ruoyao <xry111@xry111.site>2025-02-19 14:34:45 +0800
commit7c54e46b209664d3a501a03908339c9903d01f1e (patch)
treed6bdf2ffd6f0e19fee309186cdbe6c4464763f22 /gcc
parent7dda6715126c0c5aedbd5f2e4056adf43bb4ea2a (diff)
downloadgcc-7c54e46b209664d3a501a03908339c9903d01f1e.zip
gcc-7c54e46b209664d3a501a03908339c9903d01f1e.tar.gz
gcc-7c54e46b209664d3a501a03908339c9903d01f1e.tar.bz2
LoongArch: Implement vec_widen_mult_{even,odd}_* for LSX and LASX modes
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/loongarch/simd.md16
-rw-r--r--gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-1.c18
-rw-r--r--gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-2.c17
3 files changed, 51 insertions, 0 deletions
diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index b7a28f7..661f5dc 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -630,6 +630,7 @@
;; 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>"
@@ -665,6 +666,21 @@
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
index 0000000..d6e0da5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-1.c
@@ -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
index 0000000..07a7601
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-2.c
@@ -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;
+}