public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/meissner/heads/work055)] PR 101019: Improve loading 64-bit constants on power10.
@ 2021-06-10 16:33 Michael Meissner
  0 siblings, 0 replies; 6+ messages in thread
From: Michael Meissner @ 2021-06-10 16:33 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:516548b659db14b6c2e1fe8fe653cf91f0c32d85

commit 516548b659db14b6c2e1fe8fe653cf91f0c32d85
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Thu Jun 10 12:32:49 2021 -0400

    PR 101019: Improve loading 64-bit constants on power10.
    
    When the support for prefixed instructions went into GCC, we did not
    modify loading up larger constants to use one or two PLI/PADDI
    instructions.  This patch adds this support.
    
    gcc/
    2021-06-10  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * config/rs6000/rs6000-cpus.def (ISA_3_1_MASKS_SERVER): Add
            -mpower10-large-consts support.
            (POWERPC_MASKS): Add -mpower10-large-consts support.
            * config/rs6000/rs6000.c (rs6000_option_override_internal): Add
            -mpower10-large-consts support.
            (num_insns_constant_gpr): Add -mpower10-large-consts support.
            (rs6000_emit_set_long_const): Add -mpower10-large-consts support.
            (rs6000_opt_masks): Add -mpower10-large-consts.
            * config/rs6000/rs6000.opt (-mpower10-large-consts): New switch.
    
    gcc/testsuite/
    2021-06-09  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * gcc.target/powerpc/prefix-large-const.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-cpus.def                  |  2 ++
 gcc/config/rs6000/rs6000.c                         | 41 +++++++++++++++++++---
 gcc/config/rs6000/rs6000.opt                       |  4 +++
 .../gcc.target/powerpc/prefix-large-const.c        | 32 +++++++++++++++++
 4 files changed, 75 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index c0d89434fcd..b119f574e4c 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -90,6 +90,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD		\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_XXSPLTI32DX		\
 				 | OPTION_MASK_XXSPLTIDP		\
 				 | OPTION_MASK_XXSPLTIW)
@@ -145,6 +146,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD    	\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_HTM			\
 				 | OPTION_MASK_ISEL			\
 				 | OPTION_MASK_LXVKQ			\
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca92ee63d73..47703fbb2fe 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4489,6 +4489,12 @@ rs6000_option_override_internal (bool global_init_p)
       && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION_2ADD) == 0)
     rs6000_isa_flags |= OPTION_MASK_P10_FUSION_2ADD;
 
+  if (TARGET_PREFIXED
+      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_LARGE_CONSTS) == 0)
+    rs6000_isa_flags |= OPTION_MASK_P10_LARGE_CONSTS;
+  else if (!TARGET_PREFIXED)
+    rs6000_isa_flags &= ~OPTION_MASK_P10_LARGE_CONSTS;
+
   /* Turn off vector pair/mma options on non-power10 systems.  */
   else if (!TARGET_POWER10 && TARGET_MMA)
     {
@@ -5959,9 +5965,20 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
 	   && (value >> 31 == -1 || value >> 31 == 0))
     return 1;
 
-  /* PADDI can support up to 34 bit signed integers.  */
-  else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value))
-    return 1;
+  /* PADDI can support up to 34 bit signed integers, or using a combination of
+     PADDI and shift left.  */
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      if (SIGNED_INTEGER_34BIT_P (value))
+	return 1;
+
+      /* PLI and SLDI.  */
+      if ((value & 0xffffffff) == 0)
+	return 2;
+
+      /* PLI, SLDI, PADDI.  */
+      return 3;
+    }
 
   else if (TARGET_POWERPC64)
     {
@@ -10415,7 +10432,22 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
     }
-  else if ((ud4 == 0xffff && (ud3 & 0x8000))
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      HOST_WIDE_INT low_32bit = ud1 | (ud2 << 16);
+      HOST_WIDE_INT high_32bit = ud3 | (ud4 << 16);
+
+      temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
+      emit_move_insn (copy_rtx (temp), GEN_INT (high_32bit));
+
+      rtx temp2 = ((low_32bit == 0 || !can_create_pseudo_p ())
+		   ? dest
+		   : gen_reg_rtx (DImode));
+      emit_insn (gen_ashldi3 (temp2, temp, GEN_INT (32)));
+      if (low_32bit)
+	emit_insn (gen_adddi3 (dest, temp2, GEN_INT (low_32bit)));
+    }
+  else if ((ud4 == 0xaffff && (ud3 & 0x8000))
 	   || (ud4 == 0 && ! (ud3 & 0x8000)))
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
@@ -24424,6 +24456,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "power9-misc",		OPTION_MASK_P9_MISC,		false, true  },
   { "power9-vector",		OPTION_MASK_P9_VECTOR,		false, true  },
   { "power10-fusion",		OPTION_MASK_P10_FUSION,		false, true  },
+  { "power10-large-consts",	OPTION_MASK_P10_LARGE_CONSTS,	false, true  },
   { "powerpc-gfxopt",		OPTION_MASK_PPC_GFXOPT,		false, true  },
   { "powerpc-gpopt",		OPTION_MASK_PPC_GPOPT,		false, true  },
   { "prefixed",			OPTION_MASK_PREFIXED,		false, true  },
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index e65dd8762a4..add22c8be1a 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -655,3 +655,7 @@ Generate (do not generate) XXSPLTI32DX instructions.
 mlxvkq
 Target Undocumented Mask(LXVKQ) Var(rs6000_isa_flags)
 Generate (do not generate) LXVKQ instructions.
