Hi, By checking the object files of SPECint, I found that two kinds of compare/move can't be combined to "mr." pattern as there is no register link between them. The patch adds two peephole2 patterns for them.
Bootstrapped and tested on powerpc64-linux BE and LE with no regressions. Thanks Gui Haochen ChangeLog rs6000: Add two peephole patterns for "mr." insn Following two insns are never to be combined to "mr." pattern as there is no register link between them. So the patch adds these two peepholes. cmp 0,3,0 mr 4,3 mr 4,3 cmp 0,3,0 gcc/ * config/rs6000/rs6000.md (peephole2 for compare and move): New. (peephole2 for move and compare): New. gcc/testsuite/ * gcc.dg/rtl/powerpc/move_compare_peephole_32.c: New. * gcc.dg/rtl/powerpc/move_compare_peephole_64.c: New. patch.diff diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index b0db8ae508d..b60230293f9 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -7891,6 +7891,36 @@ (define_insn "*mov<mode>_internal2" (set_attr "dot" "yes") (set_attr "length" "4,4,8")]) +(define_peephole2 + [(set (match_operand:CC 2 "cc_reg_operand" "") + (compare:CC (match_operand:P 1 "int_reg_operand" "") + (const_int 0))) + (set (match_operand:P 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:P 1 "int_reg_operand" "r") + (const_int 0))) + (set (match_operand:P 0 "int_reg_operand" "=r") + (match_dup 1))])] + "" +) + +(define_peephole2 + [(set (match_operand:P 0 "int_reg_operand" "") + (match_operand:P 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:P 1 "int_reg_operand" "r") + (const_int 0))) + (set (match_operand:P 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") 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..4e094c8fe74 --- /dev/null +++ b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_32.c @@ -0,0 +1,47 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-skip-if "" { has_arch_ppc64 } } */ +/* { dg-options "-O2 -mregnames" } */ + +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..511d6cc5317 --- /dev/null +++ b/gcc/testsuite/gcc.dg/rtl/powerpc/move_compare_peephole_64.c @@ -0,0 +1,47 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-options "-O2 -mregnames" } */ +/* { dg-require-effective-target has_arch_ppc64 } */ + +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 } } */