[gcc(refs/users/meissner/heads/work041)] Add support for XXSPLTIDP to load vector constants.

Michael Meissner meissner@gcc.gnu.org
Wed Mar 17 19:00:14 GMT 2021


https://gcc.gnu.org/g:6bbc906717c5946a0954ceb21ee8d013f40ba509

commit 6bbc906717c5946a0954ceb21ee8d013f40ba509
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Wed Mar 17 14:59:49 2021 -0400

    Add support for XXSPLTIDP to load vector constants.
    
    gcc/
    2021-03-17  Michael Meissner  <meissner@linux.ibm.com>
    
            * config/rs6000/predicates.md (xxspltidp_operand): Add support for
            V2DFmode.
            (easy_vector_constant): Ditto.
            * config/rs6000/rs6000.c (rs6000_expand_vector_init): Ditto.
            * config/rs6000/rs6000.md (SF_DF_V2DF): New iterator.
            (xxspltidp splitter): Add support for V2DF.
            (xxspltidp<mode>): Ditto.
            * config/rs6000/vsx.md (vsx_mov<mode>_64bit): Add support for
            vector constants loaded with XXSPLTIDP.
            (vsx_mov<mode>_32bit): Ditto.
    
    gcc/testsuite/
    2021-03-17  Michael Meissner  <meissner@linux.ibm.com>
    
            * gcc.target/powerpc/p10-v2df-const.c: New test.

Diff:
---
 gcc/config/rs6000/predicates.md                   | 43 +++++++++++++++++-----
 gcc/config/rs6000/rs6000.c                        |  6 ++--
 gcc/config/rs6000/rs6000.md                       | 37 ++++++++++++++-----
 gcc/config/rs6000/vsx.md                          | 44 +++++++++++++++--------
 gcc/testsuite/gcc.target/powerpc/p10-v2df-const.c | 35 ++++++++++++++++++
 5 files changed, 133 insertions(+), 32 deletions(-)

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index e0c0ecafece..42e20be7636 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -565,22 +565,47 @@
   (ior (match_operand 0 "vsx_register_operand")
        (match_operand 0 "reg_or_logical_cint_operand")))
 
