s390: Implement vec_extract via vec_select.
authorRobin Dapp <rdapp@linux.ibm.com>
Mon, 4 Jul 2022 12:19:29 +0000 (14:19 +0200)
committerRobin Dapp <rdapp@linux.ibm.com>
Mon, 29 Aug 2022 09:15:09 +0000 (11:15 +0200)
vec_select can handle dynamic/runtime masks nowadays.  Therefore we can
get rid of the UNSPEC_VEC_EXTRACT that was preventing further
optimizations like combining instructions with vec_extract patterns.

gcc/ChangeLog:

* config/s390/s390.md: Remove UNSPEC_VEC_EXTRACT.
* config/s390/vector.md: Rewrite patterns to use vec_select.
* config/s390/vx-builtins.md (vec_scatter_element<V_HW_2:mode>_SI):
Likewise.

gcc/config/s390/s390.md
gcc/config/s390/vector.md
gcc/config/s390/vx-builtins.md

index aaa247d..962927c 100644 (file)
    UNSPEC_VEC_VMALO
 
    UNSPEC_VEC_GATHER
-   UNSPEC_VEC_EXTRACT
    UNSPEC_VEC_INSERT_AND_ZERO
    UNSPEC_VEC_LOAD_BNDRY
    UNSPEC_VEC_LOAD_LEN
    && GENERAL_REG_P (operands[0])
    && VECTOR_REG_P (operands[1])"
   [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
-                                UNSPEC_VEC_EXTRACT))]
+   (set (match_dup 3) (vec_select:DI (match_dup 5)
+                      (parallel [(const_int 1)])))]
 {
   operands[2] = operand_subword (operands[0], 0, 0, TImode);
   operands[3] = operand_subword (operands[0], 1, 0, TImode);
index b6a3da6..dde74af 100644 (file)
        (match_operand:V_128 1 "register_operand" ""))]
   "TARGET_VX && GENERAL_REG_P (operands[0]) && VECTOR_REG_P (operands[1])"
   [(set (match_dup 2)
-       (unspec:DI [(subreg:V2DI (match_dup 1) 0)
-                   (const_int 0)] UNSPEC_VEC_EXTRACT))
+       (vec_select:DI
+         (subreg:V2DI (match_dup 1) 0)
+           (parallel [(const_int 0)])))
    (set (match_dup 3)
-       (unspec:DI [(subreg:V2DI (match_dup 1) 0)
-                   (const_int 1)] UNSPEC_VEC_EXTRACT))]
+       (vec_select:DI
+         (subreg:V2DI (match_dup 1) 0)
+           (parallel [(const_int 1)])))]
 {
   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
   [(set_attr "op_type" "VRS")])
 
 
