s390: Implement vec_extract via vec_select.
Commit Message
Hi,
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.
Bootstrapped and regtested. No regressions.
Is it OK?
Regards
Robin
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.
---
[(set_attr "op_type" "VRV")])
@@ -455,12 +456,13 @@ (define_insn "vec_scatter_element<V_HW_4:mode>_DI"
(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:V_HW_2 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")])
@@ -469,13 +471,14 @@ (define_insn "vec_scatter_element<V_HW_2:mode>_SI"
; 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")])
@@ -1892,9 +1895,11 @@ (define_expand "vec_st2f"
(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);
@@ -2324,10 +2329,10 @@ (define_insn "*vec_set_bswap_vec<mode>"
; *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")])
@@ -2336,11 +2341,11 @@ (define_insn "*vec_extract_bswap_vec<mode>"
; *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")])
Comments
On 8/12/22 16:19, Robin Dapp wrote:
> Hi,
>
> 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.
>
> Bootstrapped and regtested. No regressions.
>
> Is it OK?
>
> Regards
> Robin
>
> 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.
Ok. Thanks!
Andreas
@@ -153,7 +153,6 @@ (define_c_enum "unspec" [
UNSPEC_VEC_VMALO
UNSPEC_VEC_GATHER
- UNSPEC_VEC_EXTRACT
UNSPEC_VEC_INSERT_AND_ZERO
UNSPEC_VEC_LOAD_BNDRY
UNSPEC_VEC_LOAD_LEN
@@ -1744,8 +1743,8 @@ (define_split
&& 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);
@@ -264,11 +264,13 @@ (define_split
(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);
@@ -505,22 +507,24 @@ (define_insn "*vec_set<mode>_plus"
[(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))"
@@ -531,11 +535,11 @@ (define_insn "*vec_extract<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")])
@@ -440,12 +440,13 @@ (define_expand "vec_splat<mode>"
(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"