diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2012-03-11 13:18:08 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2012-03-11 13:18:08 +0000 |
commit | 07c0b5604acc658ba193b2b5f0c592ade689e8e4 (patch) | |
tree | 56ef3c7d27a282bc4adfe5a73ccf5a4006a346c3 | |
parent | 9237e39d541a9eed92f0487d681ba9d6bdefa7ee (diff) | |
download | gcc-07c0b5604acc658ba193b2b5f0c592ade689e8e4.zip gcc-07c0b5604acc658ba193b2b5f0c592ade689e8e4.tar.gz gcc-07c0b5604acc658ba193b2b5f0c592ade689e8e4.tar.bz2 |
re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)
PR target/51244
* config/sh/sh.md (movnegt): Expand into respective insns immediately.
Use movrt_negc instead of negc pattern for non-SH2A.
(*movnegt): Remove.
(*movrt_negc, *negnegt, *movtt, *movt_qi): New insns and splits.
PR target/51244
* gcc.target/sh/pr51244-1.c: Fix thinkos.
From-SVN: r185192
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 91 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr51244-1.c | 12 |
4 files changed, 90 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e5b4a9..faafd80 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-03-11 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/51244 + * config/sh/sh.md (movnegt): Expand into respective insns immediately. + Use movrt_negc instead of negc pattern for non-SH2A. + (*movnegt): Remove. + (*movrt_negc, *negnegt, *movtt, *movt_qi): New insns and splits. + 2012-03-10 H.J. Lu <hongjiu.lu@intel.com> * config/i386/i386.c (ix86_decompose_address): Disallow fs:(reg) diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index eb1c852..528a120 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -9679,37 +9679,88 @@ mov.l\\t1f,r0\\n\\ ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively ;; becomes a one instruction operation. Moreover, care must be taken that ;; the insn can still be combined with inverted compare and branch code -;; around it. -;; The expander will reserve the constant -1, the insn makes the whole thing -;; combinable, the splitter finally emits the insn if it was not combined -;; away. -;; Notice that when using the negc variant the T bit also gets inverted. +;; around it. On the other hand, if a function returns the complement of +;; a previous comparison result in the T bit, the xor #1,r0 approach might +;; lead to better code. (define_expand "movnegt" - [(set (match_dup 1) (const_int -1)) - (parallel [(set (match_operand:SI 0 "arith_reg_dest" "") - (xor:SI (reg:SI T_REG) (const_int 1))) - (use (match_dup 1))])] + [(set (match_operand:SI 0 "arith_reg_dest" "") + (xor:SI (reg:SI T_REG) (const_int 1)))] "" { - operands[1] = gen_reg_rtx (SImode); + if (TARGET_SH2A) + emit_insn (gen_movrt (operands[0])); + else + { + rtx val = force_reg (SImode, gen_int_mode (-1, SImode)); + emit_insn (gen_movrt_negc (operands[0], val)); + } + DONE; }) -(define_insn_and_split "*movnegt" +(define_insn "movrt_negc" [(set (match_operand:SI 0 "arith_reg_dest" "=r") (xor:SI (reg:SI T_REG) (const_int 1))) + (set (reg:SI T_REG) (const_int 1)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "TARGET_SH1" + "negc %1,%0" + [(set_attr "type" "arith")]) + +;; The *negnegt patterns help the combine pass to figure out how to fold +;; an explicit double T bit negation. +(define_insn_and_split "*negnegt" + [(set (reg:SI T_REG) + (eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 3) + (const_int 0)))] + "! TARGET_LITTLE_ENDIAN" "#" - "&& 1" - [(const_int 0)] -{ - if (TARGET_SH2A) - emit_insn (gen_movrt (operands[0])); - else - emit_insn (gen_negc (operands[0], operands[1])); - DONE; -} + "" + [(const_int 0)]) + +(define_insn_and_split "*negnegt" + [(set (reg:SI T_REG) + (eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 0) + (const_int 0)))] + "TARGET_LITTLE_ENDIAN" + "#" + "" + [(const_int 0)]) + +;; The *movtt patterns improve code at -O1. +(define_insn_and_split "*movtt" + [(set (reg:SI T_REG) + (eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 3)) + (const_int 1)))] + "! TARGET_LITTLE_ENDIAN" + "#" + "" + [(const_int 0)]) + +(define_insn_and_split "*movtt" + [(set (reg:SI T_REG) + (eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 0)) + (const_int 1)))] + "TARGET_LITTLE_ENDIAN" + "#" + "" + [(const_int 0)]) + +;; The *movt_qi patterns help the combine pass convert a movrt_negc pattern +;; into a movt Rn, xor #1 Rn pattern. This can happen when e.g. a function +;; returns the inverted T bit value. +(define_insn "*movt_qi" + [(set (match_operand:SI 0 "arith_reg_dest" "=r") + (zero_extend:SI (subreg:QI (reg:SI T_REG) 3)))] + "! TARGET_LITTLE_ENDIAN" + "movt %0" + [(set_attr "type" "arith")]) + +(define_insn "*movt_qi" + [(set (match_operand:SI 0 "arith_reg_dest" "=r") + (zero_extend:SI (subreg:QI (reg:SI T_REG) 0)))] + "TARGET_LITTLE_ENDIAN" + "movt %0" [(set_attr "type" "arith")]) (define_expand "cstoresf4" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0234217..a9a3120 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-03-11 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/51244 + * gcc.target/sh/pr51244-1.c: Fix thinkos. + 2012-03-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> PR target/52450 diff --git a/gcc/testsuite/gcc.target/sh/pr51244-1.c b/gcc/testsuite/gcc.target/sh/pr51244-1.c index 57af104..34e1b02 100644 --- a/gcc/testsuite/gcc.target/sh/pr51244-1.c +++ b/gcc/testsuite/gcc.target/sh/pr51244-1.c @@ -13,20 +13,20 @@ testfunc_00 (int a, int b, int c, int d) } int -testfunc_01 (int a, char* p, int b, int c) +testfunc_01 (int a, int b, int c, int d) { - return (a == b && a == c) ? b : c; + return (a == b || a == d) ? b : c; } int -testfunc_02 (int a, char* p, int b, int c) +testfunc_02 (int a, int b, int c, int d) { - return (a == b && a == c) ? b : c; + return (a == b && a == d) ? b : c; } int -testfunc_03 (int a, char* p, int b, int c) +testfunc_03 (int a, int b, int c, int d) { - return (a != b && a != c) ? b : c; + return (a != b && a != d) ? b : c; } |