This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Don't consider zero succs empty blocks as forwarders (PR rtl-optimization/71916)


Hi!

Normally empty blocks without successors (result of __builtin_unreachable ()
somewhere in RTL) aren't considered as forwarder_block_p, because they
don't satisfy single_succ_p.  But e.g. during cross-jumping fake edges to
exit are added and then they suddenly satisfy this predicate, which confuses
the cross-jumping among other things (normally cross-jumping attempts to be
careful with no real successor blocks if there isn't a noreturn call
with REG_ARGS_SIZE note, but if it believes those are forwarders, it doesn't
check hard).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/6.2?

2016-07-19  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/71916
	* cfgrtl.c (contains_no_active_insn_p): Return false also for
	bb which have a single succ fake edge.

	* gcc.c-torture/compile/pr71916.c: New test.

--- gcc/cfgrtl.c.jj	2016-05-11 15:15:49.000000000 +0200
+++ gcc/cfgrtl.c	2016-07-19 16:38:20.362303955 +0200
@@ -574,8 +574,10 @@ contains_no_active_insn_p (const_basic_b
 {
   rtx_insn *insn;
 
-  if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
-      || !single_succ_p (bb))
+  if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
+      || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
+      || !single_succ_p (bb)
+      || (single_succ_edge (bb)->flags & EDGE_FAKE) != 0)
     return false;
 
   for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
--- gcc/testsuite/gcc.c-torture/compile/pr71916.c.jj	2016-07-19 16:43:37.610371787 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr71916.c	2016-07-19 16:43:20.000000000 +0200
@@ -0,0 +1,36 @@
+/* PR rtl-optimization/71916 */
+
+int a, b, c, d, f, g;
+short h;
+
+short
+foo (short p1)
+{
+  return a >= 2 || p1 > 7 >> a ? p1 : p1 << a;
+}
+
+void
+bar (void)
+{
+  for (;;)
+    {
+      int i, j[3];
+      h = b >= 2 ? d : d >> b;
+      if (foo (f > h ^ c))
+	{
+	  d = 0;
+	  while (f <= 2)
+	    {
+	      char k[2];
+	      for (;;)
+		k[i++] = 7;
+	    }
+	}
+      else
+	for (;;)
+	  g = j[2];
+      if (g)
+	for (;;)
+	  ;
+    }
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]