-; FIXME: Support also vector mode operands for 0
-; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :(
-; This is used via RTL standard name as well as for expanding the builtin
+;; FIXME: Support also vector mode operands for 0
+;; This is used via RTL standard name as well as for expanding the builtin
 (define_expand "vec_extract<mode><non_vec_l>"
-  [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "")
-       (unspec:<non_vec> [(match_operand:V  1 "register_operand" "")
-                          (match_operand:SI 2 "nonmemory_operand" "")]
-                         UNSPEC_VEC_EXTRACT))]
-  "TARGET_VX")
+  [(set (match_operand:<non_vec>    0 "nonimmediate_operand" "")
+       (vec_select:<non_vec>
+         (match_operand:V           1 "register_operand" "")
+         (parallel
+          [(match_operand:SI        2 "nonmemory_operand" "")])))]
+  "TARGET_VX"
+)
 
 ; vlgvb, vlgvh, vlgvf, vlgvg, vsteb, vsteh, vstef, vsteg
 (define_insn "*vec_extract<mode>"
-  [(set (match_operand:<non_vec> 0 "nonimmediate_operand"          "=d,R")
-       (unspec:<non_vec> [(match_operand:V  1 "register_operand"   "v,v")
-                          (match_operand:SI 2 "nonmemory_operand" "an,I")]
-                         UNSPEC_VEC_EXTRACT))]
+  [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,R")
+       (vec_select:<non_vec>
+         (match_operand:V        1 "nonmemory_operand"  "v,v")
+         (parallel
+          [(match_operand:SI     2 "nonmemory_operand" "an,I")])))]
   "TARGET_VX
    && (!CONST_INT_P (operands[2])
        || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
 
 ; vlgvb, vlgvh, vlgvf, vlgvg
 (define_insn "*vec_extract<mode>_plus"
-  [(set (match_operand:<non_vec>                      0 "nonimmediate_operand" "=d")
-       (unspec:<non_vec> [(match_operand:V           1 "register_operand"      "v")
-                          (plus:SI (match_operand:SI 2 "nonmemory_operand"     "a")
-                                   (match_operand:SI 3 "const_int_operand"     "n"))]
-                          UNSPEC_VEC_EXTRACT))]
+  [(set (match_operand:<non_vec>       0 "nonimmediate_operand" "=d")
+       (vec_select:<non_vec>
+        (match_operand:V              1 "register_operand"      "v")
+        (plus:SI (match_operand:SI    2 "nonmemory_operand"     "a")
+         (parallel [(match_operand:SI 3 "const_int_operand"     "n")]))))]
   "TARGET_VX"
   "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
   [(set_attr "op_type" "VRS")])
index 69ce00b..d20771d 100644 (file)
 (define_insn "vec_scatter_element<V_HW_4:mode>_DI"
   [(set (mem:<non_vec>
         (plus:DI (zero_extend:DI
-                  (unspec:SI [(match_operand:V4SI 1 "register_operand"   "v")
-                              (match_operand:QI   3 "const_mask_operand" "C")]
-                             UNSPEC_VEC_EXTRACT))
-                 (match_operand:SI                2 "address_operand"   "ZQ")))
-       (unspec:<non_vec> [(match_operand:V_HW_4          0 "register_operand"   "v")
-                          (match_dup 3)] UNSPEC_VEC_EXTRACT))]
+                  (vec_select:SI
+                   (match_operand:V4SI           1 "register_operand"   "v")
+                   (parallel [(match_operand:QI  3 "const_mask_operand" "C")])))
+         (match_operand:SI                       2 "address_operand"    "ZQ")))
+       (vec_select:<non_vec>
+        (match_operand:V_HW_4                    0 "register_operand"   "v")
+        (parallel [(match_dup 3)])))]
   "TARGET_VX && TARGET_64BIT && UINTVAL (operands[3]) < 4"
   "vscef\t%v0,%O2(%v1,%R2),%3"
   [(set_attr "op_type" "VRV")])
 (define_insn "vec_scatter_element<V_HW_2:mode>_SI"
   [(set (mem:<non_vec>
         (plus:SI (subreg:SI
-                  (unspec:<non_vec_int> [(match_operand:V_HW_2 1 "register_operand"   "v")
-                                         (match_operand:QI     3 "const_mask_operand" "C")]
-                                        UNSPEC_VEC_EXTRACT) 4)
-                 (match_operand:SI                             2 "address_operand"   "ZQ")))
-       (unspec:<non_vec> [(match_operand:V_HW_2                0 "register_operand"   "v")
-                          (match_dup 3)] UNSPEC_VEC_EXTRACT))]
+                  (vec_select:<non_vec_int>
+                   (match_operand:<TOINTVEC>     1 "register_operand"   "v")
+                   (parallel [(match_operand:QI  3 "const_mask_operand" "C")])) 4)
+         (match_operand:SI                       2 "address_operand"    "ZQ")))
+    (vec_select:<non_vec>
+     (match_operand:V_HW_2                        0 "register_operand"   "v")
+     (parallel [(match_dup 3)])))]
   "TARGET_VX && !TARGET_64BIT && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_2:MODE>mode)"
   "vsce<V_HW_2:bhfgq>\t%v0,%O2(%v1,%R2),%3"
   [(set_attr "op_type" "VRV")])
 ; vscef, vsceg
 (define_insn "vec_scatter_element<mode>_<non_vec_int>"
   [(set (mem:<non_vec>
-        (plus:<non_vec_int> (unspec:<non_vec_int>
-                             [(match_operand:<TOINTVEC> 1 "register_operand"   "v")
-                              (match_operand:QI         3 "const_mask_operand" "C")]
-                             UNSPEC_VEC_EXTRACT)
-                            (match_operand:DI           2 "address_operand"   "ZQ")))
-       (unspec:<non_vec> [(match_operand:V_HW_32_64     0 "register_operand"   "v")
-                          (match_dup 3)] UNSPEC_VEC_EXTRACT))]
+        (plus:<non_vec_int>
+         (vec_select:<non_vec_int>
+          (match_operand:<TOINTVEC>      1 "register_operand"   "v")
+           (parallel [(match_operand:QI  3 "const_mask_operand" "C")]))
+         (match_operand:DI               2 "address_operand"   "ZQ")))
+       (vec_select:<non_vec>
+        (match_operand:V_HW_32_64        0 "register_operand"   "v")
+        (parallel [(match_dup 3)])))]
   "TARGET_VX && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
   "vsce<bhfgq>\t%v0,%O2(%v1,%R2),%3"
   [(set_attr "op_type" "VRV")])
                      (const_int VEC_RND_CURRENT)]
                     UNSPEC_VEC_VFLR))
    (set (match_operand:SF 1 "memory_operand" "")
-       (unspec:SF [(match_dup 2) (const_int 0)] UNSPEC_VEC_EXTRACT))
+       (vec_select:SF (match_dup 2)
+        (parallel [(const_int 0)])))
    (set (match_dup 3)
-       (unspec:SF [(match_dup 2) (const_int 2)] UNSPEC_VEC_EXTRACT))]
+       (vec_select:SF (match_dup 2)
+        (parallel [(const_int 2)])))]
   "TARGET_VX"
 {
   operands[2] = gen_reg_rtx (V4SFmode);
 ; *a = vec_revb (b)[1];                            get-element-bswap-4.c
 ; vstebrh, vstebrf, vstebrg
 (define_insn "*vec_extract_bswap_vec<mode>"
-  [(set (match_operand:<non_vec>                                    0 "memory_operand"   "=R")
-       (unspec:<non_vec> [(bswap:V_HW_HSD (match_operand:V_HW_HSD  1 "register_operand"  "v"))
-                          (match_operand:SI                        2 "const_int_operand" "C")]
-                          UNSPEC_VEC_EXTRACT))]
+  [(set (match_operand:<non_vec>                  0 "memory_operand"   "=R")
+       (vec_select:<non_vec>
+        (bswap:V_HW_HSD (match_operand:V_HW_HSD  1 "register_operand"  "v"))
+        (parallel [(match_operand:SI             2 "const_int_operand" "C")])))]
   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
   "vstebr<bhfgq>\t%v1,%0,%2"
   [(set_attr "op_type" "VRX")])
 ; *a = __builtin_bswap32 (b[1]);                   get-element-bswap-2.c
 ; vstebrh, vstebrf, vstebrg
 (define_insn "*vec_extract_bswap_elem<mode>"
-  [(set (match_operand:<non_vec>                     0 "memory_operand"   "=R")
+  [(set (match_operand:<non_vec>                  0 "memory_operand"   "=R")
        (bswap:<non_vec>
-        (unspec:<non_vec> [(match_operand:V_HW_HSD  1 "register_operand"  "v")
-                           (match_operand:SI        2 "const_int_operand" "C")]
-                          UNSPEC_VEC_EXTRACT)))]
+        (vec_select:<non_vec>
+         (match_operand:V_HW_HSD                 1 "register_operand"  "v")
+         (parallel [(match_operand:SI            2 "const_int_operand" "C")]))))]
   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
   "vstebr<bhfgq>\t%v1,%0,%2"
   [(set_attr "op_type" "VRX")])