+
+mpower10-large-consts
+Target Undocumented Mask(P10_LARGE_CONSTS) Var(rs6000_isa_flags)
+Generate (do not generate) PLI/SLDI/PADDI to load large constants.
diff --git a/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
new file mode 100644
index 00000000000..f13812cbc27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_prefixed_addr } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Test whether we can use PLI/PADDI to load up large constants.  */
+
+long
+foo_1 (void)
+{
+  return 1L << 53;			/* LIS, SLDI.  */
+}
+
+long
+foo_2 (void)
+{
+  return (1L << 53) | (1L << 35);	/* PLI, SLDI.  */
+}
+
+long
+foo_3 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, PADDI.  */
+	  | (1L << 35)
+	  | (1L << 30)
+	  | (1L << 2);
+}
+
+/* { dg-final { scan-assembler-times {\mlis\M}   1 } } */
+/* { dg-final { scan-assembler-times {\mpaddi\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mpli\M}   2 } } */
+/* { dg-final { scan-assembler-times {\msldi\M}  3 } } */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/meissner/heads/work055)] PR 101019: Improve loading 64-bit constants on power10.
@ 2021-06-11 23:05 Michael Meissner
  0 siblings, 0 replies; 6+ messages in thread
From: Michael Meissner @ 2021-06-11 23:05 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:8ae38d978f081d1cf90c33c4103bf032df99dc06

commit 8ae38d978f081d1cf90c33c4103bf032df99dc06
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Fri Jun 11 19:04:50 2021 -0400

    PR 101019: Improve loading 64-bit constants on power10.
    
    When the support for prefixed instructions went into GCC, we did not
    modify loading up larger constants to use one or two PLI/PADDI
    instructions.  This patch adds this support.
    
    gcc/
    2021-06-11  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * config/rs6000/rs6000-cpus.def (ISA_3_1_MASKS_SERVER): Add
            -mpower10-large-consts support.
            (POWERPC_MASKS): Add -mpower10-large-consts support.
            * config/rs6000/rs6000.c (rs6000_option_override_internal): Add
            -mpower10-large-consts support.
            (num_insns_constant_gpr): Add -mpower10-large-consts support.
            (rs6000_emit_set_long_const): Add -mpower10-large-consts support.
            (rs6000_opt_masks): Add -mpower10-large-consts.
            * config/rs6000/rs6000.opt (-mpower10-large-consts): New switch.
    
    gcc/testsuite/
    2021-06-11  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * gcc.target/powerpc/prefix-large-const.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-cpus.def                  |  2 +
 gcc/config/rs6000/rs6000.c                         | 67 ++++++++++++++++++++--
 gcc/config/rs6000/rs6000.opt                       |  4 ++
 .../gcc.target/powerpc/prefix-large-const.c        | 57 ++++++++++++++++++
 4 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index c0d89434fcd..b119f574e4c 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -90,6 +90,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD		\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_XXSPLTI32DX		\
 				 | OPTION_MASK_XXSPLTIDP		\
 				 | OPTION_MASK_XXSPLTIW)
@@ -145,6 +146,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD    	\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_HTM			\
 				 | OPTION_MASK_ISEL			\
 				 | OPTION_MASK_LXVKQ			\
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca92ee63d73..ac01b46e864 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4489,6 +4489,12 @@ rs6000_option_override_internal (bool global_init_p)
       && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION_2ADD) == 0)
     rs6000_isa_flags |= OPTION_MASK_P10_FUSION_2ADD;
 
+  if (TARGET_PREFIXED
+      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_LARGE_CONSTS) == 0)
+    rs6000_isa_flags |= OPTION_MASK_P10_LARGE_CONSTS;
+  else if (!TARGET_PREFIXED)
+    rs6000_isa_flags &= ~OPTION_MASK_P10_LARGE_CONSTS;
+
   /* Turn off vector pair/mma options on non-power10 systems.  */
   else if (!TARGET_POWER10 && TARGET_MMA)
     {
@@ -5959,9 +5965,20 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
 	   && (value >> 31 == -1 || value >> 31 == 0))
     return 1;
 
-  /* PADDI can support up to 34 bit signed integers.  */
-  else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value))
-    return 1;
+  /* PADDI can support up to 34 bit signed integers, or using a combination of
+     PADDI and shift left.  */
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      if (SIGNED_INTEGER_34BIT_P (value))
+	return 1;
+
+      /* PLI and SLDI.  */
+      if ((value & 0xffffffff) == 0)
+	return 2;
+
+      /* PLI, SLDI, PADDI.  */
+      return 3;
+    }
 
   else if (TARGET_POWERPC64)
     {
@@ -10415,7 +10432,48 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
     }
-  else if ((ud4 == 0xffff && (ud3 & 0x8000))
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      HOST_WIDE_INT low_32bit = ud1 | (ud2 << 16);
+      HOST_WIDE_INT high_32bit = ud3 | (ud4 << 16);
+
+      temp = !can_create_pseudo_p () ? copy_rtx (dest) : gen_reg_rtx (DImode);
+      emit_move_insn (temp, GEN_INT (high_32bit));
+
+      if (!low_32bit)
+	emit_insn (gen_ashldi3 (dest, temp, GEN_INT (32)));
+      else
+	{
+	  rtx temp2 = (!can_create_pseudo_p ()
+		       ? copy_rtx (dest)
+		       : gen_reg_rtx (DImode));
+
+	  emit_insn (gen_ashldi3 (temp2, temp, GEN_INT (32)));
+
+	  /* See if a simple ORI or ORIS will suffice to fill in the
+	     constant.  */
+	  if (ud2 == 0)
+	    emit_insn (gen_iordi3 (dest, temp2, GEN_INT (ud1)));
+	  else if (ud1 == 0)
+	    emit_insn (gen_iordi3 (dest, temp2, GEN_INT (ud2 << 16)));
+	  /* If the register is not r0, we can do a PADDI.  However, if the
+	     register is r0, we need to do an ORI and ORIS instead of a PADDI.
+	     This is because R0 as the register is interpreted as 0 and not
+	     R0.  */
+	  else if (REGNO (dest) != FIRST_GPR_REGNO)
+	    emit_insn (gen_adddi3 (dest, temp2, GEN_INT (low_32bit)));
+	  else
+	    {
+	      rtx temp3 = (!can_create_pseudo_p ()
+			   ? copy_rtx (dest)
+			   : gen_reg_rtx (DImode));
+
+	      emit_insn (gen_iordi3 (temp3, temp2, GEN_INT (ud2 << 16)));
+	      emit_insn (gen_iordi3 (dest, temp3, GEN_INT (ud1)));
+	    }
+	}
+    }
+  else if ((ud4 == 0xaffff && (ud3 & 0x8000))
 	   || (ud4 == 0 && ! (ud3 & 0x8000)))
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
@@ -24424,6 +24482,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "power9-misc",		OPTION_MASK_P9_MISC,		false, true  },
   { "power9-vector",		OPTION_MASK_P9_VECTOR,		false, true  },
   { "power10-fusion",		OPTION_MASK_P10_FUSION,		false, true  },
