[gcc(refs/users/meissner/heads/work043)] Load SF/DF constants with ISA 3.1 XXSPLTIDP

Michael Meissner meissner@gcc.gnu.org
Tue Mar 30 20:26:32 GMT 2021


https://gcc.gnu.org/g:709a91c7d105444e06496f4cbba0fa612dab05f4

commit 709a91c7d105444e06496f4cbba0fa612dab05f4
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Tue Mar 30 16:26:11 2021 -0400

    Load SF/DF constants with ISA 3.1 XXSPLTIDP
    
    This patch uses the XXSPLTIDP instruction to load up SFmode/DFmode constants
    that can be expressed exactly as single precision constants.  Denormal values
    are not allowed, since these are undefined in the ISA.
    
    gcc/
    2021-03-30  Michael Meissner  <meissner@linux.ibm.com>
    
            * config/rs6000/constraint.md (eF constraint): New constraint.
            * config/rs6000/predicates.md (xxspltidp_operand): New predicate.
            (easy_fp_constant): Constants that we can load with XXSPLTIDP are
            considered easy constants.
            * config/rs6000/rs6000.md (SF/DF load constant splitter): New
            splitter for constants loaded with XXSPLTIDP.
            (xxspltidp<mode>): New insn to emit XXSPLTIDP.
            (movsf_hardfloat): Add support for loading constants with
            XXSPLTIDP.
            (mov<mode>_hardfloat32): Add support for loading constants with
            XXSPLTIDP.
            (mov<mode>_hardfloat64): Add support for loading constants with
            XXSPLTIDP.

Diff:
---
 gcc/config/rs6000/constraints.md |  4 ++
 gcc/config/rs6000/predicates.md  | 36 ++++++++++++++++
 gcc/config/rs6000/rs6000.md      | 91 ++++++++++++++++++++++++++++++++--------
 3 files changed, 113 insertions(+), 18 deletions(-)

diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index 561ce9797af..47f161df82e 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -229,6 +229,10 @@
   (and (match_code "const_double")
        (match_test "num_insns_constant (op, mode) == 3")))
 
