diff mbox

Fix PR71433

Message ID alpine.LSU.2.20.1701161034340.14052@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Jan. 16, 2017, 9:42 a.m. UTC
The following makes VRP deal better with the situation where the
same assertion is to be inserted on all predecessors of a BB.
That avoids the spurious array-bound warning (and enables some
optimization) when jump-threading f**ed up the CFG in such redundant
way.

(the fully "correct" way to deal with this VRP shortcoming is
to make assert insertion also insert PHIs for merges as there are
cases - such like this - where the merged range is useful;  but
as comments say PHI insertion is expensive and via update-ssa
it is also quite excessive)

Bootstrap / regtest running on x86_64-unknown-linux-gnu.

Richard.

2017-01-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/71433
	* tree-vrp.c (register_new_assert_for): Merge same asserts
	on all incoming edges.
	(process_assert_insertions_for): Handle insertions at the
	beginning of BBs.

	* gcc.dg/Warray-bounds-20.c: New testcase.
diff mbox

Patch

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 244484)
+++ gcc/tree-vrp.c	(working copy)
@@ -5032,6 +5032,17 @@  register_new_assert_for (tree name, tree
 	      loc->si = si;
 	      return;
 	    }
+	  /* If we have the same assertion on all incoming edges of a BB
+	     instead insert it at the beginning of it.  */
+	  if (e && loc->e
+	      && dest_bb == loc->e->dest
+	      && EDGE_COUNT (dest_bb->preds) == 2)
+	    {
+	      loc->bb = dest_bb;
+	      loc->e = NULL;
+	      loc->si = gsi_none ();
+	      return;
+	    }
 	}
 
       /* Update the last node of the list and move to the next one.  */
@@ -6429,6 +6440,15 @@  process_assert_insertions_for (tree name
       return true;
     }
 
+  /* If the stmt iterator points at the end then this is an insertion
+     at the beginning of a block.  */
+  if (gsi_end_p (loc->si))
+    {
+      gimple_stmt_iterator si = gsi_after_labels (loc->bb);
+      gsi_insert_before (&si, assert_stmt, GSI_SAME_STMT);
+      return false;
+
+    }
   /* Otherwise, we can insert right after LOC->SI iff the
      statement must not be the last statement in the block.  */
   stmt = gsi_stmt (loc->si);
Index: gcc/testsuite/gcc.dg/Warray-bounds-20.c
===================================================================
--- gcc/testsuite/gcc.dg/Warray-bounds-20.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/Warray-bounds-20.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -Warray-bounds" } */
+
+int t[1];
+int fct (int r, long e)
+{
+  int d = 0;
+  if (r == 4)
+    r = 1;
+  if (e < -52)
+    d = r == 0 ? 1 : 2;
+  else
+    {
+      int i, n = 53;
+      if (__builtin_expect (e < 0, 0))
+	n += e;
+      for (i = 1 ; i < n / 64 + 1 ; i++)
+	t[i] = 0; /* { dg-bogus "array bounds" } */
+    }
+  return d;
+}