[PATCH 5/5] Add Power10 XXSPLTIDP for SFmode/DFmode constants.

will schmidt will_schmidt@vnet.ibm.com
Fri Nov 5 19:38:45 GMT 2021


On Fri, 2021-11-05 at 00:11 -0400, Michael Meissner wrote:
> Generate XXSPLTIDP for scalars on power10.
> 
> This patch implements XXSPLTIDP support for SF, and DF scalar constants.
> The previous patch added support for vector constants.  This patch adds
> the support for SFmode and DFmode scalar constants.
> 
> I added 2 new tests to test loading up SF and DF scalar constants.


ok

> 
> 2021-11-05  Michael Meissner  <meissner@the-meissners.org>
> 
> gcc/
> 
> 	* config/rs6000/rs6000.md (UNSPEC_XXSPLTIDP_CONST): New unspec.
> 	(UNSPEC_XXSPLTIW_CONST): New unspec.
> 	(movsf_hardfloat): Add support for generating XXSPLTIDP.
> 	(mov<mode>_hardfloat32): Likewise.
> 	(mov<mode>_hardfloat64): Likewise.
> 	(xxspltidp_<mode>_internal): New insns.
> 	(xxspltiw_<mode>_internal): New insns.
> 	(splitters for SF/DFmode): Add new splitters for XXSPLTIDP.
> 
> gcc/testsuite/
> 
> 	* gcc.target/powerpc/vec-splat-constant-df.c: New test.
> 	* gcc.target/powerpc/vec-splat-constant-sf.c: New test.
> ---

ok


