De-duplicate the login by introducing gen_lasx_xvpermi_d (mode, ...)
with "@".  Also remove the merge_two label: we should really not (ab)use
goto when avoiding it is trivial.

Link: https://dl.acm.org/doi/10.5555/1241515.1241518

gcc/

        * config/loongarch/lasx.md (lasx_xvpermi_d): Add "@".
        * config/loongarch/loongarch.cc (loongarch_expand_vec_perm_1):
        Use gen_lasx_xvpermi_d instead of
        gen_lasx_xvpermi_d_{v32qi,v16hi} to deduplicate the logic.  Do
        structrual programming instead of goto and label.
---
 gcc/config/loongarch/lasx.md      |  2 +-
 gcc/config/loongarch/loongarch.cc | 72 ++++++++++---------------------
 2 files changed, 24 insertions(+), 50 deletions(-)

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index a1359952c8a..c8749d1a338 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -474,7 +474,7 @@ (define_insn "@lasx_xvperm_<lasxfmt_f_wd>"
    (set_attr "mode" "<MODE>")])
 
 ;; xvpermi.d
-(define_insn "lasx_xvpermi_d_<LASX:mode>"
+(define_insn "@lasx_xvpermi_d_<LASX:mode>"
   [(set (match_operand:LASX 0 "register_operand" "=f")
          (unspec:LASX
            [(match_operand:LASX 1 "register_operand" "f")
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 4e32b23b6db..78d04ed63de 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -9147,70 +9147,44 @@ loongarch_expand_vec_perm_1 (rtx operands[])
          t2 = gen_reg_rtx (mode);
          emit_insn (gen_lasx_xvperm (mode, t1, op0, mask));
          emit_insn (gen_lasx_xvperm (mode, t2, op1, mask));
-         goto merge_two;
        }
-      return;
+      break;
 
     case E_V16HImode:
-      if (one_operand_shuffle)
-       {
-         t1 = gen_reg_rtx (V16HImode);
-         t2 = gen_reg_rtx (V16HImode);
-         emit_insn (gen_lasx_xvpermi_d_v16hi (t1, op0, GEN_INT (0x44)));
-         emit_insn (gen_lasx_xvpermi_d_v16hi (t2, op0, GEN_INT (0xee)));
-         emit_insn (gen_lasx_xvshuf_h (target, mask, t2, t1));
-       }
-      else
-       {
-         t1 = gen_reg_rtx (V16HImode);
-         t2 = gen_reg_rtx (V16HImode);
-         t3 = gen_reg_rtx (V16HImode);
-         t4 = gen_reg_rtx (V16HImode);
-         t5 = gen_reg_rtx (V16HImode);
-         t6 = gen_reg_rtx (V16HImode);
-         emit_insn (gen_lasx_xvpermi_d_v16hi (t3, op0, GEN_INT (0x44)));
-         emit_insn (gen_lasx_xvpermi_d_v16hi (t4, op0, GEN_INT (0xee)));
-         emit_insn (gen_lasx_xvshuf_h (t1, mask, t4, t3));
-         emit_insn (gen_lasx_xvpermi_d_v16hi (t5, op1, GEN_INT (0x44)));
-         emit_insn (gen_lasx_xvpermi_d_v16hi (t6, op1, GEN_INT (0xee)));
-         emit_insn (gen_lasx_xvshuf_h (t2, mask, t6, t5));
-         goto merge_two;
-       }
-      return;
-
     case E_V32QImode:
       if (one_operand_shuffle)
        {
-         t1 = gen_reg_rtx (V32QImode);
-         t2 = gen_reg_rtx (V32QImode);
-         emit_insn (gen_lasx_xvpermi_d_v32qi (t1, op0, GEN_INT (0x44)));
-         emit_insn (gen_lasx_xvpermi_d_v32qi (t2, op0, GEN_INT (0xee)));
-         emit_insn (gen_lasx_xvshuf_b (target, t2, t1, mask));
+         t1 = gen_reg_rtx (mode);
+         t2 = gen_reg_rtx (mode);
+         emit_insn (gen_lasx_xvpermi_d (mode, t1, op0, GEN_INT (0x44)));
+         emit_insn (gen_lasx_xvpermi_d (mode, t2, op0, GEN_INT (0xee)));
+         emit_insn (gen_simd_vshuf (mode, target, t2, t1, mask));
        }
       else
        {
-         t1 = gen_reg_rtx (V32QImode);
-         t2 = gen_reg_rtx (V32QImode);
-         t3 = gen_reg_rtx (V32QImode);
-         t4 = gen_reg_rtx (V32QImode);
-         t5 = gen_reg_rtx (V32QImode);
-         t6 = gen_reg_rtx (V32QImode);
-         emit_insn (gen_lasx_xvpermi_d_v32qi (t3, op0, GEN_INT (0x44)));
-         emit_insn (gen_lasx_xvpermi_d_v32qi (t4, op0, GEN_INT (0xee)));
-         emit_insn (gen_lasx_xvshuf_b (t1, t4, t3, mask));
-         emit_insn (gen_lasx_xvpermi_d_v32qi (t5, op1, GEN_INT (0x44)));
-         emit_insn (gen_lasx_xvpermi_d_v32qi (t6, op1, GEN_INT (0xee)));
-         emit_insn (gen_lasx_xvshuf_b (t2, t6, t5, mask));
-         goto merge_two;
+         t1 = gen_reg_rtx (mode);
+         t2 = gen_reg_rtx (mode);
+         t3 = gen_reg_rtx (mode);
+         t4 = gen_reg_rtx (mode);
+         t5 = gen_reg_rtx (mode);
+         t6 = gen_reg_rtx (mode);
+         emit_insn (gen_lasx_xvpermi_d (mode, t3, op0, GEN_INT (0x44)));
+         emit_insn (gen_lasx_xvpermi_d (mode, t4, op0, GEN_INT (0xee)));
+         emit_insn (gen_simd_vshuf (mode, t1, t4, t3, mask));
+         emit_insn (gen_lasx_xvpermi_d (mode, t5, op1, GEN_INT (0x44)));
+         emit_insn (gen_lasx_xvpermi_d (mode, t6, op1, GEN_INT (0xee)));
+         emit_insn (gen_simd_vshuf (mode, t2, t6, t5, mask));
        }
-      return;
+      break;
 
     default:
-      gcc_assert (GET_MODE_SIZE (mode) == 32);
+      gcc_unreachable ();
       break;
     }
 
-merge_two:
+  if (one_operand_shuffle)
+    return;
+
   /* Then merge them together.  The key is whether any given control
      element contained a bit set that indicates the second word.  */
   rtx xops[6];
-- 
2.51.2

Reply via email to