public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-2155] rs6000: Add two peephole patterns for "mr." insn
@ 2023-06-28  8:50 HaoChen Gui
  0 siblings, 0 replies; only message in thread
From: HaoChen Gui @ 2023-06-28  8:50 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1554ab958afd4f4a94f776f3a7a03b40918bf424

commit r14-2155-g1554ab958afd4f4a94f776f3a7a03b40918bf424
Author: Haochen Gui <guihaoc@gcc.gnu.org>
Date:   Wed Jun 28 16:45:50 2023 +0800

    rs6000: Add two peephole patterns for "mr." insn
    
    When investigating the issue mentioned in PR87871#c30 - if compare
    and move pattern benefits before RA, I checked the assembly generated
    for SPEC2017 and found that certain insn sequences aren't converted to
    "mr." instructions.
    Following two sequence are never to be combined to "mr." pattern as
    there is no register link between them. This patch adds two peephole2
    patterns to convert them to "mr." instructions.
    
    cmp 0,3,0
    mr 4,3
    
    mr 4,3
    cmp 0,3,0
    
    The patch also creates a new mode iterator which decided by
    TARGET_POWERPC64.  This mode iterator is used in "mr." and its split
    pattern.  The original P iterator is improper when -m32/-mpowerpc64 is
    set.  In this situation, the "mr." should compares the whole 64-bit
    register with 0 other than the low 32-bit one.
    
    gcc/
            * config/rs6000/rs6000.md (peephole2 for compare_and_move): New.
            (peephole2 for move_and_compare): New.
            (mode_iterator WORD): New.  Set the mode to SI/DImode by
            TARGET_POWERPC64.
            (*mov<mode>_internal2): Change the mode iterator from P to WORD.
            (split pattern for compare_and_move): Likewise.
    
    gcc/testsuite/
            * gcc.dg/rtl/powerpc/move_compare_peephole_32.c: New.
            * gcc.dg/rtl/powerpc/move_compare_peephole_64.c: New.

Diff:
---
 gcc/config/rs6000/rs6000.md                        | 39 ++++++++++++--
 .../gcc.dg/rtl/powerpc/move_compare_peephole_32.c  | 60 ++++++++++++++++++++++
 .../gcc.dg/rtl/powerpc/move_compare_peephole_64.c  | 60 ++++++++++++++++++++++
 3 files changed, 155 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 75c5e5fc93d..cdab49fbb91 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -491,6 +491,7 @@
 ; The size of a pointer.  Also, the size of the value that a record-condition
 ; (one with a '.') will compare; and the size used for arithmetic carries.
 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
+(define_mode_iterator WORD [(SI "!TARGET_POWERPC64") (DI "TARGET_POWERPC64")])
 
 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
 ; PTImode is GPR only)