+  { "power10-large-consts",	OPTION_MASK_P10_LARGE_CONSTS,	false, true  },
   { "powerpc-gfxopt",		OPTION_MASK_PPC_GFXOPT,		false, true  },
   { "powerpc-gpopt",		OPTION_MASK_PPC_GPOPT,		false, true  },
   { "prefixed",			OPTION_MASK_PREFIXED,		false, true  },
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index e65dd8762a4..add22c8be1a 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -655,3 +655,7 @@ Generate (do not generate) XXSPLTI32DX instructions.
 mlxvkq
 Target Undocumented Mask(LXVKQ) Var(rs6000_isa_flags)
 Generate (do not generate) LXVKQ instructions.
+
+mpower10-large-consts
+Target Undocumented Mask(P10_LARGE_CONSTS) Var(rs6000_isa_flags)
+Generate (do not generate) PLI/SLDI/PADDI to load large constants.
diff --git a/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
new file mode 100644
index 00000000000..df0e333d148
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_prefixed_addr } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Test whether we can use PLI/PADDI to load up large constants.  */
+
+long
+foo_1 (void)
+{
+  return 1L << 53;			/* LIS, SLDI.  */
+}
+
+long
+foo_2 (void)
+{
+  return 1L << 34;			/* LI, SLDI.  */
+}
+
+long
+foo_3 (void)
+{
+  return (1L << 53) | (1L << 35);	/* PLI, SLDI.  */
+}
+
+long
+foo_4 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, PADDI.  */
+	  | (1L << 35)
+	  | (1L << 30)
+	  | (1L << 2));
+}
+
+long
+foo_5 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, ORI.  */
+	  | (1L << 35)
+	  | (1L << 2));
+}
+
+long
+foo_6 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, ORIS.  */
+	  | (1L << 35)
+	  | (1L << 30));
+}
+
+/* { dg-final { scan-assembler-times {\mli\M}    1 } } */
+/* { dg-final { scan-assembler-times {\mlis\M}   1 } } */
+/* { dg-final { scan-assembler-times {\mori\M}   1 } } */
+/* { dg-final { scan-assembler-times {\moris\M}  1 } } */
+/* { dg-final { scan-assembler-times {\mpaddi\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mpli\M}   4 } } */
+/* { dg-final { scan-assembler-times {\msldi\M}  6 } } */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/meissner/heads/work055)] PR 101019: Improve loading 64-bit constants on power10.
@ 2021-06-11 22:51 Michael Meissner
  0 siblings, 0 replies; 6+ messages in thread
From: Michael Meissner @ 2021-06-11 22:51 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0d33991ccfc68cc8ffbec944415ccfc00fce8f5d

commit 0d33991ccfc68cc8ffbec944415ccfc00fce8f5d
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Fri Jun 11 18:50:58 2021 -0400

    PR 101019: Improve loading 64-bit constants on power10.
    
    When the support for prefixed instructions went into GCC, we did not
    modify loading up larger constants to use one or two PLI/PADDI
    instructions.  This patch adds this support.
    
    gcc/
    2021-06-11  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * config/rs6000/rs6000-cpus.def (ISA_3_1_MASKS_SERVER): Add
            -mpower10-large-consts support.
            (POWERPC_MASKS): Add -mpower10-large-consts support.
            * config/rs6000/rs6000.c (rs6000_option_override_internal): Add
            -mpower10-large-consts support.
            (num_insns_constant_gpr): Add -mpower10-large-consts support.
            (rs6000_emit_set_long_const): Add -mpower10-large-consts support.
            (rs6000_opt_masks): Add -mpower10-large-consts.
            * config/rs6000/rs6000.opt (-mpower10-large-consts): New switch.
    
    gcc/testsuite/
    2021-06-11  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * gcc.target/powerpc/prefix-large-const.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-cpus.def                  |  2 +
 gcc/config/rs6000/rs6000.c                         | 67 ++++++++++++++++++++--
 gcc/config/rs6000/rs6000.opt                       |  4 ++
 .../gcc.target/powerpc/prefix-large-const.c        | 50 ++++++++++++++++
 4 files changed, 119 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index c0d89434fcd..b119f574e4c 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -90,6 +90,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD		\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_XXSPLTI32DX		\
 				 | OPTION_MASK_XXSPLTIDP		\
 				 | OPTION_MASK_XXSPLTIW)
@@ -145,6 +146,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD    	\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_HTM			\
 				 | OPTION_MASK_ISEL			\
 				 | OPTION_MASK_LXVKQ			\
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca92ee63d73..ac01b46e864 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4489,6 +4489,12 @@ rs6000_option_override_internal (bool global_init_p)
       && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION_2ADD) == 0)
     rs6000_isa_flags |= OPTION_MASK_P10_FUSION_2ADD;
 
+  if (TARGET_PREFIXED
+      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_LARGE_CONSTS) == 0)
+    rs6000_isa_flags |= OPTION_MASK_P10_LARGE_CONSTS;
+  else if (!TARGET_PREFIXED)
+    rs6000_isa_flags &= ~OPTION_MASK_P10_LARGE_CONSTS;
+
   /* Turn off vector pair/mma options on non-power10 systems.  */
   else if (!TARGET_POWER10 && TARGET_MMA)
     {
@@ -5959,9 +5965,20 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
 	   && (value >> 31 == -1 || value >> 31 == 0))
     return 1;
 
-  /* PADDI can support up to 34 bit signed integers.  */
-  else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value))
-    return 1;
+  /* PADDI can support up to 34 bit signed integers, or using a combination of
+     PADDI and shift left.  */
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      if (SIGNED_INTEGER_34BIT_P (value))
+	return 1;
+
+      /* PLI and SLDI.  */
+      if ((value & 0xffffffff) == 0)
+	return 2;
+
+      /* PLI, SLDI, PADDI.  */
+      return 3;
+    }
 
   else if (TARGET_POWERPC64)
     {
@@ -10415,7 +10432,48 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
     }
-  else if ((ud4 == 0xffff && (ud3 & 0x8000))
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      HOST_WIDE_INT low_32bit = ud1 | (ud2 << 16);
+      HOST_WIDE_INT high_32bit = ud3 | (ud4 << 16);
+
+      temp = !can_create_pseudo_p () ? copy_rtx (dest) : gen_reg_rtx (DImode);
+      emit_move_insn (temp, GEN_INT (high_32bit));
+
+      if (!low_32bit)
+	emit_insn (gen_ashldi3 (dest, temp, GEN_INT (32)));
+      else
+	{
+	  rtx temp2 = (!can_create_pseudo_p ()
+		       ? copy_rtx (dest)
+		       : gen_reg_rtx (DImode));
+
+	  emit_insn (gen_ashldi3 (temp2, temp, GEN_INT (32)));
+
+	  /* See if a simple ORI or ORIS will suffice to fill in the
+	     constant.  */
+	  if (ud2 == 0)
+	    emit_insn (gen_iordi3 (dest, temp2, GEN_INT (ud1)));
+	  else if (ud1 == 0)
+	    emit_insn (gen_iordi3 (dest, temp2, GEN_INT (ud2 << 16)));
+	  /* If the register is not r0, we can do a PADDI.  However, if the
+	     register is r0, we need to do an ORI and ORIS instead of a PADDI.
+	     This is because R0 as the register is interpreted as 0 and not
+	     R0.  */
+	  else if (REGNO (dest) != FIRST_GPR_REGNO)
+	    emit_insn (gen_adddi3 (dest, temp2, GEN_INT (low_32bit)));
+	  else
+	    {
+	      rtx temp3 = (!can_create_pseudo_p ()
+			   ? copy_rtx (dest)
+			   : gen_reg_rtx (DImode));
+
+	      emit_insn (gen_iordi3 (temp3, temp2, GEN_INT (ud2 << 16)));
+	      emit_insn (gen_iordi3 (dest, temp3, GEN_INT (ud1)));
+	    }
+	}
+    }
+  else if ((ud4 == 0xaffff && (ud3 & 0x8000))
 	   || (ud4 == 0 && ! (ud3 & 0x8000)))
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
@@ -24424,6 +24482,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "power9-misc",		OPTION_MASK_P9_MISC,		false, true  },
   { "power9-vector",		OPTION_MASK_P9_VECTOR,		false, true  },
   { "power10-fusion",		OPTION_MASK_P10_FUSION,		false, true  },
+  { "power10-large-consts",	OPTION_MASK_P10_LARGE_CONSTS,	false, true  },
   { "powerpc-gfxopt",		OPTION_MASK_PPC_GFXOPT,		false, true  },
   { "powerpc-gpopt",		OPTION_MASK_PPC_GPOPT,		false, true  },
   { "prefixed",			OPTION_MASK_PREFIXED,		false, true  },
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index e65dd8762a4..add22c8be1a 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -655,3 +655,7 @@ Generate (do not generate) XXSPLTI32DX instructions.
 mlxvkq
 Target Undocumented Mask(LXVKQ) Var(rs6000_isa_flags)
 Generate (do not generate) LXVKQ instructions.
+
+mpower10-large-consts
+Target Undocumented Mask(P10_LARGE_CONSTS) Var(rs6000_isa_flags)
+Generate (do not generate) PLI/SLDI/PADDI to load large constants.
diff --git a/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
new file mode 100644
index 00000000000..50921326d5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_prefixed_addr } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Test whether we can use PLI/PADDI to load up large constants.  */
+
+long
+foo_1 (void)
+{
+  return 1L << 53;			/* LIS, SLDI.  */
+}
+
+long
+foo_2 (void)
+{
+  return (1L << 53) | (1L << 35);	/* PLI, SLDI.  */
+}
+
+long
+foo_3 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, PADDI.  */
+	  | (1L << 35)
+	  | (1L << 30)
+	  | (1L << 2));
+}
+
+long
+foo_4 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, ORI.  */
+	  | (1L << 35)
+	  | (1L << 2));
+}
+
+long
+foo_5 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, ORIS.  */
+	  | (1L << 35)
+	  | (1L << 30));
+}
+
+/* { dg-final { scan-assembler-times {\mlis\M}   1 } } */
+/* { dg-final { scan-assembler-times {\mori\M}   1 } } */
+/* { dg-final { scan-assembler-times {\moris\M}  1 } } */
+/* { dg-final { scan-assembler-times {\mpaddi\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mpli\M}   4 } } */
+/* { dg-final { scan-assembler-times {\msldi\M}  5 } } */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/meissner/heads/work055)] PR 101019: Improve loading 64-bit constants on power10.
@ 2021-06-10 22:55 Michael Meissner
  0 siblings, 0 replies; 6+ messages in thread
