[v2,6/8] LoongArch: Simplify lsx_vpick description

Message ID 20250213094204.12290-7-xry111@xry111.site
State New
Headers
Series LoongArch: SIMD odd/even/horizontal widening arithmetic cleanup and optimization |

Commit Message

Xi Ruoyao Feb. 13, 2025, 9:42 a.m. UTC
  Like what we've done for {lsx_,lasx_x}v{add,sub,mul}l{ev,od}, use
special predicates instead of hard-coded const vectors.

This is not suitable for LASX where lasx_xvpick has a different
semantic.

gcc/ChangeLog:

	* config/loongarch/simd.md (LVEC): New define_mode_attr.
	(simdfmt_as_i): Make it same as simdfmt for integer vector
	modes.
	(_f): New define_mode_attr.
	* config/loongarch/lsx.md (lsx_vpickev_b): Remove.
	(lsx_vpickev_h): Remove.
	(lsx_vpickev_w): Remove.
	(lsx_vpickev_w_f): Remove.
	(lsx_vpickod_b): Remove.
	(lsx_vpickod_h): Remove.
	(lsx_vpickod_w): Remove.
	(lsx_vpickev_w_f): Remove.
	(lsx_pick_evod_<mode>): New define_insn.
	(lsx_<x>vpick<ev_od>_<simdfmt_as_i><_f>): New
	define_expand.
---
 gcc/config/loongarch/lsx.md  | 142 ++++++-----------------------------
 gcc/config/loongarch/simd.md |  24 +++++-
 2 files changed, 47 insertions(+), 119 deletions(-)
  

Patch

diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index c7df04c6389..9d7254768ae 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -1624,125 +1624,33 @@  (define_insn "lsx_nor_<lsxfmt>"
   [(set_attr "type" "simd_logic")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "lsx_vpickev_b"
-[(set (match_operand:V16QI 0 "register_operand" "=f")
-      (vec_select:V16QI
-	(vec_concat:V32QI
-	  (match_operand:V16QI 1 "register_operand" "f")
-	  (match_operand:V16QI 2 "register_operand" "f"))
-	(parallel [(const_int 0) (const_int 2)
-		   (const_int 4) (const_int 6)
-		   (const_int 8) (const_int 10)
-		   (const_int 12) (const_int 14)
-		   (const_int 16) (const_int 18)
-		   (const_int 20) (const_int 22)
-		   (const_int 24) (const_int 26)
-		   (const_int 28) (const_int 30)])))]
-  "ISA_HAS_LSX"
-  "vpickev.b\t%w0,%w2,%w1"
-  [(set_attr "type" "simd_permute")
-   (set_attr "mode" "V16QI")])
-
-(define_insn "lsx_vpickev_h"
-[(set (match_operand:V8HI 0 "register_operand" "=f")
-      (vec_select:V8HI
-	(vec_concat:V16HI
-	  (match_operand:V8HI 1 "register_operand" "f")
-	  (match_operand:V8HI 2 "register_operand" "f"))
-	(parallel [(const_int 0) (const_int 2)
-		   (const_int 4) (const_int 6)
-		   (const_int 8) (const_int 10)
-		   (const_int 12) (const_int 14)])))]
-  "ISA_HAS_LSX"
-  "vpickev.h\t%w0,%w2,%w1"
-  [(set_attr "type" "simd_permute")
-   (set_attr "mode" "V8HI")])
-
-(define_insn "lsx_vpickev_w"
-[(set (match_operand:V4SI 0 "register_operand" "=f")
-      (vec_select:V4SI
-	(vec_concat:V8SI
-	  (match_operand:V4SI 1 "register_operand" "f")
-	  (match_operand:V4SI 2 "register_operand" "f"))
-	(parallel [(const_int 0) (const_int 2)
-		   (const_int 4) (const_int 6)])))]
-  "ISA_HAS_LSX"
-  "vpickev.w\t%w0,%w2,%w1"
-  [(set_attr "type" "simd_permute")
-   (set_attr "mode" "V4SI")])
-
-(define_insn "lsx_vpickev_w_f"
-[(set (match_operand:V4SF 0 "register_operand" "=f")
-      (vec_select:V4SF
-	(vec_concat:V8SF
-	  (match_operand:V4SF 1 "register_operand" "f")
-	  (match_operand:V4SF 2 "register_operand" "f"))
-	(parallel [(const_int 0) (const_int 2)
-		   (const_int 4) (const_int 6)])))]
-  "ISA_HAS_LSX"
-  "vpickev.w\t%w0,%w2,%w1"
-  [(set_attr "type" "simd_permute")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "lsx_vpickod_b"
-[(set (match_operand:V16QI 0 "register_operand" "=f")
-      (vec_select:V16QI
-	(vec_concat:V32QI
-	  (match_operand:V16QI 1 "register_operand" "f")
-	  (match_operand:V16QI 2 "register_operand" "f"))
-	(parallel [(const_int 1) (const_int 3)
-		   (const_int 5) (const_int 7)
-		   (const_int 9) (const_int 11)
-		   (const_int 13) (const_int 15)
-		   (const_int 17) (const_int 19)
-		   (const_int 21) (const_int 23)
-		   (const_int 25) (const_int 27)
-		   (const_int 29) (const_int 31)])))]
-  "ISA_HAS_LSX"
-  "vpickod.b\t%w0,%w2,%w1"
-  [(set_attr "type" "simd_permute")
-   (set_attr "mode" "V16QI")])
-
-(define_insn "lsx_vpickod_h"
-[(set (match_operand:V8HI 0 "register_operand" "=f")
-      (vec_select:V8HI
-	(vec_concat:V16HI
-	  (match_operand:V8HI 1 "register_operand" "f")
-	  (match_operand:V8HI 2 "register_operand" "f"))
-	(parallel [(const_int 1) (const_int 3)
-		   (const_int 5) (const_int 7)
-		   (const_int 9) (const_int 11)
-		   (const_int 13) (const_int 15)])))]
-  "ISA_HAS_LSX"
-  "vpickod.h\t%w0,%w2,%w1"
-  [(set_attr "type" "simd_permute")
-   (set_attr "mode" "V8HI")])
-
-(define_insn "lsx_vpickod_w"
-[(set (match_operand:V4SI 0 "register_operand" "=f")
-      (vec_select:V4SI
-	(vec_concat:V8SI
-	  (match_operand:V4SI 1 "register_operand" "f")
-	  (match_operand:V4SI 2 "register_operand" "f"))
-	(parallel [(const_int 1) (const_int 3)
-		   (const_int 5) (const_int 7)])))]
-  "ISA_HAS_LSX"
-  "vpickod.w\t%w0,%w2,%w1"
+;; Picking even/odd elements.
+(define_insn "lsx_pick_evod_<mode>"
+  [(set (match_operand:LSX 0 "register_operand" "=f")
+	(vec_select:LSX
+	  (vec_concat:<LVEC>
+	    (match_operand:LSX 1 "register_operand" "f")
+	    (match_operand:LSX 2 "register_operand" "f"))
+	  (match_operand:<LVEC> 3 "vect_par_cnst_even_or_odd_half")))]
+  "GET_MODE_SIZE (<UNITMODE>mode) != 8" ;; Use vilvl.d instead
+  "vpick%O3.<simdfmt_as_i>\t%<wu>0,%<wu>2,%<wu>1"
   [(set_attr "type" "simd_permute")
-   (set_attr "mode" "V4SI")])
+   (set_attr "mode" "<MODE>")])
 
-(define_insn "lsx_vpickod_w_f"
-[(set (match_operand:V4SF 0 "register_operand" "=f")
-      (vec_select:V4SF
-	(vec_concat:V8SF
-	  (match_operand:V4SF 1 "register_operand" "f")
-	  (match_operand:V4SF 2 "register_operand" "f"))
-	(parallel [(const_int 1) (const_int 3)
-		   (const_int 5) (const_int 7)])))]
-  "ISA_HAS_LSX"
-  "vpickod.w\t%w0,%w2,%w1"
-  [(set_attr "type" "simd_permute")
-   (set_attr "mode" "V4SF")])
+(define_expand "lsx_vpick<ev_od>_<simdfmt_as_i><_f>"
+  [(match_operand:LSX 0 "register_operand" "=f")
+   (match_operand:LSX 1 "register_operand" " f")
+   (match_operand:LSX 2 "register_operand" " f")
+   (const_int zero_one)]
+  "GET_MODE_SIZE (<UNITMODE>mode) != 8" ;; Use vilvl.d instead
+{
+  int nelts = GET_MODE_NUNITS (<MODE>mode);
+  rtx op3 = loongarch_gen_stepped_int_parallel (nelts, <zero_one>, 2);
+  rtx insn = gen_lsx_pick_evod_<mode> (operands[0], operands[1],
+				       operands[2], op3);
+  emit_insn (insn);
+  DONE;
+})
 
 (define_insn "popcount<mode>2"
   [(set (match_operand:ILSX 0 "register_operand" "=f")
diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index 1bf113d65be..b7a28f7b3f2 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -75,6 +75,14 @@  (define_mode_attr VEC_HALF [(V2DI "V1DI") (V4DI "V2DI")
 			    (V8HI "V4HI") (V16HI "V8HI")
 			    (V16QI "V8QI") (V32QI "V16QI")])
 
+;; Modes with doubled length for intermediate values in RTX pattern.
+(define_mode_attr LVEC [(V2DF "V4DF") (V4DF "V8DF")
+			(V4SF "V8SF") (V8SF "V16SF")
+			(V2DI "V4DI") (V4DI "V8DI")
+			(V4SI "V8SI") (V8SI "V16SI")
+			(V8HI "V16HI") (V16HI "V32HI")
+			(V16QI "V32QI") (V32QI "V64QI")])
+
 ;; The elements are widen but the total size is unchanged
 ;; (i.e. the number of elements is halfed).
 (define_mode_attr WVEC_HALF [(V2DI "V1TI") (V4DI "V2TI")
@@ -121,10 +129,22 @@  (define_mode_attr simdfmt_w [(V2DI "q") (V4DI "q")
 (define_mode_attr simdifmt_for_f [(V2DF "l") (V4DF "l")
 				  (V4SF "w") (V8SF "w")])
 
-;; Suffix for integer mode in LSX or LASX instructions to operating FP
+;; Suffix for integer mode in LSX or LASX instructions to operate FP
 ;; vectors using integer vector operations.
 (define_mode_attr simdfmt_as_i [(V2DF "d") (V4DF "d")
-				(V4SF "w") (V8SF "w")])
+				(V4SF "w") (V8SF "w")
+				(V2DI "d") (V4DI "d")
+				(V4SI "w") (V8SI "w")
+				(V8HI "h") (V16HI "h")
+				(V16QI "b") (V32QI "b")])
+
+;; "_f" for FP vectors, "" for integer vectors
+(define_mode_attr _f [(V2DF "_f") (V4DF "_f")
+		      (V4SF "_f") (V8SF "_f")
+		      (V2DI "") (V4DI "")
+		      (V4SI "") (V8SI "")
+		      (V8HI "") (V16HI "")
+		      (V16QI "") (V32QI "")])
 
 ;; Size of vector elements in bits.
 (define_mode_attr elmbits [(V2DI "64") (V4DI "64")