@@ -7879,9 +7880,9 @@
 
 (define_insn "*mov<mode>_internal2"
   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
-	(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
+	(compare:CC (match_operand:WORD 1 "gpc_reg_operand" "0,r,r")
 		    (const_int 0)))
-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
+   (set (match_operand:WORD 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
   ""
   "@
    cmp<wd>i %2,%0,0
@@ -7891,11 +7892,41 @@
    (set_attr "dot" "yes")
    (set_attr "length" "4,4,8")])
 
+(define_peephole2
+  [(set (match_operand:CC 2 "cc_reg_operand")
+	(compare:CC (match_operand:WORD 1 "int_reg_operand")
+		    (const_int 0)))
+   (set (match_operand:WORD 0 "int_reg_operand")
+	(match_dup 1))]
+  "!cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(parallel [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+		   (compare:CC (match_operand:WORD 1 "int_reg_operand" "r")
+		   (const_int 0)))
+	      (set (match_operand:WORD 0 "int_reg_operand" "=r")
+		   (match_dup 1))])]
+  ""
+)
+
+(define_peephole2
+  [(set (match_operand:WORD 0 "int_reg_operand")
+	(match_operand:WORD 1 "int_reg_operand"))
+   (set (match_operand:CC 2 "cc_reg_operand")
+	(compare:CC (match_dup 1)
+		    (const_int 0)))]
+  "!cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(parallel [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+		   (compare:CC (match_operand:GPR 1 "int_reg_operand" "r")
+		   (const_int 0)))
+	      (set (match_operand:WORD 0 "int_reg_operand" "=r")
+		   (match_dup 1))])]
+  ""
+)
+
 (define_split
   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
-	(compare:CC (match_operand:P 1 "gpc_reg_operand")
+	(compare:CC (match_operand:WORD 1 "gpc_reg_operand")
 		    (const_int 0)))
-   (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
+   (set (match_operand:WORD 0 "gpc_reg_operand") (match_dup 1))]
   "reload_completed"
   [(set (match_dup 0) (match_dup 1))
    (set (match_dup 2)
diff --git a/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_32.c b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_32.c
new file mode 100644
index 00000000000..571a3112a74
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_32.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target powerpc*-*-linux* } } */
+/* { dg-skip-if "" { has_arch_ppc64 } } */
+/* { dg-options "-O2 -mregnames" } */
+
+/* Following instruction sequence is found in assembly of
+   Perl_block_start, which is a function of op.c in SPEC2017
+   perlbench.  It can be never combined to a move and compare
+   instruction in combine pass.  A peephole pattern is needed to
+   converted the sequence to a "mr." instruction.
+
+	cmpdi 0,9,0
+	mr 12,9
+
+   This test case is an analogue of the source code and verifies
+   if the peephole2 patterns work.
+*/
+
+int __RTL (startwith ("peephole2")) compare_move_peephole ()
+{
+(function "compare_move_peephole"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 8 (set (reg:CC %cr0)
+                    (compare:CC (reg:SI %r3)
+                        (const_int 0))))
+      (cinsn 2 (set (reg:SI %r4)
+                    (reg:SI %r3)))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 18 (use (reg:SI %r4)))
+      (cinsn 19 (use (reg:CC %cr0)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+int __RTL (startwith ("peephole2")) move_compare_peephole ()
+{
+(function "move_compare_peephole"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 2 (set (reg:SI %r4)
+                    (reg:SI %r3)))
+      (cinsn 8 (set (reg:CC %cr0)
+                    (compare:CC (reg:SI %r3)
+                        (const_int 0))))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 18 (use (reg:SI %r4)))
+      (cinsn 19 (use (reg:CC %cr0)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+/* { dg-final { scan-assembler-times {\mmr\.} 2 } } */
diff --git a/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_64.c b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_64.c
new file mode 100644
index 00000000000..e25d655fb29
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_64.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target powerpc*-*-linux* } } */
+/* { dg-options "-O2 -mregnames" } */
+/* { dg-require-effective-target has_arch_ppc64 } */
+
+/* Following instruction sequence is found in assembly of
+   Perl_block_start, which is a function of op.c in SPEC2017
+   perlbench.  It can be never combined to a move and compare
+   instruction in combine pass.  A peephole pattern is needed to
+   converted the sequence to a "mr." instruction.
+
+	cmpdi 0,9,0
+	mr 12,9
+
+   This test case is an analogue of the source code and verifies
+   if the peephole2 patterns work.
+*/
+
+int __RTL (startwith ("peephole2")) compare_move_peephole ()
+{
+(function "compare_move_peephole"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 8 (set (reg:CC %cr0)
+                    (compare:CC (reg:DI %r3)
+                        (const_int 0))))
+      (cinsn 2 (set (reg:DI %r4)
+                    (reg:DI %r3)))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 18 (use (reg:DI %r4)))
+      (cinsn 19 (use (reg:CC %cr0)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+int __RTL (startwith ("peephole2")) move_compare_peephole ()
+{
+(function "move_compare_peephole"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 2 (set (reg:DI %r4)
+                    (reg:DI %r3)))
+      (cinsn 8 (set (reg:CC %cr0)
+                    (compare:CC (reg:DI %r3)
+                        (const_int 0))))
+      ;; Extra insn to avoid the above being deleted by DCE.
+      (cinsn 18 (use (reg:DI %r4)))
+      (cinsn 19 (use (reg:CC %cr0)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "main"
+}
+
+/* { dg-final { scan-assembler-times {\mmr\.} 2 } } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-28  8:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-28  8:50 [gcc r14-2155] rs6000: Add two peephole patterns for "mr." insn HaoChen Gui

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).