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] Fix up maybe_cleanup_end_of_block (PR middle-end/46499)


Hi!

On the attached testcases jumpif* emits:
   (jump_insn 8 7 9 (set (pc)
           (label_ref 0)) pr46499-1.c:26 -1
        (nil))

   (barrier 9 8 10)

   (jump_insn 10 9 11 (set (pc)
           (label_ref 0)) pr46499-1.c:26 -1
        (nil))

   (barrier 11 10 0)
where the label_ref in both cases is the non-fallthru label.  This is
because ssa_name & ssa_name is the condition and both ssa_name's
are found using TER to be 0 (and the -fno-* options ensure it is not
optimized earlier).
maybe_cleanup_end_of_block is called to find out when the sequence ends
with an unconditional jump to the non-fallthru label, with no fallthru
code_label afterwards, which means all the sequence does (assuming no
side-effects in it but GIMPLE should ensure that) is that unconditional
jump and attempts to remove any other jumps from the sequence.
Apparently it was expecting just conditional jumps to the non-fallthru
label, for unconditional ones as in this example the following
barrier needs to be removed too, otherwise we end up with a barrier
in a middle of a bb and we either ICE on it, or miscompile it.

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

2010-11-22  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/46499
	* cfgexpand.c (maybe_cleanup_end_of_block): Remove also BARRIERs
	following unconditional jumps.

	* gcc.dg/pr46499-1.c: New test.
	* gcc.dg/pr46499-2.c: New test.

--- gcc/cfgexpand.c.jj	2010-11-10 13:14:53.000000000 +0100
+++ gcc/cfgexpand.c	2010-11-22 14:45:49.000000000 +0100
@@ -1694,7 +1694,14 @@ maybe_cleanup_end_of_block (edge e, rtx 
 	{
 	  insn = PREV_INSN (insn);
 	  if (JUMP_P (NEXT_INSN (insn)))
-	    delete_insn (NEXT_INSN (insn));
+	    {
+	      if (!any_condjump_p (insn))
+		{
+		  gcc_assert (BARRIER_P (NEXT_INSN (NEXT_INSN (insn))));
+		  delete_insn (NEXT_INSN (NEXT_INSN (insn)));
+		}
+	      delete_insn (NEXT_INSN (insn));
+	    }
 	}
     }
 }
--- gcc/testsuite/gcc.dg/pr46499-1.c.jj	2010-11-22 14:59:48.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr46499-1.c	2010-11-22 14:59:11.000000000 +0100
@@ -0,0 +1,31 @@
+/* PR middle-end/46499 */
+/* { dg-do run } */
+/* { dg-options "-O -fno-omit-frame-pointer -fno-tree-ccp -fno-tree-dominator-opts -finline-small-functions" } */
+
+extern void abort (void);
+
+int count = 0;
+
+int
+foo (void)
+{
+  count++;
+  return 0;
+}
+
+int
+bar (void)
+{
+  count++;
+  return 0;
+}
+
+int
+main ()
+{
+  if ((foo () == 1) & (bar () == 1))
+    abort ();
+  if (count != 2)
+    abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.dg/pr46499-2.c.jj	2010-11-22 14:59:53.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr46499-2.c	2010-11-22 14:55:37.000000000 +0100
@@ -0,0 +1,19 @@
+/* PR middle-end/46499 */
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-ccp -fno-tree-dominator-opts" } */
+
+extern void abort (void);
+
+static inline int
+foo (void)
+{
+  return 0;
+}
+
+int
+main ()
+{
+  if ((foo () == 1) & (foo () == 1))
+    abort ();
+  return 0;
+}

	Jakub


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