Using __builtin_convertvector to extend a LSX vector to a LASX vector
with the same element count (i.e. the element width is doubled) has
produced some really meaningless instructions:
vext2xv.d.w $xr1,$xr0
vexth.d.w $vr0,$vr0 # ???
xvpermi.q $xr1,$xr0,0x02 # ???
Add {zero_,}extend optab to get rid of them.
gcc/
* config/loongarch/simd.md (wvec): New define_mode_attr.
* config/loongarch/lasx.md (ext_optab_pfx): New
define_code_attr.
(<ext_optab_pfx>extend<mode><wvec>2): New define_insn.
gcc/testsuite
* gcc.target/loongarch/la64/vext2xv.c: New test.
---
Bootstrapped and regtested on loongarch64-linux-gnu but I'm unsure if
this counts as a "bug fix" in stage 3. Ok for trunk now or in next
stage 1?
gcc/config/loongarch/lasx.md | 10 ++++++++++
gcc/config/loongarch/simd.md | 5 +++++
.../gcc.target/loongarch/la64/vext2xv.c | 19 +++++++++++++++++++
3 files changed, 34 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/loongarch/la64/vext2xv.c
diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index c8749d1a338..164bae7e65a 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -2364,6 +2364,16 @@ (define_insn "lasx_<lasxbr>_v_<lasxfmt_f>"
(set_attr "mode" "<MODE>")])
;; loongson-asx.
+(define_code_attr ext_optab_pfx [(sign_extend "") (zero_extend "zero_")])
+(define_insn "<ext_optab_pfx>extend<mode><wvec>2"
+ [(set (match_operand:<WVEC> 0 "register_operand" "=f")
+ (any_extend:<WVEC>
+ (match_operand:ILSX_WHB 1 "register_operand" "f")))]
+ "ISA_HAS_LASX"
+ "vext2xv.<simdfmt_w><u>.<simdfmt><u>\t%u0,%u1"
+ [(set_attr "type" "simd_shift")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "vec_unpack<su>_lo_v32qi"
[(set (match_operand:V16HI 0 "register_operand" "=f")
(any_extend:V16HI
diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index 0ad10683cb5..220d35de2d7 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -110,6 +110,11 @@ (define_mode_attr WVEC_QUARTER [(V8HI "V2DI") (V16HI
"V4DI")
(V16QI "V4SI") (V32QI "V8SI")])
;; Lower-case version.
+(define_mode_attr wvec [(V2DI "v2ti") (V4DI "v4ti")
+ (V4SI "v4di") (V8SI "v8di")
+ (V8HI "v8si") (V16HI "v16si")
+ (V16QI "v16hi") (V32QI "v32hi")])
+
(define_mode_attr wvec_half [(V2DI "v1ti") (V4DI "v2ti")
(V4SI "v2di") (V8SI "v4di")
(V8HI "v4si") (V16HI "v8si")
diff --git a/gcc/testsuite/gcc.target/loongarch/la64/vext2xv.c
b/gcc/testsuite/gcc.target/loongarch/la64/vext2xv.c
new file mode 100644
index 00000000000..d2b4c61511c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/la64/vext2xv.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mlasx" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+void
+test (void)
+{
+ [[gnu::vector_size (16)]] int lsx;
+ [[gnu::vector_size (32)]] long lasx;
+ asm ("" : "=f" (lsx));
+ lasx = __builtin_convertvector(lsx, long [[gnu::vector_size (32)]]);
+ asm ("" :: "f" (lasx));
+}
+
+/*
+** test:
+** vext2xv\.d\.w \$xr[0-9]+,\$xr[0-9]+
+** jr \$r1
+*/
--
2.52.0