From: Michael Meissner @ 2021-06-10 22:55 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0f34f87fd5adb91d36b3ad961d9396567c5f7e98

commit 0f34f87fd5adb91d36b3ad961d9396567c5f7e98
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Thu Jun 10 18:55:12 2021 -0400

    PR 101019: Improve loading 64-bit constants on power10.
    
    When the support for prefixed instructions went into GCC, we did not
    modify loading up larger constants to use one or two PLI/PADDI
    instructions.  This patch adds this support.
    
    gcc/
    2021-06-10  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * config/rs6000/rs6000-cpus.def (ISA_3_1_MASKS_SERVER): Add
            -mpower10-large-consts support.
            (POWERPC_MASKS): Add -mpower10-large-consts support.
            * config/rs6000/rs6000.c (rs6000_option_override_internal): Add
            -mpower10-large-consts support.
            (num_insns_constant_gpr): Add -mpower10-large-consts support.
            (rs6000_emit_set_long_const): Add -mpower10-large-consts support.
            (rs6000_opt_masks): Add -mpower10-large-consts.
            * config/rs6000/rs6000.opt (-mpower10-large-consts): New switch.
    
    gcc/testsuite/
    2021-06-09  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * gcc.target/powerpc/prefix-large-const.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-cpus.def                  |  2 +
 gcc/config/rs6000/rs6000.c                         | 50 ++++++++++++++++++++--
 gcc/config/rs6000/rs6000.opt                       |  4 ++
 .../gcc.target/powerpc/prefix-large-const.c        | 32 ++++++++++++++
 4 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index c0d89434fcd..b119f574e4c 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -90,6 +90,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD		\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_XXSPLTI32DX		\
 				 | OPTION_MASK_XXSPLTIDP		\
 				 | OPTION_MASK_XXSPLTIW)
@@ -145,6 +146,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD    	\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_HTM			\
 				 | OPTION_MASK_ISEL			\
 				 | OPTION_MASK_LXVKQ			\
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca92ee63d73..93e14570ed3 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4489,6 +4489,12 @@ rs6000_option_override_internal (bool global_init_p)
       && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION_2ADD) == 0)
     rs6000_isa_flags |= OPTION_MASK_P10_FUSION_2ADD;
 
+  if (TARGET_PREFIXED
+      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_LARGE_CONSTS) == 0)
+    rs6000_isa_flags |= OPTION_MASK_P10_LARGE_CONSTS;
+  else if (!TARGET_PREFIXED)
+    rs6000_isa_flags &= ~OPTION_MASK_P10_LARGE_CONSTS;
+
   /* Turn off vector pair/mma options on non-power10 systems.  */
   else if (!TARGET_POWER10 && TARGET_MMA)
     {
@@ -5959,9 +5965,20 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
 	   && (value >> 31 == -1 || value >> 31 == 0))
     return 1;
 
-  /* PADDI can support up to 34 bit signed integers.  */
-  else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value))
-    return 1;
+  /* PADDI can support up to 34 bit signed integers, or using a combination of
+     PADDI and shift left.  */
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      if (SIGNED_INTEGER_34BIT_P (value))
+	return 1;
+
+      /* PLI and SLDI.  */
+      if ((value & 0xffffffff) == 0)
+	return 2;
+
+      /* PLI, SLDI, PADDI.  */
+      return 3;
+    }
 
   else if (TARGET_POWERPC64)
     {
@@ -10415,7 +10432,31 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
     }
-  else if ((ud4 == 0xffff && (ud3 & 0x8000))
+  /* We can't load R0 using PLI/SLDA/PADDI, since the R0 in the PADDI would be
+     interpreted as 0 and not register 0.  */
+  else if (TARGET_P10_LARGE_CONSTS
+	   && (base_reg_operand (dest, DImode)
+	       || can_create_pseudo_p ()
+	       || (ud1 == 0 && ud2 == 0)))
+    {
+      HOST_WIDE_INT low_32bit = ud1 | (ud2 << 16);
+      HOST_WIDE_INT high_32bit = ud3 | (ud4 << 16);
+
+      temp = !can_create_pseudo_p () ? copy_rtx (dest) : gen_reg_rtx (DImode);
+      emit_move_insn (temp, GEN_INT (high_32bit));
+
+      if (!low_32bit)
+	emit_insn (gen_ashldi3 (dest, temp, GEN_INT (32)));
+      else
+	{
+	  rtx temp2 = (!can_create_pseudo_p ()
+		       ? copy_rtx (dest)
+		       : gen_reg_rtx (DImode));
+	  emit_insn (gen_ashldi3 (temp2, temp, GEN_INT (32)));
+	  emit_insn (gen_adddi3 (dest, temp2, GEN_INT (low_32bit)));
+	}
+    }
+  else if ((ud4 == 0xaffff && (ud3 & 0x8000))
 	   || (ud4 == 0 && ! (ud3 & 0x8000)))
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
@@ -24424,6 +24465,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "power9-misc",		OPTION_MASK_P9_MISC,		false, true  },
   { "power9-vector",		OPTION_MASK_P9_VECTOR,		false, true  },
   { "power10-fusion",		OPTION_MASK_P10_FUSION,		false, true  },
