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

Reply via email to