-;; Return 1 if operand is a SF/DF CONST_DOUBLE that can be loaded via the ISA
-;; 3.1 XXSPLTIDP instruction.  This function has to check, if the immediate
-;; specifies a single-precision denormal value (i.e., bits 1:8 equal to 0 and
-;; bits 9:31 not equal to 0), since the result is undefined in the hardware.
+;; Return 1 if operand is a SF/DF CONST_DOUBLE or V2DF CONST_VECTOR that can be
+;; loaded via the ISA 3.1 XXSPLTIDP instruction.  This function has to check,
+;; if the immediate specifies a single-precision denormal value (i.e., bits 1:8
+;; equal to 0 and bits 9:31 not equal to 0), since the result is undefined in
+;; the hardware.
 (define_predicate "xxspltidp_operand"
-  (match_code "const_double")
+  (match_code "const_double,const_vector,vec_duplicate")
 {
   long value;
+  rtx element;
 
   if (!TARGET_POWER10 || !TARGET_VSX)
     return 0;
 
-  if (mode != SFmode && mode != DFmode)
+  if (mode == V2DFmode)
+    {
+      /* Handle VEC_DUPLICATE and CONST_VECTOR.  */
+      if (GET_CODE (op) == VEC_DUPLICATE)
+	element = XEXP (op, 0);
+
+      else if (GET_CODE (op) == CONST_VECTOR)
+	{
+	  element = CONST_VECTOR_ELT (op, 0);
+	  if (!rtx_equal_p (element, CONST_VECTOR_ELT (op, 1)))
+	    return 0;
+	}
+
+      else
+	return 0;
+    }
+
+  else if (mode == SFmode || mode == DFmode)
+    element = op;
+
+  else
+    return 0;
+
+  if (!CONST_DOUBLE_P (element))
     return 0;
 
-  const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (op);
+  const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (element);
   if (!exact_real_truncate (SFmode, rv))
     return 0;
 
@@ -692,7 +717,9 @@
       if (zero_constant (op, mode) || all_ones_constant (op, mode))
 	return true;
 
-      if (TARGET_POWER10 && xxspltiw_constant_p (op, mode, &constant))
+      if (TARGET_POWER10
+	  && (xxspltiw_constant_p (op, mode, &constant)
+	      || xxspltidp_operand (op, mode)))
 	return true;
 
       if (TARGET_P9_VECTOR
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ec2c0dc2f7c..8ac4bc8cbdc 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -6651,9 +6651,11 @@ rs6000_expand_vector_init (rtx target, rtx vals)
 
   if (n_var == 0)
     {
-      /* Generate XXSPLTIW if we can.  */
+      /* Generate XXSPLTIW/XXSPLTIDP if we can.  */
       if (TARGET_POWER10 && all_same
-	  && (mode == V4SImode || mode == V4SFmode))
+	  && (mode == V4SImode || mode == V4SFmode
+	      || (mode == V2DFmode
+		  && xxspltidp_operand (XVECEXP (vals, 0, 0), inner_mode))))
 	{
 	  rtx dup = gen_rtx_VEC_DUPLICATE (mode, XVECEXP (vals, 0, 0));
 	  emit_insn (gen_rtx_SET (target, dup));							 
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f25ac1ec53a..2c6296c1f18 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -573,6 +573,9 @@
 ; And again, for when we need two FP modes in a pattern.
 (define_mode_iterator SFDF2 [SF DF])
 
+; SFmode, DFmode, or V2DF.
+(define_mode_iterator SF_DF_V2DF [SF DF V2DF])
+
 ; Floating scalars that supports the set compare mask instruction.
 (define_mode_iterator FPMASK [SF
 			      DF
@@ -7529,24 +7532,42 @@
   DONE;
 })
 
-;; Load a SFmode/DFmode constant via the ISA 3.1 XXSPLTIDP instruction
+;; Load a SFmode/DFmode/V2DFmode constant via the ISA 3.1 XXSPLTIDP instruction
 (define_split
-  [(set (match_operand:SFDF 0 "vsx_register_operand")
-	(match_operand:SFDF 1 "xxspltidp_operand"))]
+  [(set (match_operand:SF_DF_V2DF 0 "vsx_register_operand")
+	(match_operand:SF_DF_V2DF 1 "xxspltidp_operand"))]
   "TARGET_POWER10 && TARGET_VSX"
   [(set (match_dup 0)
-	(unspec:SFDF [(match_dup 2)] UNSPEC_XXSPLTIDP))]
+	(unspec:SF_DF_V2DF [(match_dup 2)] UNSPEC_XXSPLTIDP))]
 {
   long value;
-  const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (operands[1]);
+  rtx op1 = operands[1];
+  rtx element;
+
+  if (<MODE>mode == V2DFmode)
+    {
+      if (GET_CODE (op1) == VEC_DUPLICATE)
+	element = XEXP (op1, 0);
+
+      else if (GET_CODE (op1) == CONST_VECTOR)
+	element = CONST_VECTOR_ELT (op1, 0);
+
+      else
+	gcc_unreachable ();
+    }
+
+  else
+    element = operands[1];
+
+  const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (element);
   REAL_VALUE_TO_TARGET_SINGLE (*rv, value);
   operands[2] = GEN_INT (value);
 })
 
 (define_insn "*xxspltidp<mode>"
-  [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
-	(unspec:SFDF [(match_operand 1 "const_int_operand" "n")]
-		     UNSPEC_XXSPLTIDP))]
+  [(set (match_operand:SF_DF_V2DF 0 "vsx_register_operand" "=wa")
+	(unspec:SF_DF_V2DF [(match_operand 1 "const_int_operand" "n")]
+			   UNSPEC_XXSPLTIDP))]
   "TARGET_POWER10 && TARGET_VSX"
   "xxspltidp %x0,%1"
   [(set_attr "type" "vecsimple")
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index a1fa4f94d51..c2153eb0bcf 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -1167,17 +1167,17 @@
 
 ;;              VSX store  VSX load   VSX move  VSX->GPR   GPR->VSX    LQ (GPR)
 ;;              STQ (GPR)  GPR load   GPR store GPR move   XXSPLTIB    VSPLTISW
-;;              VSX 0/-1   VMX const  GPR const LVX (VMX)  STVX (VMX)
+;;              VSX 0/-1   VMX const  GPR const LVX (VMX)  STVX (VMX)  XXSPLTIDP
 (define_insn "vsx_mov<mode>_64bit"
   [(set (match_operand:VSX_M 0 "nonimmediate_operand"
                "=ZwO,      wa,        wa,        r,         we,        ?wQ,
                 ?&r,       ??r,       ??Y,       <??r>,     wa,        v,
-                ?wa,       v,         <??r>,     wZ,        v")
+                ?wa,       v,         <??r>,     wZ,        v,         wa")
 
 	(match_operand:VSX_M 1 "input_operand" 
                "wa,        ZwO,       wa,        we,        r,         r,
                 wQ,        Y,         r,         r,         wE,        jwM,
-                ?jwM,      W,         <nW>,      v,         wZ"))]
+                ?jwM,      W,         <nW>,      v,         wZ,        eF"))]
 
   "TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
    && (register_operand (operands[0], <MODE>mode) 
@@ -1188,36 +1188,44 @@
   [(set_attr "type"
                "vecstore,  vecload,   vecsimple, mtvsr,     mfvsr,     load,
                 store,     load,      store,     *,         vecsimple, vecsimple,
-                vecsimple, *,         *,         vecstore,  vecload")
+                vecsimple, *,         *,         vecstore,  vecload,   vecsimple")
    (set_attr "num_insns"
                "*,         *,         *,         2,         *,         2,
                 2,         2,         2,         2,         *,         *,
-                *,         5,         2,         *,         *")
+                *,         5,         2,         *,         *,         *")
    (set_attr "max_prefixed_insns"
                "*,         *,         *,         *,         *,         2,
                 2,         2,         2,         2,         *,         *,
-                *,         *,         *,         *,         *")
+                *,         *,         *,         *,         *,         *")
    (set_attr "length"
                "*,         *,         *,         8,         *,         8,
                 8,         8,         8,         8,         *,         *,
-                *,         20,        8,         *,         *")
+                *,         20,        8,         *,         *,         *")
    (set_attr "isa"
                "<VSisa>,   <VSisa>,   <VSisa>,   *,         *,         *,
                 *,         *,         *,         *,         p9v,       *,
-                <VSisa>,   *,         *,         *,         *")])
+                <VSisa>,   *,         *,         *,         *,         p10")
+   (set_attr "prefixed"
+               "*,         *,         *,         *,         *,         *,
+                *,         *,         *,         *,         *,         *,
+                *,         *,         *,         *,         *,         yes")
+   (set_attr "prefixed_prepend_p"
+               "*,         *,         *,         *,         *,         *,
+                *,         *,         *,         *,         *,         *,
+                *,         *,         *,         *,         *,         no")])
 
 ;;              VSX store  VSX load   VSX move   GPR load   GPR store  GPR move
-;;              XXSPLTIB   VSPLTISW   VSX 0/-1   VMX const  GPR const
+;;              XXSPLTIB   VSPLTISW   VSX 0/-1   VMX const  GPR const  XXSPLTIDP
 ;;              LVX (VMX)  STVX (VMX)
 (define_insn "*vsx_mov<mode>_32bit"
   [(set (match_operand:VSX_M 0 "nonimmediate_operand"
                "=ZwO,      wa,        wa,        ??r,       ??Y,       <??r>,
-                wa,        v,         ?wa,       v,         <??r>,
+                wa,        v,         ?wa,       v,         <??r>,     wa,
                 wZ,        v")
 
 	(match_operand:VSX_M 1 "input_operand" 
                "wa,        ZwO,       wa,        Y,         r,         r,
-                wE,        jwM,       ?jwM,      W,         <nW>,
+                wE,        jwM,       ?jwM,      W,         <nW>,      eF,
                 v,         wZ"))]
 
   "!TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
@@ -1228,15 +1236,23 @@
 }
   [(set_attr "type"
                "vecstore,  vecload,   vecsimple, load,      store,    *,
-                vecsimple, vecsimple, vecsimple, *,         *,
+                vecsimple, vecsimple, vecsimple, *,         *,        vecsimple,
                 vecstore,  vecload")
    (set_attr "length"
                "*,         *,         *,         16,        16,        16,
-                *,         *,         *,         20,        16,
+                *,         *,         *,         20,        16,        *,
                 *,         *")
    (set_attr "isa"
                "<VSisa>,   <VSisa>,   <VSisa>,   *,         *,         *,
-                p9v,       *,         <VSisa>,   *,         *,
+                p9v,       *,         <VSisa>,   *,         *,         p10,
+                *,         *")
+   (set_attr "prefixed"
+               "*,         *,         *,         *,         *,         *,
+                *,         *,         *,         *,         *,         yes,
+                *,         *")
+   (set_attr "prefixed_prepend_p"
+               "*,         *,         *,         *,         *,         *,
+                *,         *,         *,         *,         *,         no,
                 *,         *")])
 
 ;; Explicit  load/store expanders for the builtin functions
diff --git a/gcc/testsuite/gcc.target/powerpc/p10-v2df-const.c b/gcc/testsuite/gcc.target/powerpc/p10-v2df-const.c
new file mode 100644
index 00000000000..e82f2f5c59a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p10-v2df-const.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Test generating XXSPLTIDP on power10 for V2DF vectors.  */
+
+#include <altivec.h>
+
+vector double
+init_zero (void)
+{
+  return (vector double) { 0.0, 0.0 };			/* XXSPLTIB  */
+}
+
+vector double
+init_one (void)
+{
+  return (vector double) { 1.0, 1.0 };			/* XXSPLTIDP  */
+}
+
+vector double
+splat_zero (void)
+{
+  return vec_splats (0.0);				/* XXSPLTIB  */
+}
+
+vector double
+splat_one (void)
+{
+  return vec_splats (1.0);				/* XXSPLTIDP  */
+}
+
+/* { dg-final { scan-assembler-times {\mxxlxor|vspltiw|xxspltib\M}  2 } } */
+/* { dg-final { scan-assembler-times {\mxxspltidp\M}                2 } } */
+/* { dg-final { scan-assembler-not   {\mp?lxvx?\M}                    } } */


More information about the Gcc-cvs mailing list