+  { "power10-large-consts",	OPTION_MASK_P10_LARGE_CONSTS,	false, true  },
   { "powerpc-gfxopt",		OPTION_MASK_PPC_GFXOPT,		false, true  },
   { "powerpc-gpopt",		OPTION_MASK_PPC_GPOPT,		false, true  },
   { "prefixed",			OPTION_MASK_PREFIXED,		false, true  },
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index e65dd8762a4..add22c8be1a 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -655,3 +655,7 @@ Generate (do not generate) XXSPLTI32DX instructions.
 mlxvkq
 Target Undocumented Mask(LXVKQ) Var(rs6000_isa_flags)
 Generate (do not generate) LXVKQ instructions.
+
+mpower10-large-consts
+Target Undocumented Mask(P10_LARGE_CONSTS) Var(rs6000_isa_flags)
+Generate (do not generate) PLI/SLDI/PADDI to load large constants.
diff --git a/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
new file mode 100644
index 00000000000..fa4904efbc7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_prefixed_addr } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Test whether we can use PLI/PADDI to load up large constants.  */
+
+long
+foo_1 (void)
+{
+  return 1L << 53;			/* LIS, SLDI.  */
+}
+
+long
+foo_2 (void)
+{
+  return (1L << 53) | (1L << 35);	/* PLI, SLDI.  */
+}
+
+long
+foo_3 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, PADDI.  */
+	  | (1L << 35)
+	  | (1L << 30)
+	  | (1L << 2));
+}
+
+/* { dg-final { scan-assembler-times {\mlis\M}   1 } } */
+/* { dg-final { scan-assembler-times {\mpaddi\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mpli\M}   2 } } */
+/* { dg-final { scan-assembler-times {\msldi\M}  3 } } */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/meissner/heads/work055)] PR 101019: Improve loading 64-bit constants on power10.
@ 2021-06-10 20:37 Michael Meissner
  0 siblings, 0 replies; 6+ messages in thread
From: Michael Meissner @ 2021-06-10 20:37 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0dd95c9c4a410eff9178bb6d04097b0bf2065e14

commit 0dd95c9c4a410eff9178bb6d04097b0bf2065e14
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Thu Jun 10 16:36:58 2021 -0400

    PR 101019: Improve loading 64-bit constants on power10.
    
    When the support for prefixed instructions went into GCC, we did not
    modify loading up larger constants to use one or two PLI/PADDI
    instructions.  This patch adds this support.
    
    gcc/
    2021-06-10  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * config/rs6000/rs6000-cpus.def (ISA_3_1_MASKS_SERVER): Add
            -mpower10-large-consts support.
            (POWERPC_MASKS): Add -mpower10-large-consts support.
            * config/rs6000/rs6000.c (rs6000_option_override_internal): Add
            -mpower10-large-consts support.
            (num_insns_constant_gpr): Add -mpower10-large-consts support.
            (rs6000_emit_set_long_const): Add -mpower10-large-consts support.
            (rs6000_opt_masks): Add -mpower10-large-consts.
            * config/rs6000/rs6000.opt (-mpower10-large-consts): New switch.
    
    gcc/testsuite/
    2021-06-09  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * gcc.target/powerpc/prefix-large-const.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-cpus.def                  |  2 +
 gcc/config/rs6000/rs6000.c                         | 50 ++++++++++++++++++++--
 gcc/config/rs6000/rs6000.opt                       |  4 ++
 .../gcc.target/powerpc/prefix-large-const.c        | 32 ++++++++++++++
 4 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index c0d89434fcd..b119f574e4c 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -90,6 +90,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD		\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_XXSPLTI32DX		\
 				 | OPTION_MASK_XXSPLTIDP		\
 				 | OPTION_MASK_XXSPLTIW)
@@ -145,6 +146,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD    	\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_HTM			\
 				 | OPTION_MASK_ISEL			\
 				 | OPTION_MASK_LXVKQ			\
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca92ee63d73..93e14570ed3 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4489,6 +4489,12 @@ rs6000_option_override_internal (bool global_init_p)
       && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION_2ADD) == 0)
     rs6000_isa_flags |= OPTION_MASK_P10_FUSION_2ADD;
 
+  if (TARGET_PREFIXED
+      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_LARGE_CONSTS) == 0)
+    rs6000_isa_flags |= OPTION_MASK_P10_LARGE_CONSTS;
+  else if (!TARGET_PREFIXED)
+    rs6000_isa_flags &= ~OPTION_MASK_P10_LARGE_CONSTS;
+
   /* Turn off vector pair/mma options on non-power10 systems.  */
   else if (!TARGET_POWER10 && TARGET_MMA)
     {
@@ -5959,9 +5965,20 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
 	   && (value >> 31 == -1 || value >> 31 == 0))
     return 1;
 
-  /* PADDI can support up to 34 bit signed integers.  */
-  else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value))
-    return 1;
+  /* PADDI can support up to 34 bit signed integers, or using a combination of
+     PADDI and shift left.  */
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      if (SIGNED_INTEGER_34BIT_P (value))
+	return 1;
+
+      /* PLI and SLDI.  */
+      if ((value & 0xffffffff) == 0)
+	return 2;
+
+      /* PLI, SLDI, PADDI.  */
+      return 3;
+    }
 
   else if (TARGET_POWERPC64)
     {
@@ -10415,7 +10432,31 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
     }
