]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)
authorOleg Endo <olegendo@gcc.gnu.org>
Fri, 16 May 2014 22:54:32 +0000 (22:54 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Fri, 16 May 2014 22:54:32 +0000 (22:54 +0000)
gcc/
PR target/51244
* config/sh/sh.c (sh_eval_treg_value): Handle t_reg_operand and
negt_reg_operand cases.
* config/sh/sh.md (*cset_zero): Likewise by using cbranch_treg_value
predicate.
* config/sh/predicates.md (cbranch_treg_value): Simplify.

From-SVN: r210535

gcc/ChangeLog
gcc/config/sh/predicates.md
gcc/config/sh/sh.c
gcc/config/sh/sh.md

index dcc0f8f22af4b8e9a479d4a8f5770f707199eaa4..2af2ef3b7b85e99cb75a53b1716deccb3a24845a 100644 (file)
@@ -1,3 +1,12 @@
+2014-05-16  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/51244
+       * config/sh/sh.c (sh_eval_treg_value): Handle t_reg_operand and
+       negt_reg_operand cases.
+       * config/sh/sh.md (*cset_zero): Likewise by using cbranch_treg_value
+       predicate.
+       * config/sh/predicates.md (cbranch_treg_value): Simplify.
+
 2014-05-16  Oleg Endo  <olegendo@gcc.gnu.org>
 
        * config/sh/sh.c (sh_option_override): Set branch cost to 2 for all
index 31f2e1f5a0b972875cb460d19fe42999764f9058..1307bbf7d3bdc55695b33ae3fb2cc9fdfa70f489 100644 (file)
 ;; A predicate that returns true if OP is a valid construct around the T bit
 ;; that can be used as an operand for conditional branches.
 (define_predicate "cbranch_treg_value"
-  (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend")
-{
-  return sh_eval_treg_value (op) >= 0;
-})
+  (and (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend")
+       (match_test "sh_eval_treg_value (op) >= 0")))
 
 ;; Returns true if OP is arith_reg_operand or t_reg_operand.
 (define_predicate "arith_reg_or_t_reg_operand"
index d52e8c1139e72be82306378c0bff39a04de2a5c2..a0c46283e2ec9d117917aa6eb2a699ff4c683793 100644 (file)
@@ -2250,7 +2250,12 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
 int
 sh_eval_treg_value (rtx op)
 {
-  enum rtx_code code = GET_CODE (op);
+  if (t_reg_operand (op, GET_MODE (op)))
+    return 1;
+  if (negt_reg_operand (op, GET_MODE (op)))
+    return 0;
+
+  rtx_code code = GET_CODE (op);
   if ((code != EQ && code != NE) || !CONST_INT_P (XEXP (op, 1)))
     return -1;
 
index 367f4ef2bbfc2bbd7d922e6d6d0152e400999a12..640188e5d5620ff30fa8a158ea99b8b35e236fa1 100644 (file)
@@ -11624,14 +11624,22 @@ label:
 
 (define_insn "*cset_zero"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
-       (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
+       (if_then_else:SI (match_operand:SI 1 "cbranch_treg_value")
                         (match_operand:SI 2 "arith_reg_operand" "0")
                         (const_int 0)))]
   "TARGET_SH1 && TARGET_ZDCBRANCH"
 {
-  return       "bt     0f"     "\n"
-        "      mov     #0,%0"  "\n"
-        "0:";
+  int tval = sh_eval_treg_value (operands[1]);
+  if (tval == true)
+    return     "bt     0f"     "\n"
+          "    mov     #0,%0"  "\n"
+          "0:";
+  else if (tval == false)
+    return     "bf     0f"     "\n"
+          "    mov     #0,%0"  "\n"
+          "0:";
+  else
+    gcc_unreachable ();
 }
   [(set_attr "type" "arith") ;; poor approximation
    (set_attr "length" "4")])