Fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83396#c28 on ia64 (PR bootstrap/83396)

Message ID 20171213142507.GK2353@tucnak
State New
Headers show
Series
  • Fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83396#c28 on ia64 (PR bootstrap/83396)
Related show

Commit Message

Jakub Jelinek Dec. 13, 2017, 2:25 p.m.
Hi!

I think there are 2 issues.  One is that the ia64 backend emits
the group barrier insns before BB_HEAD label, so it isn't part of a bb,
but has BLOCK_FOR_INSN of the following block, that looks invalid to me
and the ia64.c hunk ought to fix that, except that I don't have access to
ia64 anymore and so can't test it.  Andreas, could you try that?

Another thing is that if we because of this end up with insns outside of
basic blocks, the vt_initialize asserts will fire again.  Here, first of
all, IMNSHO we should assert that debug bind insns aren't outside of basic
blocks, the other patches and checking should ensure that (and if any slips
in, we want to fix that too rather than work-around).
Another is that while walking from get_first_insn to one before BB_HEAD (bb->next_bb),
we can encounter insns outside of bb not just before BB_HEAD (bb), but also
after BB_END (bb), both cases are outside of a bb and thus we can
expect BLOCK_FOR_INSN being NULL.

Bootstrapped/regtested on x86_64-linux, i686-linux, powerpc64le-linux,
regtest on powerpc64-linux pending.  Ok for trunk perhaps without the
ia64.c bits until that gets tested?

Or, in the PR there is a variant patch which just doesn't do the asserts and
doesn't have to track outside_bb.

2017-12-13  Jakub Jelinek  <jakub@redhat.com>

	PR bootstrap/83396
	* config/ia64/ia64.c (emit_insn_group_barriers): If emitting a group
	barrier before BB_HEAD, clear BLOCK_FOR_INSN on the group barrier.
	* var-tracking.c (vt_initialize): Don't assert blocks without
	BLOCK_FOR_INSN are only debug insns, instead assert they are outside of
	basic blocks.  Don't reset debug bind stmts outside of basic blocks,
	instead assert they aren't present outside of basic blocks.  Simplify.

	* gcc.dg/pr83396.c: New test.


	Jakub

Comments

Andreas Schwab Dec. 13, 2017, 3:59 p.m. | #1
On Dez 13 2017, Jakub Jelinek <jakub@redhat.com> wrote:

> I think there are 2 issues.  One is that the ia64 backend emits

> the group barrier insns before BB_HEAD label, so it isn't part of a bb,

> but has BLOCK_FOR_INSN of the following block, that looks invalid to me

> and the ia64.c hunk ought to fix that, except that I don't have access to

> ia64 anymore and so can't test it.  Andreas, could you try that?


That doesn't bootstrap, details in the PR.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

Patch

--- gcc/config/ia64/ia64.c.jj	2017-12-07 18:05:02.000000000 +0100
+++ gcc/config/ia64/ia64.c	2017-12-13 12:29:07.598684661 +0100
@@ -7098,7 +7098,13 @@  emit_insn_group_barriers (FILE *dump)
 		  if (dump)
 		    fprintf (dump, "Emitting stop before label %d\n",
 			     INSN_UID (last_label));
-		  emit_insn_before (gen_insn_group_barrier (GEN_INT (3)), last_label);
+		  insn
+		    = emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+					last_label);
+		  /* If we emit the group barrier before BB_HEAD, it should
+		     be outside of any bb.  */
+		  if (BB_HEAD (BLOCK_FOR_INSN (last_label)) == last_label)
+		    BLOCK_FOR_INSN (insn) = NULL;
 		  insn = last_label;
 
 		  init_insn_group_barriers ();
--- gcc/var-tracking.c.jj	2017-12-12 09:48:26.000000000 +0100
+++ gcc/var-tracking.c	2017-12-13 12:38:51.856261497 +0100
@@ -10157,28 +10157,28 @@  vt_initialize (void)
 	     insns that might be before it too.  Unfortunately,
 	     BB_HEADER and BB_FOOTER are not set while we run this
 	     pass.  */
-	  insn = get_first_insn (bb);
-	  for (rtx_insn *next;
-	       insn != BB_HEAD (bb->next_bb)
-		 ? next = NEXT_INSN (insn), true : false;
+	  rtx_insn *next;
+	  bool outside_bb = true;
+	  for (insn = get_first_insn (bb); insn != BB_HEAD (bb->next_bb);
 	       insn = next)
 	    {
+	      next = NEXT_INSN (insn);
+	      if (insn == BB_HEAD (bb))
+		outside_bb = false;
 	      if (INSN_P (insn))
 		{
 		  basic_block save_bb = BLOCK_FOR_INSN (insn);
 		  if (!BLOCK_FOR_INSN (insn))
 		    {
+		      gcc_assert (outside_bb);
 		      BLOCK_FOR_INSN (insn) = bb;
-		      gcc_assert (DEBUG_INSN_P (insn));
-		      /* Reset debug insns between basic blocks.
-			 Their location is not reliable, because they
-			 were probably not maintained up to date.  */
-		      if (DEBUG_BIND_INSN_P (insn))
-			INSN_VAR_LOCATION_LOC (insn)
-			  = gen_rtx_UNKNOWN_VAR_LOC ();
 		    }
 		  else
 		    gcc_assert (BLOCK_FOR_INSN (insn) == bb);
+		  /* Verify debug bind insns don't occur outside of bbs.  */
+		  gcc_assert (!DEBUG_BIND_INSN_P (insn) || !outside_bb);
+		  if (insn == BB_END (bb))
+		    outside_bb = true;
 
 		  if (!frame_pointer_needed)
 		    {
@@ -10255,6 +10255,8 @@  vt_initialize (void)
 		    }
 		  BLOCK_FOR_INSN (insn) = save_bb;
 		}
+	      else if (insn == BB_END (bb))
+		outside_bb = true;
 	    }
 	  gcc_assert (offset == VTI (bb)->out.stack_adjust);
 	}
--- gcc/testsuite/gcc.dg/pr83396.c.jj	2017-12-13 12:41:05.127570666 +0100
+++ gcc/testsuite/gcc.dg/pr83396.c	2017-12-13 12:40:30.020014539 +0100
@@ -0,0 +1,12 @@ 
+/* PR bootstrap/83396 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+int bar (int);
+int baz (int);
+
+int
+foo (int x)
+{
+  return bar (x) || baz (x) != 0;
+}