+(define_constraint "eF"
+  "A floating point constant that can be loaded with XXSPLTIDP."
+  (match_operand 0 "xxspltidp_operand"))
+
 ;; Memory constraints
 
 ; Actually defined in common.md:
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 0c5d7a096f3..089a2597ce7 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -565,6 +565,37 @@
   (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.
+(define_predicate "xxspltidp_operand"
+  (match_code "const_double")
+{
+  long value;
+
+  if (!TARGET_POWER10 || !TARGET_VSX)
+    return 0;
+
+  if (mode != SFmode && mode != DFmode)
+    return 0;
+
+  if (!CONST_DOUBLE_P (op))
+    return 0;
+
+  const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (op);
+  if (!exact_real_truncate (SFmode, rv))
+    return 0;
+
+  REAL_VALUE_TO_TARGET_SINGLE (*rv, value);
+
+  /* Test for SFmode denormal (exponent is 0, mantissa field is non-zero).  */
+  if (((value & 0x7F800000) == 0) && ((value & 0x7FFFFF) != 0))
+    return 0;
+
+  return 1;
+})
+
 ;; Return 1 if operand is a CONST_DOUBLE that can be set in a register
 ;; with no more than one instruction per word.
 (define_predicate "easy_fp_constant"
@@ -601,6 +632,11 @@
   if (TARGET_VSX && op == CONST0_RTX (mode))
     return 1;
 
+  /* If we have the ISA 3.1 XXSPLTIDP instruction, see if the constant can
+     be loaded with that instruction.  */
+  if (xxspltidp_operand (op, mode))
+    return 1;
+
   /* Otherwise consider floating point constants hard, so that the
      constant gets pushed to memory during the early RTL phases.  This
      has the advantage that double precision constants that can be
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 5df9eb7500d..1bbb17bef7d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7530,6 +7530,32 @@
   DONE;
 })
 
+;; Convert a load of a SFmode/DFmode constant to use the ISA 3.1 XXSPLTIDP
+;; instruction if we can.  We don't do this for 0.0 to allow the move patterns
+;; to generate the smaller XXSPLTIB/VSPLTISW/XXLXOR to zero the register.
+(define_split
+  [(set (match_operand:SFDF 0 "vsx_register_operand")
+	(match_operand:SFDF 1 "xxspltidp_operand"))]
+  "TARGET_POWER10 && TARGET_VSX && operands[1] != CONST0_RTX (<MODE>mode)"
+  [(set (match_dup 0)
+	(unspec:SFDF [(match_dup 2)] UNSPEC_XXSPLTID))]
+{
+  long value;
+  const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (operands[1]);
+  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_XXSPLTID))]
+  "TARGET_POWER10 && TARGET_VSX"
+  "xxspltidp %x0,%1"
+  [(set_attr "type" "vecperm")
+   (set_attr "prefixed" "yes")
+   (set_attr "prefixed_prepend_p" "no")])
+
 (define_split
   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
 	(match_operand:FMOVE32 1 "const_double_operand"))]
@@ -7563,17 +7589,17 @@
 ;;
 ;;	LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
 ;;	STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
-;;	MR           MT<x>      MF<x>       NOP
+;;	MR           MT<x>      MF<x>       NOP        XXSPLTIDP
 
 (define_insn "movsf_hardfloat"
   [(set (match_operand:SF 0 "nonimmediate_operand"
 	 "=!r,       f,         v,          wa,        m,         wY,
 	  Z,         m,         wa,         !r,        f,         wa,
-	  !r,        *c*l,      !r,         *h")
+	  !r,        *c*l,      !r,         *h,        wa")
 	(match_operand:SF 1 "input_operand"
 	 "m,         m,         wY,         Z,         f,         v,
 	  wa,        r,         j,          j,         f,         wa,
-	  r,         r,         *h,         0"))]
+	  r,         r,         *h,         0,         eF"))]
   "(register_operand (operands[0], SFmode)
    || register_operand (operands[1], SFmode))
    && TARGET_HARD_FLOAT
@@ -7595,15 +7621,24 @@
    mr %0,%1
    mt%0 %1
    mf%1 %0
-   nop"
+   nop
+   #"
   [(set_attr "type"
 	"load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
 	 fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
-	 *,          mtjmpr,    mfjmpr,     *")
+	 *,          mtjmpr,    mfjmpr,     *,         vecperm")
    (set_attr "isa"
 	"*,          *,         p9v,        p8v,       *,         p9v,
 	 p8v,        *,         *,          *,         *,         *,
-	 *,          *,         *,          *")])
+	 *,          *,         *,          *,         p10")
+   (set_attr "prefixed"
+	"*,          *,         *,          *,         *,         *,
+	 *,          *,         *,          *,         *,         *,
+	 *,          *,         *,          *,         yes")
+   (set_attr "prefixed_prepend_p"
+	"*,          *,         *,          *,         *,         *,
+	 *,          *,         *,          *,         *,         *,
+	 *,          *,         *,          *,         no")])
 
 ;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
 ;;	FMR          MR         MT%0       MF%1       NOP
@@ -7863,18 +7898,18 @@
 
 ;;           STFD         LFD         FMR         LXSD        STXSD
 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
-;;           LWZ          STW         MR
+;;           LWZ          STW         MR          XXSPLTIDP
 
 
 (define_insn "*mov<mode>_hardfloat32"
   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
             "=m,          d,          d,          <f64_p9>,   wY,
               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
-              Y,          r,          !r")
+              Y,          r,          !r,         wa")
 	(match_operand:FMOVE64 1 "input_operand"
              "d,          m,          d,          wY,         <f64_p9>,
               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
-              r,          Y,          r"))]
+              r,          Y,          r,          eF"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
@@ -7891,20 +7926,29 @@
    #
    #
    #
+   #
    #"
   [(set_attr "type"
             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
              fpload,      fpstore,    veclogical, veclogical, two,
-             store,       load,       two")
+             store,       load,       two,        vecperm")
    (set_attr "size" "64")
    (set_attr "length"
             "*,           *,          *,          *,          *,
              *,           *,          *,          *,          8,
-             8,           8,          8")
+             8,           8,          8,          *")
    (set_attr "isa"
             "*,           *,          *,          p9v,        p9v,
              p7v,         p7v,        *,          *,          *,
-             *,           *,          *")])
+             *,           *,          *,          p10")
+   (set_attr "prefixed"
+            "*,           *,          *,          *,          *,
+             *,           *,          *,          *,          *,
+             *,           *,          *,          yes")
+   (set_attr "prefixed_prepend_p"
+            "*,           *,          *,          *,          *,
+             *,           *,          *,          *,          *,
+             *,           *,          *,          no")])
 
 ;;           STW      LWZ     MR      G-const H-const F-const
 
@@ -7931,19 +7975,19 @@
 ;;           STFD         LFD         FMR         LXSD        STXSD
 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
-;;           NOP          MFVSRD      MTVSRD
+;;           NOP          MFVSRD      MTVSRD      XXSPLTIDP
 
 (define_insn "*mov<mode>_hardfloat64"
   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
            "=m,           d,          d,          <f64_p9>,   wY,
              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
              YZ,          r,          !r,         *c*l,       !r,
-            *h,           r,          <f64_dm>")
+            *h,           r,          <f64_dm>,   wa")
 	(match_operand:FMOVE64 1 "input_operand"
             "d,           m,          d,          wY,         <f64_p9>,
              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
              r,           YZ,         r,          r,          *h,
-             0,           <f64_dm>,   r"))]
+             0,           <f64_dm>,   r,          eF"))]
   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
@@ -7965,18 +8009,29 @@
    mf%1 %0
    nop
    mfvsrd %0,%x1
-   mtvsrd %x0,%1"
+   mtvsrd %x0,%1
+   #"
   [(set_attr "type"
             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
              fpload,      fpstore,    veclogical, veclogical, integer,
              store,       load,       *,          mtjmpr,     mfjmpr,
-             *,           mfvsr,      mtvsr")
+             *,           mfvsr,      mtvsr,      vecperm")
    (set_attr "size" "64")
    (set_attr "isa"
             "*,           *,          *,          p9v,        p9v,
              p7v,         p7v,        *,          *,          *,
              *,           *,          *,          *,          *,
-             *,           p8v,        p8v")])
+             *,           p8v,        p8v,        p10")
+   (set_attr "prefixed"
+            "*,           *,          *,          *,          *,
+             *,           *,          *,          *,          *,
+             *,           *,          *,          *,          *,
+             *,           *,          *,          yes")
+   (set_attr "prefixed_prepend_p"
+            "*,           *,          *,          *,          *,
+             *,           *,          *,          *,          *,
+             *,           *,          *,          *,          *,
+             *,           *,          *,          no")])
 
 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
 ;;           H-const  F-const  Special


More information about the Gcc-cvs mailing list