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 some EVRP stupidness


At some point we decided to not simply intersect all ranges we get
via register_edge_assert_for.  Instead we simply register them
in-order.  That causes things like replacing [64, +INF] with ~[0, 0].

The following patch avoids replacing a range with a larger one
as obvious improvement.

Compared to assert_expr based VRP we lack the ability to put down
actual assert_exprs and thus multiple SSA names with ranges we
could link via equivalences.  In the end we need sth similar,
for example by keeping a stack of active ranges for each SSA name.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2018-10-18  Richard Biener  <rguenther@suse.de>

	* gimple-ssa-evrp-analyze.c
	(evrp_range_analyzer::record_ranges_from_incoming_edge): Be
	smarter about what ranges to use.
	* tree-vrp.c (add_assert_info): Dump here.
	(register_edge_assert_for_2): Instead of here at multiple but
	not all places.

	* gcc.dg/tree-ssa/evrp12.c: New testcase.
	* gcc.dg/predict-6.c: Adjust.
	* gcc.dg/tree-ssa/vrp33.c: Disable EVRP.
	* gcc.dg/tree-ssa/vrp02.c: Likewise.
	* gcc.dg/tree-ssa/cunroll-9.c: Likewise.

diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index e9afa80e191..0748a53cdb8 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -206,6 +206,17 @@ evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
 	     ordering issues that can lead to worse ranges.  */
 	  for (unsigned i = 0; i < vrs.length (); ++i)
 	    {
+	      /* But make sure we do not weaken ranges like when
+	         getting first [64, +INF] and then ~[0, 0] from
+		 conditions like (s & 0x3cc0) == 0).  */
+	      value_range *old_vr = get_value_range (vrs[i].first);
+	      value_range tem = *old_vr;
+	      tem.equiv = NULL;
+	      vrp_intersect_ranges (&tem, vrs[i].second);
+	      if (tem.type == old_vr->type
+		  && tem.min == old_vr->min
+		  && tem.max == old_vr->max)
+		continue;
 	      push_value_range (vrs[i].first, vrs[i].second);
 	      if (is_fallthru
 		  && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt))