-  else if ((ud4 == 0xffff && (ud3 & 0x8000))
+  /* We can't load R0 using PLI/SLDA/PADDI, since the R0 in the PADDI would be
+     interpreted as 0 and not register 0.  */
+  else if (TARGET_P10_LARGE_CONSTS
+	   && (base_reg_operand (dest, DImode)
+	       || can_create_pseudo_p ()
+	       || (ud1 == 0 && ud2 == 0)))
+    {
+      HOST_WIDE_INT low_32bit = ud1 | (ud2 << 16);
+      HOST_WIDE_INT high_32bit = ud3 | (ud4 << 16);
+
+      temp = !can_create_pseudo_p () ? copy_rtx (dest) : gen_reg_rtx (DImode);
+      emit_move_insn (temp, GEN_INT (high_32bit));
+
+      if (!low_32bit)
+	emit_insn (gen_ashldi3 (dest, temp, GEN_INT (32)));
+      else
+	{
+	  rtx temp2 = (!can_create_pseudo_p ()
+		       ? copy_rtx (dest)
+		       : gen_reg_rtx (DImode));
+	  emit_insn (gen_ashldi3 (temp2, temp, GEN_INT (32)));
+	  emit_insn (gen_adddi3 (dest, temp2, GEN_INT (low_32bit)));
+	}
+    }
+  else if ((ud4 == 0xaffff && (ud3 & 0x8000))
 	   || (ud4 == 0 && ! (ud3 & 0x8000)))
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
@@ -24424,6 +24465,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "power9-misc",		OPTION_MASK_P9_MISC,		false, true  },
   { "power9-vector",		OPTION_MASK_P9_VECTOR,		false, true  },
   { "power10-fusion",		OPTION_MASK_P10_FUSION,		false, true  },
+  { "power10-large-consts",	OPTION_MASK_P10_LARGE_CONSTS,	false, true  },
   { "powerpc-gfxopt",		OPTION_MASK_PPC_GFXOPT,		false, true  },
   { "powerpc-gpopt",		OPTION_MASK_PPC_GPOPT,		false, true  },
   { "prefixed",			OPTION_MASK_PREFIXED,		false, true  },
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index e65dd8762a4..add22c8be1a 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -655,3 +655,7 @@ Generate (do not generate) XXSPLTI32DX instructions.
 mlxvkq
 Target Undocumented Mask(LXVKQ) Var(rs6000_isa_flags)
 Generate (do not generate) LXVKQ instructions.
+
+mpower10-large-consts
+Target Undocumented Mask(P10_LARGE_CONSTS) Var(rs6000_isa_flags)
+Generate (do not generate) PLI/SLDI/PADDI to load large constants.
diff --git a/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
new file mode 100644
index 00000000000..f13812cbc27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_prefixed_addr } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Test whether we can use PLI/PADDI to load up large constants.  */
+
+long
+foo_1 (void)
+{
+  return 1L << 53;			/* LIS, SLDI.  */
+}
+
+long
+foo_2 (void)
+{
+  return (1L << 53) | (1L << 35);	/* PLI, SLDI.  */
+}
+
+long
+foo_3 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, PADDI.  */
+	  | (1L << 35)
+	  | (1L << 30)
+	  | (1L << 2);
+}
+
+/* { dg-final { scan-assembler-times {\mlis\M}   1 } } */
+/* { dg-final { scan-assembler-times {\mpaddi\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mpli\M}   2 } } */
+/* { dg-final { scan-assembler-times {\msldi\M}  3 } } */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/meissner/heads/work055)] PR 101019: Improve loading 64-bit constants on power10.
@ 2021-06-10 19:30 Michael Meissner
  0 siblings, 0 replies; 6+ messages in thread
From: Michael Meissner @ 2021-06-10 19:30 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:20d4275737ed00c617c4764f56454d07b8bd4264

commit 20d4275737ed00c617c4764f56454d07b8bd4264
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Thu Jun 10 15:30:13 2021 -0400

    PR 101019: Improve loading 64-bit constants on power10.
    
    When the support for prefixed instructions went into GCC, we did not
    modify loading up larger constants to use one or two PLI/PADDI
    instructions.  This patch adds this support.
    
    gcc/
    2021-06-10  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * config/rs6000/rs6000-cpus.def (ISA_3_1_MASKS_SERVER): Add
            -mpower10-large-consts support.
            (POWERPC_MASKS): Add -mpower10-large-consts support.
            * config/rs6000/rs6000.c (rs6000_option_override_internal): Add
            -mpower10-large-consts support.
            (num_insns_constant_gpr): Add -mpower10-large-consts support.
            (rs6000_emit_set_long_const): Add -mpower10-large-consts support.
            (rs6000_opt_masks): Add -mpower10-large-consts.
            * config/rs6000/rs6000.opt (-mpower10-large-consts): New switch.
    
    gcc/testsuite/
    2021-06-09  Michael Meissner  <meissner@linux.ibm.com>
    
            PR target/101019
            * gcc.target/powerpc/prefix-large-const.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-cpus.def                  |  2 +
 gcc/config/rs6000/rs6000.c                         | 51 ++++++++++++++++++++--
 gcc/config/rs6000/rs6000.opt                       |  4 ++
 .../gcc.target/powerpc/prefix-large-const.c        | 32 ++++++++++++++
 4 files changed, 85 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index c0d89434fcd..b119f574e4c 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -90,6 +90,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD		\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_XXSPLTI32DX		\
 				 | OPTION_MASK_XXSPLTIDP		\
 				 | OPTION_MASK_XXSPLTIW)
@@ -145,6 +146,7 @@
 				 | OPTION_MASK_P10_FUSION_LOGADD 	\
 				 | OPTION_MASK_P10_FUSION_ADDLOG	\
 				 | OPTION_MASK_P10_FUSION_2ADD    	\
+				 | OPTION_MASK_P10_LARGE_CONSTS		\
 				 | OPTION_MASK_HTM			\
 				 | OPTION_MASK_ISEL			\
 				 | OPTION_MASK_LXVKQ			\
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca92ee63d73..d51c0ad13d4 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4489,6 +4489,12 @@ rs6000_option_override_internal (bool global_init_p)
       && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION_2ADD) == 0)
     rs6000_isa_flags |= OPTION_MASK_P10_FUSION_2ADD;
 
