S/390: vec_init improvements
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Fri, 24 Mar 2017 13:54:23 +0000 (13:54 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Fri, 24 Mar 2017 13:54:23 +0000 (13:54 +0000)
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

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/config/s390/vector.md
gcc/config/s390/vx-builtins.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/vector/vec-init-2.c [new file with mode: 0644]

index ef736f5626e94ea3cdab837a9a1784ed92747ff8..7098da9ca3af6547fc4ef9cef5d4ab489e87377d 100644 (file)
@@ -1,3 +1,16 @@
+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.
index f3cebd63ef93f5fc07b5bf80792c54098915c8d8..65a75464b1c957d9e70bd2c813d8a927701f10e1 100644 (file)
@@ -6617,7 +6617,10 @@ s390_expand_vec_init (rtx target, rtx vals)
       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.  */
       emit_insn (gen_rtx_SET (target,
index 38905e86b099fbeff9d2d22b87af1942c54ea864..7ddeb9a2f9c5d5021af0c7e3dfc38d72c88798bb 100644 (file)
@@ -31,6 +31,9 @@
 ; independently e.g. vcond
 (define_mode_iterator V_HW  [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, ...)
 (define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI])
 
@@ -53,6 +56,8 @@
 (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_NOSINGLE [V16QI V8HI V4SI V4SF V2DI V2DF])
+
 ; 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
 ; for an example.
   "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
   [(set_attr "op_type" "VRS")])
 
-(define_expand "vec_init<V_HW:mode>"
-  [(match_operand:V_HW 0 "register_operand" "")
-   (match_operand:V_HW 1 "nonmemory_operand" "")]
+(define_expand "vec_init<mode>"
+  [(match_operand:V_128 0 "register_operand" "")
+   (match_operand:V_128 1 "nonmemory_operand" "")]
   "TARGET_VX"
 {
   s390_expand_vec_init (operands[0], operands[1]);
 ; Replicate from vector element
 ; vrepb, vreph, vrepf, vrepg
 (define_insn "*vec_splat<mode>"
-  [(set (match_operand:V_HW   0 "register_operand" "=v")
-       (vec_duplicate:V_HW
+  [(set (match_operand:V_128_NOSINGLE   0 "register_operand" "=v")
+       (vec_duplicate:V_128_NOSINGLE
         (vec_select:<non_vec>
-         (match_operand:V_HW 1 "register_operand"  "v")
+         (match_operand:V_128_NOSINGLE 1 "register_operand"  "v")
          (parallel
           [(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"
   [(set_attr "op_type" "VRI")])
 
 ; vlrepb, vlreph, vlrepf, vlrepg, vrepib, vrepih, vrepif, vrepig, vrepb, vreph, vrepf, vrepg
 (define_insn "*vec_splats<mode>"
-  [(set (match_operand:V_HW                          0 "register_operand" "=v,v,v,v")
-       (vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand"  " R,K,v,d")))]
+  [(set (match_operand:V_128_NOSINGLE                          0 "register_operand" "=v,v,v,v")
+       (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "general_operand"  " R,K,v,d")))]
   "TARGET_VX"
   "@
    vlrep<bhfgq>\t%v0,%1
    #"
   [(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
 ; This splitter first sets the rightmost element of op0 to op1 and
 ; then does a vec_splat to replicate that element into all other
 ; elements.
 (define_split
-  [(set (match_operand:V_HW                          0 "register_operand" "")
-       (vec_duplicate:V_HW (match_operand:<non_vec> 1 "register_operand" "")))]
+  [(set (match_operand:V_128_NOSINGLE                          0 "register_operand" "")
+       (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "register_operand" "")))]
   "TARGET_VX && GENERAL_REG_P (operands[1])"
   [(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)
-       (vec_duplicate:V_HW
+       (vec_duplicate:V_128_NOSINGLE
         (vec_select:<non_vec>
          (match_dup 0) (parallel [(match_dup 2)]))))]
 {
   operands[3] = gen_reg_rtx (V2DImode);
 })
 
-(define_insn "*vec_load_pairv2di"
-  [(set (match_operand:V2DI                0 "register_operand" "=v")
-       (vec_concat:V2DI (match_operand:DI 1 "register_operand"  "d")
-                        (match_operand:DI 2 "register_operand"  "d")))]
+(define_insn "*vec_load_pair<mode>"
+  [(set (match_operand:V_HW_64                       0 "register_operand" "=v,v")
+       (vec_concat:V_HW_64 (match_operand:<non_vec> 1 "register_operand"  "d,v")
+                           (match_operand:<non_vec> 2 "register_operand"  "d,v")))]
   "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"
   [(set (match_operand:V16QI              0 "register_operand" "=v")
index 6aff378810e204ff35871d1e4bb2bf48d92c1214..48164dae213c889faec7174681ee641de9186617 100644 (file)
@@ -20,7 +20,6 @@
 
 ; 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 VI_HW_SD [V4SI V2DI])
 (define_mode_iterator V_HW_HSD [V8HI V4SI V2DI V2DF])
index 316efb472775fe5e89800350848b84124cf566d9..359673ff6e3ed0938436a1412b311d8e14f31e84 100644 (file)
@@ -1,3 +1,7 @@
+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.
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-init-2.c b/gcc/testsuite/gcc.target/s390/vector/vec-init-2.c
new file mode 100644 (file)
index 0000000..e497210
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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 } } */