https://gcc.gnu.org/g:8a3838d53d6010914ce05cf3c09c96bd68f87bae

commit r16-4901-g8a3838d53d6010914ce05cf3c09c96bd68f87bae
Author: Lulu Cheng <[email protected]>
Date:   Wed Mar 5 17:25:23 2025 +0800

    LoongArch: Implement vec_widen_<su>{add/sub/mult}_{hi/lo}_{v16qi/v8hi}.
    
    This patch will cause gcc.dg/vect/bb-slp-35.c test to fail.
    
    gcc/ChangeLog:
    
            * config/loongarch/lasx.md (hi_lo): Move to ...
            * config/loongarch/simd.md (hi_lo): ... here.
            * config/loongarch/loongarch.cc
            (loongarch_expand_vec_widen_hilo): Add 128-bit data processing.
            * config/loongarch/lsx.md
            (vec_widen_<su><optab>_<hi_lo>_<mode>): New define_expand.
            (vec_widen_<su>mult_<hi_lo>_<mode>): Likewise.

Diff:
---
 gcc/config/loongarch/lasx.md      |  2 --
 gcc/config/loongarch/loongarch.cc | 24 +++++++++++++++++++++++-
 gcc/config/loongarch/lsx.md       | 35 +++++++++++++++++++++++++++++++++++
 gcc/config/loongarch/simd.md      |  2 ++
 4 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index ef67eb3915dc..efb0841aecf2 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -3570,8 +3570,6 @@
   [(set_attr "type" "simd_store")
    (set_attr "mode" "DI")])
 
-(define_int_attr hi_lo [(0 "lo") (1 "hi")])
-
 (define_expand "vec_widen_<su><optab>_<hi_lo>_<mode>"
   [(match_operand:<VDMODE256> 0 "register_operand")
    (match_operand:ILASX_HB 1 "register_operand")
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 2198946facfe..e42e70251de3 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -8919,6 +8919,29 @@ loongarch_expand_vec_widen_hilo (rtx dest, rtx op1, rtx 
op2,
        {
          emit_insn (fn_even (t1, op1, op2));
          emit_insn (fn_odd (t2, op1, op2));
+         loongarch_expand_vec_interleave (t3, t1, t2, high_p);
+       }
+      break;
+
+    case V8HImode:
+       {
+         emit_insn (fn_even (t1, op1, op2));
+         emit_insn (fn_odd (t2, op1, op2));
+         if (high_p)
+           emit_insn (gen_lsx_vilvh_w (t3, t1, t2));
+         else
+           emit_insn (gen_lsx_vilvl_w (t3, t1, t2));
+       }
+      break;
+
+    case V16QImode:
+       {
+         emit_insn (fn_even (t1, op1, op2));
+         emit_insn (fn_odd (t2, op1, op2));
+         if (high_p)
+           emit_insn (gen_lsx_vilvh_h (t3, t1, t2));
+         else
+           emit_insn (gen_lsx_vilvl_h (t3, t1, t2));
        }
       break;
 
@@ -8926,7 +8949,6 @@ loongarch_expand_vec_widen_hilo (rtx dest, rtx op1, rtx 
op2,
       gcc_unreachable ();
     }
 
-  loongarch_expand_vec_interleave (t3, t1, t2, high_p);
   emit_move_insn (dest, gen_lowpart (wmode, t3));
 }
 
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index 5424b47c9ed2..62a8a4bb3301 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -3157,3 +3157,38 @@
   [(set (match_dup 0)
        (vec_duplicate:V2DI (match_dup 1)))]
   "")
+
+(define_expand "vec_widen_<su><optab>_<hi_lo>_<mode>"
+  [(match_operand:<VDMODE> 0 "register_operand")
+   (match_operand:ILSX_HB 1 "register_operand")
+   (match_operand:ILSX_HB 2 "register_operand")
+   (any_extend (const_int 0))
+   (addsub (const_int 0) (const_int 0))
+   (const_int zero_one)]
+  "ISA_HAS_LSX"
+{
+  rtx (*fn_even) (rtx, rtx, rtx) =
+gen_lsx_v<optab>wev_<dlsxfmt>_<lsxfmt><u>;
+  rtx (*fn_odd) (rtx, rtx, rtx) =
+gen_lsx_v<optab>wod_<dlsxfmt>_<lsxfmt><u>;
+  loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+                        <zero_one>, fn_even, fn_odd);
+  DONE;
+})
+
+(define_expand "vec_widen_<su>mult_<hi_lo>_<mode>"
+  [(match_operand:<VDMODE> 0 "register_operand")
+   (match_operand:ILSX_HB 1 "register_operand")
+   (match_operand:ILSX_HB 2 "register_operand")
+   (any_extend (const_int 0))
+   (const_int zero_one)]
+  "ISA_HAS_LSX"
+{
+  rtx (*fn_even) (rtx, rtx, rtx) =
+gen_lsx_vmulwev_<dlsxfmt>_<lsxfmt><u>;
+  rtx (*fn_odd) (rtx, rtx, rtx) =
+gen_lsx_vmulwod_<dlsxfmt>_<lsxfmt><u>;
+  loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+                        <zero_one>, fn_even, fn_odd);
+  DONE;
+})
diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index fb20935471de..2cea82e0abf9 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -169,6 +169,8 @@
                          (V4SI  "uimm5") (V8SI "uimm5")
                          (V2DI  "uimm6") (V4DI "uimm6")])
 
+(define_int_attr hi_lo [(0 "lo") (1 "hi")])
+
 ;; =======================================================================
 ;; For many LASX instructions, the only difference of it from the LSX
 ;; counterpart is the length of vector operands.  Describe these LSX/LASX

Reply via email to