+  if (TARGET_PREFIXED
+      && (rs6000_isa_flags_explicit & OPTION_MASK_P10_LARGE_CONSTS) == 0)
+    rs6000_isa_flags |= OPTION_MASK_P10_LARGE_CONSTS;
+  else if (!TARGET_PREFIXED)
+    rs6000_isa_flags &= ~OPTION_MASK_P10_LARGE_CONSTS;
+
   /* Turn off vector pair/mma options on non-power10 systems.  */
   else if (!TARGET_POWER10 && TARGET_MMA)
     {
@@ -5959,9 +5965,20 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
 	   && (value >> 31 == -1 || value >> 31 == 0))
     return 1;
 
-  /* PADDI can support up to 34 bit signed integers.  */
-  else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value))
-    return 1;
+  /* PADDI can support up to 34 bit signed integers, or using a combination of
+     PADDI and shift left.  */
+  else if (TARGET_P10_LARGE_CONSTS)
+    {
+      if (SIGNED_INTEGER_34BIT_P (value))
+	return 1;
+
+      /* PLI and SLDI.  */
+      if ((value & 0xffffffff) == 0)
+	return 2;
+
+      /* PLI, SLDI, PADDI.  */
+      return 3;
+    }
 
   else if (TARGET_POWERPC64)
     {
@@ -10366,6 +10383,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
   rtx temp;
   HOST_WIDE_INT ud1, ud2, ud3, ud4;
 
+  HOST_WIDE_INT orig_c = c;
   ud1 = c & 0xffff;
   c = c >> 16;
   ud2 = c & 0xffff;
@@ -10415,7 +10433,31 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
     }
-  else if ((ud4 == 0xffff && (ud3 & 0x8000))
+  /* We can't load R0 using PLI/SLDA/PADDI, since the R0 in the PADDI would be
+     interpreted as 0 and not register 0.  */
+  else if (TARGET_P10_LARGE_CONSTS
+	   && (base_reg_operand (dest, DImode)
+	       || can_create_pseudo_p ()
+	       || (ud1 == 0 && ud2 == 0)))
+    {
+      HOST_WIDE_INT low_32bit = ud1 | (ud2 << 16);
+      HOST_WIDE_INT high_32bit = ud3 | (ud4 << 16);
+
+      temp = !can_create_pseudo_p () ? copy_rtx (dest) : gen_reg_rtx (DImode);
+      emit_move_insn (temp, GEN_INT (high_32bit));
+
+      if (!low_32bit)
+	emit_insn (gen_ashldi3 (dest, temp, GEN_INT (32)));
+      else
+	{
+	  rtx temp2 = (!can_create_pseudo_p ()
+		       ? copy_rtx (dest)
+		       : gen_reg_rtx (DImode));
+	  emit_insn (gen_ashldi3 (temp2, temp, GEN_INT (32)));
+	  emit_insn (gen_adddi3 (dest, temp2, GEN_INT (low_32bit)));
+	}
+    }
+  else if ((ud4 == 0xaffff && (ud3 & 0x8000))
 	   || (ud4 == 0 && ! (ud3 & 0x8000)))
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
@@ -24424,6 +24466,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "power9-misc",		OPTION_MASK_P9_MISC,		false, true  },
   { "power9-vector",		OPTION_MASK_P9_VECTOR,		false, true  },
   { "power10-fusion",		OPTION_MASK_P10_FUSION,		false, true  },
+  { "power10-large-consts",	OPTION_MASK_P10_LARGE_CONSTS,	false, true  },
   { "powerpc-gfxopt",		OPTION_MASK_PPC_GFXOPT,		false, true  },
   { "powerpc-gpopt",		OPTION_MASK_PPC_GPOPT,		false, true  },
   { "prefixed",			OPTION_MASK_PREFIXED,		false, true  },
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index e65dd8762a4..add22c8be1a 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -655,3 +655,7 @@ Generate (do not generate) XXSPLTI32DX instructions.
 mlxvkq
 Target Undocumented Mask(LXVKQ) Var(rs6000_isa_flags)
 Generate (do not generate) LXVKQ instructions.
+
+mpower10-large-consts
+Target Undocumented Mask(P10_LARGE_CONSTS) Var(rs6000_isa_flags)
+Generate (do not generate) PLI/SLDI/PADDI to load large constants.
diff --git a/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
new file mode 100644
index 00000000000..f13812cbc27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_prefixed_addr } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Test whether we can use PLI/PADDI to load up large constants.  */
+
+long
+foo_1 (void)
+{
+  return 1L << 53;			/* LIS, SLDI.  */
+}
+
+long
+foo_2 (void)
+{
+  return (1L << 53) | (1L << 35);	/* PLI, SLDI.  */
+}
+
+long
+foo_3 (void)
+{
+  return ((1L << 53)			/* PLI, SLDI, PADDI.  */
+	  | (1L << 35)
+	  | (1L << 30)
+	  | (1L << 2);
+}
+
+/* { dg-final { scan-assembler-times {\mlis\M}   1 } } */
+/* { dg-final { scan-assembler-times {\mpaddi\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mpli\M}   2 } } */
+/* { dg-final { scan-assembler-times {\msldi\M}  3 } } */


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-06-11 23:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-10 16:33 [gcc(refs/users/meissner/heads/work055)] PR 101019: Improve loading 64-bit constants on power10 Michael Meissner
2021-06-10 19:30 Michael Meissner
2021-06-10 20:37 Michael Meissner
2021-06-10 22:55 Michael Meissner
2021-06-11 22:51 Michael Meissner
2021-06-11 23:05 Michael Meissner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).