public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jiufu Guo <guojiufu@linux.ibm.com>
To: gcc-patches@gcc.gnu.org
Cc: segher@kernel.crashing.org, dje.gcc@gmail.com, linkw@gcc.gnu.org,
	guojiufu@linux.ibm.com
Subject: [PATCH] rs6000: Enable generate const through pli+pli+rldimi
Date: Wed, 10 Aug 2022 15:11:23 +0800	[thread overview]
Message-ID: <20220810071123.165157-1-guojiufu@linux.ibm.com> (raw)

Hi,

As mentioned in PR106550, since pli could support 34bits immediate, we could
use less instructions(3insn would be ok) to build 64bits constant with pli.

For example, for constant 0x020805006106003, we could generate it with:
asm code1:
pli 9,101736451 (0x6106003)
sldi 9,9,32
paddi 9,9, 2130000 (0x0208050)

or asm code2:
pli 10, 2130000
pli 9, 101736451
rldimi 9, 10, 32, 0

If there is only one register can be used, then the asm code1 is ok. Otherwise
asm code2 may be better.

This patch re-enable the constant building(splitter) before RA by updating the
constrains from int_reg_operand_not_pseudo to gpc_reg_operand.  And then, we
could use two different pseduo for two pli(s), and asm code2 can be generated.

This patch also could generate asm code1 if hard register is allocated for the
constant.

This patch pass boostrap and regtest on ppc64le(includes p10).
Is it ok for trunk?

BR,
Jeff(Jiufu)


	PR target/106550

gcc/ChangeLog:

	* config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Enable constant
	build with pli instructions.
	* config/rs6000/rs6000.md: Use gpc_reg_operand for constant splitter.

gcc/testsuite/ChangeLog:

	* gcc.target/powerpc/pr106550.c: New test.


---
 gcc/config/rs6000/rs6000.cc                 | 40 +++++++++++++++++++++
 gcc/config/rs6000/rs6000.md                 |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr106550.c | 14 ++++++++
 3 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr106550.c

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index df491bee2ea..a2e6b7f59a0 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -10181,6 +10181,46 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
 			gen_rtx_IOR (DImode, copy_rtx (temp),
 				     GEN_INT (ud1)));
     }
+  else if (TARGET_PREFIXED)
+    {
+      /* pli 9,high32 + pli 10,low32 + rldimi 9,10,32,0.  */
+      if (can_create_pseudo_p ())
+	{
+	  temp = gen_reg_rtx (DImode);
+	  rtx temp1 = gen_reg_rtx (DImode);
+	  emit_move_insn (copy_rtx (temp), GEN_INT ((ud4 << 16) | ud3));
+	  emit_move_insn (copy_rtx (temp1), GEN_INT ((ud2 << 16) | ud1));
+
+	  rtx one = gen_rtx_AND (DImode, temp1, GEN_INT (0xffffffff));
+	  rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
+	  emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
+	}
+
+      /* pli 9,high32 + sldi 9,32 + paddi 9,9,low32.  */
+      else
+	{
+	  emit_move_insn (copy_rtx (dest), GEN_INT ((ud4 << 16) | ud3));
+
+	  emit_move_insn (copy_rtx (dest),
+			  gen_rtx_ASHIFT (DImode, copy_rtx (dest),
+					  GEN_INT (32)));
+
+	  bool cannot_use_paddi = REGNO (dest) == FIRST_GPR_REGNO;
+
+	  /* Use paddi for the low32 bits.  */
+	  if (ud2 != 0 && ud1 != 0 && !cannot_use_paddi)
+	    emit_move_insn (dest, gen_rtx_PLUS (DImode, copy_rtx (dest),
+						GEN_INT ((ud2 << 16) | ud1)));
+	  /* Use oris, ori for low32 bits.  */
+	  if (ud2 != 0 && (ud1 == 0 || cannot_use_paddi))
+	    emit_move_insn (ud1 != 0 ? copy_rtx (dest) : dest,
+			    gen_rtx_IOR (DImode, copy_rtx (dest),
+					 GEN_INT (ud2 << 16)));
+	  if (ud1 != 0 && (ud2 == 0 || cannot_use_paddi))
+	    emit_move_insn (dest, gen_rtx_IOR (DImode, copy_rtx (dest),
+					       GEN_INT (ud1)));
+	}
+    }
   else
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 1367a2cb779..abe777a593c 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -9659,7 +9659,7 @@ (define_split
 ;; When non-easy constants can go in the TOC, this should use
 ;; easy_fp_constant predicate.
 (define_split
-  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
+  [(set (match_operand:DI 0 "gpc_reg_operand")
 	(match_operand:DI 1 "const_int_operand"))]
   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
   [(set (match_dup 0) (match_dup 2))
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106550.c b/gcc/testsuite/gcc.target/powerpc/pr106550.c
new file mode 100644
index 00000000000..bca7760bad9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr106550.c
@@ -0,0 +1,14 @@
+/* PR target/106550 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -std=c99 -mdejagnu-cpu=power10" } */
+
+void
+foo (unsigned long long *a)
+{
+  *a++ = 0x020805006106003;
+  *a++ = 0x2351847027482577;  
+}
+
+/* { dg-final { scan-assembler-times {\mpli\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mrldimi\M} 2 } } */
+
-- 
2.17.1


             reply	other threads:[~2022-08-10  7:11 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-10  7:11 Jiufu Guo [this message]
2022-08-10 16:43 ` Segher Boessenkool
2022-08-11 12:52   ` Jiufu Guo
2022-08-11 13:48     ` Segher Boessenkool

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220810071123.165157-1-guojiufu@linux.ibm.com \
    --to=guojiufu@linux.ibm.com \
    --cc=dje.gcc@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=linkw@gcc.gnu.org \
    --cc=segher@kernel.crashing.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).