re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)
authorOleg Endo <olegendo@gcc.gnu.org>
Mon, 20 Aug 2012 20:51:06 +0000 (20:51 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Mon, 20 Aug 2012 20:51:06 +0000 (20:51 +0000)
PR target/51244
* config/sh/sh.md (*cset_zero): New insns.

PR target/51244
* gcc.target/sh/pr51244-11.c: New.

From-SVN: r190544

gcc/ChangeLog
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr51244-11.c [new file with mode: 0644]

index 677fc17c24298c9d68e2b63f2b88f279cac64406..03a2afe15d648382bcbccda2ffed82ca2b58b5a1 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-20  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/51244
+       * config/sh/sh.md (*cset_zero): New insns.
+
 2012-08-20  Mark Wielaard  <mjw@redhat.com>
 
        * dwarf2out.h (enum dw_val_class): Add dw_val_class_high_pc.
index 26d3e636d9144740f4c65cba3866daf7cb468712..9a58f8acd1feb569ff28a381d68a75096294b2fa 100644 (file)
@@ -10409,6 +10409,41 @@ label:
   operands[0] = gen_reg_rtx (SImode);
 })
 
+;; The *cset_zero patterns convert optimizations such as
+;;     "if (test) x = 0;" to "x &= -(test == 0);"
+;; back to conditional branch sequences if zero-displacement branches
+;; are enabled.
+;; FIXME: These patterns can be removed when conditional execution patterns
+;; are implemented, since ifcvt will not perform these optimizations if
+;; conditional execution is supported.
+(define_insn "*cset_zero"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+       (and:SI (plus:SI (match_operand:SI 1 "t_reg_operand")
+                        (const_int -1))
+               (match_operand:SI 2 "arith_reg_operand" "0")))]
+  "TARGET_SH1 && TARGET_ZDCBRANCH"
+{
+  return       "bf     0f"     "\n"
+        "      mov     #0,%0"  "\n"
+        "0:";
+}
+  [(set_attr "type" "arith") ;; poor approximation
+   (set_attr "length" "4")])
+
+(define_insn "*cset_zero"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+       (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
+                        (match_operand:SI 2 "arith_reg_operand" "0")
+                        (const_int 0)))]
+  "TARGET_SH1 && TARGET_ZDCBRANCH"
+{
+  return       "bt     0f"     "\n"
+        "      mov     #0,%0"  "\n"
+        "0:";
+}
+  [(set_attr "type" "arith") ;; poor approximation
+   (set_attr "length" "4")])
+
 (define_expand "cstoresf4"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (match_operator:SI 1 "sh_float_comparison_operator"
index 0b1bf5a21da006b1e3787c3da8056d94f9a78960..ecff56c25e3a4a2bff4af1bf68106c28a1eed04f 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-20  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/51244
+       * gcc.target/sh/pr51244-11.c: New.
+
 2012-08-20  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/54301
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-11.c b/gcc/testsuite/gcc.target/sh/pr51244-11.c
new file mode 100644 (file)
index 0000000..4a9c93c
--- /dev/null
@@ -0,0 +1,24 @@
+/* Check that zero-displacement branches are used instead of branch-free
+   execution patterns.  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1 -mzdcbranch" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-not "subc|and" } } */
+
+int*
+test_00 (int* s)
+{
+  if (s[0] == 0)
+    if (!s[3])
+      s = 0;
+  return s;
+}
+
+int*
+test_01 (int* s)
+{
+  if (s[0] == 0)
+    if (s[3])
+      s = 0;
+  return s;
+}