diff options
author | Xi Ruoyao <xry111@xry111.site> | 2025-01-20 20:43:07 +0800 |
---|---|---|
committer | Xi Ruoyao <xry111@xry111.site> | 2025-02-19 14:34:45 +0800 |
commit | 7c54e46b209664d3a501a03908339c9903d01f1e (patch) | |
tree | d6bdf2ffd6f0e19fee309186cdbe6c4464763f22 | |
parent | 7dda6715126c0c5aedbd5f2e4056adf43bb4ea2a (diff) | |
download | gcc-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.
-rw-r--r-- | gcc/config/loongarch/simd.md | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-1.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/loongarch/wide-mul-reduc-2.c | 17 |
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; +} |