re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)
authorOleg Endo <olegendo@gcc.gnu.org>
Wed, 17 Dec 2014 22:52:21 +0000 (22:52 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Wed, 17 Dec 2014 22:52:21 +0000 (22:52 +0000)
gcc/
PR target/51244
* config/sh/sh_treg_combine.cc (sh_treg_combine::try_optimize_cbranch):
Combine ccreg inversion and cbranch into inverted cbranch.

From-SVN: r218847

gcc/ChangeLog
gcc/config/sh/sh_treg_combine.cc

index 87940a24a4e0c74dabd3b1e5d76e176355de0a01..00b37280adc02ce3866b4fec697c636d3cca39a5 100644 (file)
@@ -1,3 +1,9 @@
+2014-12-17  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/51244
+       * config/sh/sh_treg_combine.cc (sh_treg_combine::try_optimize_cbranch):
+       Combine ccreg inversion and cbranch into inverted cbranch.
+
 2014-12-17  Vladimir Makarov  <vmakarov@redhat.com>
 
        * lra-constraints.c (process_alt_operands): Remove non
index 68c7fc1cc6d1c65c0d8e8bf2e327516ee24256c8..62392d81f1bfb4b42e1b8a0df8e1b3c2113e8b43 100644 (file)
@@ -1339,9 +1339,17 @@ sh_treg_combine::try_optimize_cbranch (rtx_insn *insn)
   // for now we limit the search to the current basic block.
   trace.setcc = find_set_of_reg_bb (m_ccreg, prev_nonnote_insn_bb (insn));
 
-  if (!is_cmp_eq_zero (trace.setcc.set_src ()))
+  if (trace.setcc.set_src () == NULL_RTX)
     log_return_void ("could not find set of ccreg in current BB\n");
 
+  if (!is_cmp_eq_zero (trace.setcc.set_src ())
+      && !is_inverted_ccreg (trace.setcc.set_src ()))
+    {
+      log_msg ("unsupported set of ccreg in current BB: ");
+      log_rtx (trace.setcc.set_src ());
+      log_return_void ("\n");
+    }
+
   rtx trace_reg = XEXP (trace.setcc.set_src (), 0);
 
   log_msg ("set of ccreg:\n");
@@ -1358,6 +1366,19 @@ sh_treg_combine::try_optimize_cbranch (rtx_insn *insn)
       log_return_void ("\nbecause it's volatile\n");
     }
 
+  // If the ccreg is inverted before cbranch try inverting the branch
+  // condition.
+  if (is_inverted_ccreg (trace.setcc.set_src ()))
+    {
+      if (!trace.can_invert_condition ())
+       log_return_void ("branch condition can't be inverted - aborting\n");
+
+      if (try_invert_branch_condition (trace))
+       delete_insn (trace.setcc.insn);
+
+      return;
+    }
+
   // Now that we have an insn which tests some reg and sets the condition
   // reg before the conditional branch, try to figure out how that tested
   // reg was formed, i.e. find all the insns that set the tested reg in