diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2014-05-21 08:06:06 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2014-05-21 08:06:06 +0000 |
commit | c4e5de1b1af1b33acbbe5a2271ff37405d1d17b5 (patch) | |
tree | dd5b8b640423eb178d547c1a5e4da925bd8c59a6 | |
parent | decaaec8116ffefcc2a260185c133333834eb083 (diff) | |
download | gcc-c4e5de1b1af1b33acbbe5a2271ff37405d1d17b5.zip gcc-c4e5de1b1af1b33acbbe5a2271ff37405d1d17b5.tar.gz gcc-c4e5de1b1af1b33acbbe5a2271ff37405d1d17b5.tar.bz2 |
re PR target/54236 ([SH] Improve addc and subc insn utilization)
gcc/
PR target/54236
* config/sh/sh.md (*addc_r_1): Rename to addc_t_r. Remove empty
constraints.
(*addc_r_t): Add new insn_and_split.
gcc/testsuite/
PR target/54236
* gcc.target/sh/pr54236-3.c: New.
From-SVN: r210682
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 23 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr54236-3.c | 31 |
4 files changed, 62 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f167e76..e2e3dd3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-05-21 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/54236 + * config/sh/sh.md (*addc_r_1): Rename to addc_t_r. Remove empty + constraints. + (*addc_r_t): Add new insn_and_split. + 2014-05-21 Jakub Jelinek <jakub@redhat.com> PR middle-end/61252 diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 0250f92..d998af9 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -1830,6 +1830,8 @@ ;; We allow a reg or 0 for one of the operands in order to be able to ;; do 'reg + T' sequences. Reload will load the constant 0 into the reg ;; as needed. +;; FIXME: The load of constant 0 should be split out before reload, or else +;; it will be difficult to hoist or combine the constant load. (define_insn "*addc" [(set (match_operand:SI 0 "arith_reg_dest" "=r") (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0") @@ -1898,10 +1900,10 @@ ;; can be scheduled much better since the load of the constant can be ;; done earlier, before any comparison insns that store the result in ;; the T bit. -(define_insn_and_split "*addc_r_1" - [(set (match_operand:SI 0 "arith_reg_dest" "") - (plus:SI (match_operand:SI 1 "t_reg_operand" "") - (match_operand:SI 2 "arith_reg_operand" ""))) +(define_insn_and_split "*addc_t_r" + [(set (match_operand:SI 0 "arith_reg_dest") + (plus:SI (match_operand:SI 1 "t_reg_operand") + (match_operand:SI 2 "arith_reg_operand"))) (clobber (reg:SI T_REG))] "TARGET_SH1" "#" @@ -1911,6 +1913,19 @@ (match_dup 1))) (clobber (reg:SI T_REG))])]) +(define_insn_and_split "*addc_r_t" + [(set (match_operand:SI 0 "arith_reg_dest") + (plus:SI (match_operand:SI 1 "arith_reg_operand") + (match_operand:SI 2 "t_reg_operand"))) + (clobber (reg:SI T_REG))] + "TARGET_SH1" + "#" + "&& 1" + [(parallel [(set (match_dup 0) + (plus:SI (plus:SI (match_dup 1) (const_int 0)) + (match_dup 2))) + (clobber (reg:SI T_REG))])]) + ;; Use shlr-addc to do 'reg + (reg & 1)'. (define_insn_and_split "*addc_r_lsb" [(set (match_operand:SI 0 "arith_reg_dest") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a5d155c..802f654 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-05-21 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/54236 + * gcc.target/sh/pr54236-3.c: New. + 2014-05-21 Igor Zamyatin <igor.zamyatin@intel.com> PR c++/60189 diff --git a/gcc/testsuite/gcc.target/sh/pr54236-3.c b/gcc/testsuite/gcc.target/sh/pr54236-3.c new file mode 100644 index 0000000..fc0d111 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr54236-3.c @@ -0,0 +1,31 @@ +/* Tests to check the utilization of the addc and subc instructions. + If everything works as expected we won't see any movt instructions in + these cases. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ +/* { dg-final { scan-assembler-times "addc" 1 } } */ +/* { dg-final { scan-assembler-times "subc" 1 } } */ +/* { dg-final { scan-assembler-not "movt" } } */ + +int +test_000 (int* x, unsigned int c) +{ + /* 1x addc */ + int s = 0; + unsigned int i; + for (i = 0; i < c; ++i) + s += ! (x[i] & 0x3000); + return s; +} + +int +test_001 (int* x, unsigned int c) +{ + /* 1x subc */ + int s = 0; + unsigned int i; + for (i = 0; i < c; ++i) + s -= ! (x[i] & 0x3000); + return s; +} |