diff --git a/gcc/testsuite/gcc.dg/predict-6.c b/gcc/testsuite/gcc.dg/predict-6.c
index 5d6fbf158f2..08ce5cdb81d 100644
--- a/gcc/testsuite/gcc.dg/predict-6.c
+++ b/gcc/testsuite/gcc.dg/predict-6.c
@@ -10,9 +10,9 @@ void foo (int base, int bound)
   int i, ret = 0;
   for (i = base; i <= bound; i++)
     {
-      if (i < base)
+      if (i <= base)
 	global += bar (i);
-      if (i < base + 1)
+      if (i < base + 2)
 	global += bar (i);
       if (i <= base + 3)
 	global += bar (i);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-9.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-9.c
index 0e4407dcbd7..886dc147ad1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-9.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-9.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-cunrolli-details" } */
+/* { dg-options "-O2 -fdump-tree-cunrolli-details -fdisable-tree-evrp" } */
 void abort (void);
 int q (void);
 int a[10];
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp12.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp12.c
new file mode 100644
index 00000000000..b3906c23465
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp12.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void link_error ();
+
+void
+f3 (unsigned int s)
+{
+  if ((s & 0x3cc0) == 0)
+    {
+      if (s >= -15552U)
+	link_error ();
+    }
+  else
+    {
+      if (s <= 0x3f)
+	link_error ();
+    }
+}
+
+/* { dg-final { scan-tree-dump-not "link_error" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c
index 8d14feadb6a..4be538f5944 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1 -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fdump-tree-vrp1 -fdelete-null-pointer-checks -fdisable-tree-evrp" } */
 
 struct A
 {
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
index 75fefa49925..f1d3863943e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-fre" } */
+/* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-fre -fdisable-tree-evrp" } */
 
 /* This is from PR14052.  */
 
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index cbc2ea2f26b..6f5ec43670e 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -2133,6 +2133,17 @@ add_assert_info (vec<assert_info> &asserts,
   info.val = val;
   info.expr = expr;
   asserts.safe_push (info);
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "Adding assert for ");
+      print_generic_expr (dump_file, name);
+      fprintf (dump_file, " from ");
+      print_generic_expr (dump_file, expr);
+      fprintf (dump_file, " %s ", op_symbol_code (comp_code));
+      print_generic_expr (dump_file, val);
+      fprintf (dump_file, "\n");
+    }
 }
 
 /* If NAME doesn't have an ASSERT_EXPR registered for asserting
@@ -2532,16 +2543,6 @@ register_edge_assert_for_2 (tree name, edge e,
 	  tmp = build1 (NOP_EXPR, TREE_TYPE (name), name3);
 	  if (cst2 != NULL_TREE)
 	    tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
-
-	  if (dump_file)
-	    {
-	      fprintf (dump_file, "Adding assert for ");
-	      print_generic_expr (dump_file, name3);
-	      fprintf (dump_file, " from ");
-	      print_generic_expr (dump_file, tmp);
-	      fprintf (dump_file, "\n");
-	    }
-
 	  add_assert_info (asserts, name3, tmp, comp_code, val);
 	}
 
@@ -2559,16 +2560,6 @@ register_edge_assert_for_2 (tree name, edge e,
 	    tmp = build1 (NOP_EXPR, TREE_TYPE (name), tmp);
 	  if (cst2 != NULL_TREE)
 	    tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
-
-	  if (dump_file)
-	    {
-	      fprintf (dump_file, "Adding assert for ");
-	      print_generic_expr (dump_file, name2);
-	      fprintf (dump_file, " from ");
-	      print_generic_expr (dump_file, tmp);
-	      fprintf (dump_file, "\n");
-	    }
-
 	  add_assert_info (asserts, name2, tmp, comp_code, val);
 	}
     }
@@ -2691,16 +2682,6 @@ register_edge_assert_for_2 (tree name, edge e,
 		  cst = fold_build2 (MINUS_EXPR, TREE_TYPE (name2), cst,
 				     build_int_cst (TREE_TYPE (name2), 1));
 		}
-
-	      if (dump_file)
-		{
-		  fprintf (dump_file, "Adding assert for ");
-		  print_generic_expr (dump_file, name2);
-		  fprintf (dump_file, " from ");
-		  print_generic_expr (dump_file, tmp);
-		  fprintf (dump_file, "\n");
-		}
-
 	      add_assert_info (asserts, name2, tmp, new_comp_code, cst);
 	    }
 	}
@@ -2765,18 +2746,7 @@ register_edge_assert_for_2 (tree name, edge e,
 	    }
 
 	  if (new_val)
-	    {
-	      if (dump_file)
-		{
-		  fprintf (dump_file, "Adding assert for ");
-		  print_generic_expr (dump_file, name2);
-		  fprintf (dump_file, " from ");
-		  print_generic_expr (dump_file, tmp);
-		  fprintf (dump_file, "\n");
-		}
-
-	      add_assert_info (asserts, name2, tmp, new_comp_code, new_val);
-	    }
+	    add_assert_info (asserts, name2, tmp, new_comp_code, new_val);
 	}
 
       /* Add asserts for NAME cmp CST and NAME being defined as
@@ -3004,16 +2974,6 @@ register_edge_assert_for_2 (tree name, edge e,
 			maxv2 = maxv - minv;
 		      }
 		    new_val = wide_int_to_tree (type, maxv2);
-
-		    if (dump_file)
-		      {
-			fprintf (dump_file, "Adding assert for ");
-			print_generic_expr (dump_file, names[i]);
-			fprintf (dump_file, " from ");
-			print_generic_expr (dump_file, tmp);
-			fprintf (dump_file, "\n");
-		      }
-
 		    add_assert_info (asserts, names[i], tmp, LE_EXPR, new_val);
 		  }
 	    }


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