From d0ae0f51fa0dfc1f8dfbc9ea4e51e3389460568c Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Tue, 19 May 2015 08:00:41 +0000 Subject: [PATCH] re PR target/54236 ([SH] Improve addc and subc insn utilization) gcc/ PR target/54236 * config/sh/sh.md (*round_int_even): New insn_and_split and accompanying new unnamed split. gcc/testsuite/ PR target/54236 * gcc.target/sh/pr54236-2.c: Adjust expected insn counts. From-SVN: r223346 --- gcc/ChangeLog | 6 ++++ gcc/config/sh/sh.md | 38 +++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/sh/pr54236-2.c | 16 ++++++++--- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c87f6453a5f..dd8f5c7f7ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-05-19 Oleg Endo + + PR target/54236 + * config/sh/sh.md (*round_int_even): New insn_and_split and + accompanying new unnamed split. + 2015-05-19 Richard Sandiford * bitmap.c (bitmap_set_range): Handle count==1 specially. diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index eb6983aec97..3b669928a20 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -1998,6 +1998,44 @@ [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))]) + +;; The tree optimiziers canonicalize +;; reg + (reg & 1) +;; into +;; (reg + 1) & -2 +;; +;; On SH2A an add-bclr sequence will be used to handle this. +;; On non-SH2A re-emit the add-and sequence to improve register utilization. +(define_insn_and_split "*round_int_even" + [(set (match_operand:SI 0 "arith_reg_dest") + (and:SI (plus:SI (match_operand:SI 1 "arith_reg_operand") + (const_int 1)) + (const_int -2)))] + "TARGET_SH1 && !TARGET_SH2A && can_create_pseudo_p ()" + "#" + "&& 1" + [(set (match_dup 0) (const_int -2)) + (set (match_dup 2) (plus:SI (match_dup 1) (const_int 1))) + (set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))] +{ + operands[2] = gen_reg_rtx (SImode); +}) + +;; If the *round_int_even pattern is combined with another plus, +;; convert it into an addc pattern to emit an shlr-addc sequence. +;; This split is taken by combine on non-SH2A and SH2A. +(define_split + [(set (match_operand:SI 0 "arith_reg_dest") + (plus:SI (and:SI (plus:SI (match_operand:SI 1 "arith_reg_operand") + (const_int 1)) + (const_int -2)) + (match_operand:SI 2 "arith_reg_operand")))] + "TARGET_SH1 && can_create_pseudo_p ()" + [(parallel [(set (match_dup 0) + (plus:SI (plus:SI (match_dup 1) (match_dup 2)) + (and:SI (match_dup 1) (const_int 1)))) + (clobber (reg:SI T_REG))])]) + ;; Split 'reg + T' into 'reg + 0 + T' to utilize the addc insn. ;; If the 0 constant can be CSE-ed, this becomes a one instruction ;; operation, as opposed to sequences such as diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7987859653e..28533716d91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-05-19 Oleg Endo + + PR target/54236 + * gcc.target/sh/pr54236-2.c: Adjust expected insn counts. + 2015-05-19 Sameera Deshpande * gcc.target/mips/p5600-bonding.c : New file. diff --git a/gcc/testsuite/gcc.target/sh/pr54236-2.c b/gcc/testsuite/gcc.target/sh/pr54236-2.c index b3cf48c9d32..b94c2c0a5e2 100644 --- a/gcc/testsuite/gcc.target/sh/pr54236-2.c +++ b/gcc/testsuite/gcc.target/sh/pr54236-2.c @@ -4,12 +4,19 @@ /* { dg-do compile } */ /* { dg-options "-O1" } */ /* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ -/* { dg-final { scan-assembler-times "addc" 37 } } */ -/* { dg-final { scan-assembler-times "shlr" 23 } } */ +/* { dg-final { scan-assembler-times "addc" 36 } } */ +/* { dg-final { scan-assembler-times "shlr" 22 } } */ /* { dg-final { scan-assembler-times "shll" 14 } } */ -/* { dg-final { scan-assembler-times "add\t" 12 } } */ +/* { dg-final { scan-assembler-times "add\tr" 12 } } */ /* { dg-final { scan-assembler-not "movt" } } */ +/* { dg-final { scan-assembler-times "add\t#1" 1 } } */ + +/* { dg-final { scan-assembler-times "mov\t#-2" 1 { target { ! sh2a } } } } */ +/* { dg-final { scan-assembler-times "and\tr" 1 { target { ! sh2a } } } } */ + +/* { dg-final { scan-assembler-times "bclr\t#0" 1 { target { sh2a } } } } */ + int test_000 (int a, int c, int b, int d) { @@ -125,7 +132,8 @@ test_015 (int a, int c, int b, int d) int test_016 (int a, int b, int c, int d) { - // 1x shlr, 1x addc + // non-SH2A: 1x add #1, 1x mov #-2, 1x and + // SH2A: 1x add #1, 1x blcr #0 return a + (a & 1); } -- 2.30.2