>  gcc/config/rs6000/rs6000.md                   | 97 +++++++++++++++----
>  .../powerpc/vec-splat-constant-df.c           | 60 ++++++++++++
>  .../powerpc/vec-splat-constant-sf.c           | 60 ++++++++++++
>  3 files changed, 199 insertions(+), 18 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
> 
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index 3a7bcd2426e..4122acb98cf 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -156,6 +156,8 @@ (define_c_enum "unspec"
>     UNSPEC_PEXTD
>     UNSPEC_HASHST
>     UNSPEC_HASHCHK
> +   UNSPEC_XXSPLTIDP_CONST
> +   UNSPEC_XXSPLTIW_CONST
>    ])
> 
>  ;;
> @@ -7764,17 +7766,17 @@ (define_split
>  ;;
>  ;;	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,         eP"))]
>    "(register_operand (operands[0], SFmode)
>     || register_operand (operands[1], SFmode))
>     && TARGET_HARD_FLOAT
> @@ -7796,15 +7798,16 @@ (define_insn "movsf_hardfloat"
>     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")])
> 
>  ;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
>  ;;	FMR          MR         MT%0       MF%1       NOP
> @@ -8064,18 +8067,18 @@ (define_split
> 
>  ;;           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,          eP"))]
>    "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
>     && (gpc_reg_operand (operands[0], <MODE>mode)
>         || gpc_reg_operand (operands[1], <MODE>mode))"
> @@ -8092,20 +8095,21 @@ (define_insn "*mov<mode>_hardfloat32"
>     #
>     #
>     #
> +   #
>     #"
>    [(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")])
> 
>  ;;           STW      LWZ     MR      G-const H-const F-const
> 
> @@ -8132,19 +8136,19 @@ (define_insn "*mov<mode>_softfloat32"
>  ;;           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,          eP"))]
>    "TARGET_POWERPC64 && TARGET_HARD_FLOAT
>     && (gpc_reg_operand (operands[0], <MODE>mode)
>         || gpc_reg_operand (operands[1], <MODE>mode))"
> @@ -8166,18 +8170,19 @@ (define_insn "*mov<mode>_hardfloat64"
>     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")])
> 
>  ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
>  ;;           H-const  F-const  Special
> @@ -8211,6 +8216,62 @@ (define_insn "*mov<mode>_softfloat64"
>     (set_attr "length"
>              "*,       *,      *,      *,      *,      8,
>               12,      16,     *")])
> +

ok


> +;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
> +;; constants that look like DFmode floating point values where both elements
> +;; are the same.  The constant has to be expressible as a SFmode constant that
> +;; is not a SFmode denormal value.
> +;;
> +;; We don't need splitters for the 128-bit types, since the function
> +;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.

ok

> +(define_insn "xxspltidp_<mode>_internal"
> +  [(set (match_operand:SFDF 0 "register_operand" "=wa")
> +	(unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTIDP_CONST))]
> +  "TARGET_POWER10"
> +  "xxspltidp %x0,%1"
> +  [(set_attr "type" "vecperm")
> +   (set_attr "prefixed" "yes")])
> +
> +(define_insn "xxspltiw_<mode>_internal"
> +  [(set (match_operand:SFDF 0 "register_operand" "=wa")
> +	(unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTIW_CONST))]
> +  "TARGET_POWER10"
> +  "xxspltiw %x0,%1"
> +  [(set_attr "type" "vecperm")
> +   (set_attr "prefixed" "yes")])
> +
> +(define_split
> +  [(set (match_operand:SFDF 0 "vsx_register_operand")
> +	(match_operand:SFDF 1 "vsx_prefixed_constant"))]
> +  "TARGET_POWER10"
> +  [(pc)]
> +{
> +  rtx dest = operands[0];
> +  rtx src = operands[1];
> +  vec_const_128bit_type vsx_const;
> +
> +  if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
> +    gcc_unreachable ();
> +
> +  unsigned imm = constant_generates_xxspltidp (&vsx_const);
> +  if (imm)
> +    {
> +      emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
> +      DONE;
> +    }
> +
> +  imm = constant_generates_xxspltiw (&vsx_const);
> +  if (imm)
> +    {
> +      emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
> +      DONE;
> +    }
> +
> +  else
> +    gcc_unreachable ();
> +})


ok
Nothing further, 
thanks,
-Will


>  
>  (define_expand "mov<mode>"
>    [(set (match_operand:FMOVE128 0 "general_operand")
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
> new file mode 100644
> index 00000000000..8f6e176f9af
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
> @@ -0,0 +1,60 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target power10_ok } */
> +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
> +
> +#include <math.h>
> +
> +/* Test generating DFmode constants with the ISA 3.1 (power10) XXSPLTIDP
> +   instruction.  */
> +
> +double
> +scalar_double_0 (void)
> +{
> +  return 0.0;			/* XXSPLTIB or XXLXOR.  */
> +}
> +
> +double
> +scalar_double_1 (void)
> +{
> +  return 1.0;			/* XXSPLTIDP.  */
> +}
> +
> +#ifndef __FAST_MATH__
> +double
> +scalar_double_m0 (void)
> +{
> +  return -0.0;			/* XXSPLTIDP.  */
> +}
> +
> +double
> +scalar_double_nan (void)
> +{
> +  return __builtin_nan ("");	/* XXSPLTIDP.  */
> +}
> +
> +double
> +scalar_double_inf (void)
> +{
> +  return __builtin_inf ();	/* XXSPLTIDP.  */
> +}
> +
> +double
> +scalar_double_m_inf (void)	/* XXSPLTIDP.  */
> +{
> +  return - __builtin_inf ();
> +}
> +#endif
> +
> +double
> +scalar_double_pi (void)
> +{
> +  return M_PI;			/* PLFD.  */
> +}
> +
> +double
> +scalar_double_denorm (void)
> +{
> +  return 0x1p-149f;		/* PLFD.  */
> +}
> +
> +/* { dg-final { scan-assembler-times {\mxxspltidp\M} 5 } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
> new file mode 100644
> index 00000000000..72504bdfbbd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
> @@ -0,0 +1,60 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target power10_ok } */
> +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
> +
> +#include <math.h>
> +
> +/* Test generating SFmode constants with the ISA 3.1 (power10) XXSPLTIDP
> +   instruction.  */
> +
> +float
> +scalar_float_0 (void)
> +{
> +  return 0.0f;			/* XXSPLTIB or XXLXOR.  */
> +}
> +
> +float
> +scalar_float_1 (void)
> +{
> +  return 1.0f;			/* XXSPLTIDP.  */
> +}
> +
> +#ifndef __FAST_MATH__
> +float
> +scalar_float_m0 (void)
> +{
> +  return -0.0f;			/* XXSPLTIDP.  */
> +}
> +
> +float
> +scalar_float_nan (void)
> +{
> +  return __builtin_nanf ("");	/* XXSPLTIDP.  */
> +}
> +
> +float
> +scalar_float_inf (void)
> +{
> +  return __builtin_inff ();	/* XXSPLTIDP.  */
> +}
> +
> +float
> +scalar_float_m_inf (void)	/* XXSPLTIDP.  */
> +{
> +  return - __builtin_inff ();
> +}
> +#endif
> +
> +float
> +scalar_float_pi (void)
> +{
> +  return (float)M_PI;		/* XXSPLTIDP.  */
> +}
> +
> +float
> +scalar_float_denorm (void)
> +{
> +  return 0x1p-149f;		/* PLFS.  */
> +}
> +
> +/* { dg-final { scan-assembler-times {\mxxspltidp\M} 6 } } */
> -- 
> 2.31.1
> 
> 



More information about the Gcc-patches mailing list