Commit a602f985 by Andreas Krebbel Committed by Andreas Krebbel

S/390: vec_init improvements

This enables the vec_init pattern also for V4SF, V1TI, and V1TF.

gcc/testsuite/ChangeLog:

2017-03-24  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

	* gcc.target/s390/vector/vec-init-2.c: New test.

gcc/ChangeLog:

2017-03-24  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

	* config/s390/s390.c (s390_expand_vec_init): Enable vector load
	pair for all vector types with 64 bit elements.
	* config/s390/vx-builtins.md (V_HW_64): Move mode iterator to ...
	* config/s390/vector.md (V_HW_64): ... here.
	(V_128_NOSINGLE): New mode iterator.
	("vec_init<V_HW:mode>"): Use V_128 as mode iterator.
	("*vec_splat<mode>"): Use V_128_NOSINGLE mode iterator.
	("*vec_tf_to_v1tf", "*vec_ti_to_v1ti"): New pattern definitions.
	("*vec_load_pairv2di"): Change to ...
	("*vec_load_pair<mode>"): ... this one.

From-SVN: r246446
parent 9d605427
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com> 2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/s390.c (s390_expand_vec_init): Enable vector load
pair for all vector types with 64 bit elements.
* config/s390/vx-builtins.md (V_HW_64): Move mode iterator to ...
* config/s390/vector.md (V_HW_64): ... here.
(V_128_NOSINGLE): New mode iterator.
("vec_init<V_HW:mode>"): Use V_128 as mode iterator.
("*vec_splat<mode>"): Use V_128_NOSINGLE mode iterator.
("*vec_tf_to_v1tf", "*vec_ti_to_v1ti"): New pattern definitions.
("*vec_load_pairv2di"): Change to ...
("*vec_load_pair<mode>"): ... this one.
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/constraints.md: Add comments. * config/s390/constraints.md: Add comments.
(jKK): Reject element sizes > 8 bytes. (jKK): Reject element sizes > 8 bytes.
* config/s390/s390.c (s390_split_ok_p): Enable splitting also for * config/s390/s390.c (s390_split_ok_p): Enable splitting also for
......
...@@ -6617,7 +6617,10 @@ s390_expand_vec_init (rtx target, rtx vals) ...@@ -6617,7 +6617,10 @@ s390_expand_vec_init (rtx target, rtx vals)
return; return;
} }
if (all_regs && REG_P (target) && n_elts == 2 && inner_mode == DImode) if (all_regs
&& REG_P (target)
&& n_elts == 2
&& GET_MODE_SIZE (inner_mode) == 8)
{ {
/* Use vector load pair. */ /* Use vector load pair. */
emit_insn (gen_rtx_SET (target, emit_insn (gen_rtx_SET (target,
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
; independently e.g. vcond ; independently e.g. vcond
(define_mode_iterator V_HW [V16QI V8HI V4SI V2DI V2DF]) (define_mode_iterator V_HW [V16QI V8HI V4SI V2DI V2DF])
(define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF]) (define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF])
(define_mode_iterator V_HW_64 [V2DI V2DF])
; Including TI for instructions that support it (va, vn, ...) ; Including TI for instructions that support it (va, vn, ...)
(define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI]) (define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI])
...@@ -53,6 +56,8 @@ ...@@ -53,6 +56,8 @@
(define_mode_iterator V_64 [V8QI V4HI V2SI V2SF V1DI V1DF]) (define_mode_iterator V_64 [V8QI V4HI V2SI V2SF V1DI V1DF])
(define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF]) (define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF])
(define_mode_iterator V_128_NOSINGLE [V16QI V8HI V4SI V4SF V2DI V2DF])
; A blank for vector modes and a * for TImode. This is used to hide ; A blank for vector modes and a * for TImode. This is used to hide
; the TImode expander name in case it is defined already. See addti3 ; the TImode expander name in case it is defined already. See addti3
; for an example. ; for an example.
...@@ -437,9 +442,9 @@ ...@@ -437,9 +442,9 @@
"vlgv<bhfgq>\t%0,%v1,%Y3(%2)" "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
[(set_attr "op_type" "VRS")]) [(set_attr "op_type" "VRS")])
(define_expand "vec_init<V_HW:mode>" (define_expand "vec_init<mode>"
[(match_operand:V_HW 0 "register_operand" "") [(match_operand:V_128 0 "register_operand" "")
(match_operand:V_HW 1 "nonmemory_operand" "")] (match_operand:V_128 1 "nonmemory_operand" "")]
"TARGET_VX" "TARGET_VX"
{ {
s390_expand_vec_init (operands[0], operands[1]); s390_expand_vec_init (operands[0], operands[1]);
...@@ -449,20 +454,20 @@ ...@@ -449,20 +454,20 @@
; Replicate from vector element ; Replicate from vector element
; vrepb, vreph, vrepf, vrepg ; vrepb, vreph, vrepf, vrepg
(define_insn "*vec_splat<mode>" (define_insn "*vec_splat<mode>"
[(set (match_operand:V_HW 0 "register_operand" "=v") [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v")
(vec_duplicate:V_HW (vec_duplicate:V_128_NOSINGLE
(vec_select:<non_vec> (vec_select:<non_vec>
(match_operand:V_HW 1 "register_operand" "v") (match_operand:V_128_NOSINGLE 1 "register_operand" "v")
(parallel (parallel
[(match_operand:QI 2 "const_mask_operand" "C")]))))] [(match_operand:QI 2 "const_mask_operand" "C")]))))]
"TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW:MODE>mode)" "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<MODE>mode)"
"vrep<bhfgq>\t%v0,%v1,%2" "vrep<bhfgq>\t%v0,%v1,%2"
[(set_attr "op_type" "VRI")]) [(set_attr "op_type" "VRI")])
; vlrepb, vlreph, vlrepf, vlrepg, vrepib, vrepih, vrepif, vrepig, vrepb, vreph, vrepf, vrepg ; vlrepb, vlreph, vlrepf, vlrepg, vrepib, vrepih, vrepif, vrepig, vrepb, vreph, vrepf, vrepg
(define_insn "*vec_splats<mode>" (define_insn "*vec_splats<mode>"
[(set (match_operand:V_HW 0 "register_operand" "=v,v,v,v") [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v,v,v,v")
(vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand" " R,K,v,d")))] (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "general_operand" " R,K,v,d")))]
"TARGET_VX" "TARGET_VX"
"@ "@
vlrep<bhfgq>\t%v0,%1 vlrep<bhfgq>\t%v0,%1
...@@ -471,18 +476,45 @@ ...@@ -471,18 +476,45 @@
#" #"
[(set_attr "op_type" "VRX,VRI,VRI,*")]) [(set_attr "op_type" "VRX,VRI,VRI,*")])
; A TFmode operand resides in FPR register pairs while V1TF is in a
; single vector register.
(define_insn "*vec_tf_to_v1tf"
[(set (match_operand:V1TF 0 "nonimmediate_operand" "=v,v,R,v,v")
(vec_duplicate:V1TF (match_operand:TF 1 "general_operand" "v,R,v,G,d")))]
"TARGET_VX"
"@
vmrhg\t%v0,%1,%N1
vl\t%v0,%1
vst\t%v1,%0
vzero\t%v0
vlvgp\t%v0,%1,%N1"
[(set_attr "op_type" "VRR,VRX,VRX,VRI,VRR")])
(define_insn "*vec_ti_to_v1ti"
[(set (match_operand:V1TI 0 "nonimmediate_operand" "=v,v,R, v, v,v")
(vec_duplicate:V1TI (match_operand:TI 1 "general_operand" "v,R,v,j00,jm1,d")))]
"TARGET_VX"
"@
vlr\t%v0,%v1
vl\t%v0,%1
vst\t%v1,%0
vzero\t%v0
vone\t%v0
vlvgp\t%v0,%1,%N1"
[(set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRR")])
; vec_splats is supposed to replicate op1 into all elements of op0 ; vec_splats is supposed to replicate op1 into all elements of op0
; This splitter first sets the rightmost element of op0 to op1 and ; This splitter first sets the rightmost element of op0 to op1 and
; then does a vec_splat to replicate that element into all other ; then does a vec_splat to replicate that element into all other
; elements. ; elements.
(define_split (define_split
[(set (match_operand:V_HW 0 "register_operand" "") [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "")
(vec_duplicate:V_HW (match_operand:<non_vec> 1 "register_operand" "")))] (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "register_operand" "")))]
"TARGET_VX && GENERAL_REG_P (operands[1])" "TARGET_VX && GENERAL_REG_P (operands[1])"
[(set (match_dup 0) [(set (match_dup 0)
(unspec:V_HW [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET)) (unspec:V_128_NOSINGLE [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET))
(set (match_dup 0) (set (match_dup 0)
(vec_duplicate:V_HW (vec_duplicate:V_128_NOSINGLE
(vec_select:<non_vec> (vec_select:<non_vec>
(match_dup 0) (parallel [(match_dup 2)]))))] (match_dup 0) (parallel [(match_dup 2)]))))]
{ {
...@@ -1129,13 +1161,15 @@ ...@@ -1129,13 +1161,15 @@
operands[3] = gen_reg_rtx (V2DImode); operands[3] = gen_reg_rtx (V2DImode);
}) })
(define_insn "*vec_load_pairv2di" (define_insn "*vec_load_pair<mode>"
[(set (match_operand:V2DI 0 "register_operand" "=v") [(set (match_operand:V_HW_64 0 "register_operand" "=v,v")
(vec_concat:V2DI (match_operand:DI 1 "register_operand" "d") (vec_concat:V_HW_64 (match_operand:<non_vec> 1 "register_operand" "d,v")
(match_operand:DI 2 "register_operand" "d")))] (match_operand:<non_vec> 2 "register_operand" "d,v")))]
"TARGET_VX" "TARGET_VX"
"vlvgp\t%v0,%1,%2" "@
[(set_attr "op_type" "VRR")]) vlvgp\t%v0,%1,%2
vmrhg\t%v0,%v1,%v2"
[(set_attr "op_type" "VRR,VRR")])
(define_insn "vllv16qi" (define_insn "vllv16qi"
[(set (match_operand:V16QI 0 "register_operand" "=v") [(set (match_operand:V16QI 0 "register_operand" "=v")
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
; The patterns in this file are enabled with -mzvector ; The patterns in this file are enabled with -mzvector
(define_mode_iterator V_HW_64 [V2DI V2DF])
(define_mode_iterator V_HW_32_64 [V4SI V2DI V2DF]) (define_mode_iterator V_HW_32_64 [V4SI V2DI V2DF])
(define_mode_iterator VI_HW_SD [V4SI V2DI]) (define_mode_iterator VI_HW_SD [V4SI V2DI])
(define_mode_iterator V_HW_HSD [V8HI V4SI V2DI V2DF]) (define_mode_iterator V_HW_HSD [V8HI V4SI V2DI V2DF])
......
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com> 2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* gcc.target/s390/vector/vec-init-2.c: New test.
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* gcc.dg/ubsan/pr79904-2.c: New test. * gcc.dg/ubsan/pr79904-2.c: New test.
2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com> 2017-03-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
......
/* Check that the vec_init expander does its job. */
/* { dg-do compile } */
/* { dg-options "-O3 -mzarch -march=z13" } */
/* { dg-require-effective-target int128 } */
typedef __attribute__((vector_size(16))) double v2df;
typedef __attribute__((vector_size(16))) long long v2di;
typedef __attribute__((vector_size(16))) long double v1tf;
typedef __attribute__((vector_size(16))) __int128 v1ti;
v1tf gld;
v1tf
f (long double a)
{
return (v1tf){ a };
}
v1ti
g (__int128 a)
{
return (v1ti){ a };
}
/* { dg-final { scan-assembler-times "vl\t" 2 } } */
v1tf
h ()
{
long double a;
asm volatile ("" : "=f" (a));
return (v1tf){ a };
}
/* { dg-final { scan-assembler-times "vmrhg\t" 1 } } */
v1ti
i ()
{
__int128 a;
asm volatile ("" : "=d" (a));
return (v1ti){ a };
}
/* { dg-final { scan-assembler-times "vlvgp\t" 1 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment