re PR tree-optimization/55936 (Missed VRP optimization)

2016-03-03  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/55936
	* tree-vrp.c (compare_name_with_value): Add use_equiv_p
	parameter and guard unsafe equivalence use.
	(vrp_evaluate_conditional_warnv_with_ops): Always use
	safe equivalences but not via the quadratic compare_names
	helper.

	* gcc.dg/tree-ssa/vrp06.c: Remove XFAIL.

From-SVN: r233928
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f149eba..97d3bb6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2016-03-03  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/55936
+	* tree-vrp.c (compare_name_with_value): Add use_equiv_p
+	parameter and guard unsafe equivalence use.
+	(vrp_evaluate_conditional_warnv_with_ops): Always use
+	safe equivalences but not via the quadratic compare_names
+	helper.
+
 2016-03-03  Michael Collison  <michael.collison@linaro.org>
 
 	PR target/70014
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 39fdb64..1c6e170 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-03-03  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/55936
+	* gcc.dg/tree-ssa/vrp06.c: Remove XFAIL.
+
 2016-03-02  Jeff Law  <law@redhat.com>
 
 	PR rtl-optimization/69942
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c
index 46bbef1..cdad534 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c
@@ -30,4 +30,4 @@
 
 /* { dg-final { scan-tree-dump-times "Folding predicate i_\[0-9\]+.*0 to 0" 1 "vrp1" } } */
 /* { dg-final { scan-tree-dump-times "Folding predicate j_\[0-9\]+.*0 to 1" 1 "vrp1" } } */
-/* { dg-final { scan-tree-dump-times "Folding predicate i_\[0-9]+.*j_\[0-9\]+.* to 0" 1 "vrp1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Folding predicate i_\[0-9]+.*j_\[0-9\]+.* to 0" 1 "vrp1" } } */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index a11635d..b5654c5 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -7161,7 +7161,7 @@
 
 static tree
 compare_name_with_value (enum tree_code comp, tree var, tree val,
-			 bool *strict_overflow_p)
+			 bool *strict_overflow_p, bool use_equiv_p)
 {
   bitmap_iterator bi;
   unsigned i;
@@ -7196,6 +7196,11 @@
 
   EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
     {
+      if (! use_equiv_p
+	  && ! SSA_NAME_IS_DEFAULT_DEF (ssa_name (i))
+	  && prop_simulate_again_p (SSA_NAME_DEF_STMT (ssa_name (i))))
+	continue;
+
       equiv_vr = get_vr_for_comparison (i);
       sop = false;
       t = compare_range_with_value (comp, &equiv_vr, val, &sop);
@@ -7381,24 +7386,21 @@
       && !POINTER_TYPE_P (TREE_TYPE (op0)))
     return NULL_TREE;
 
-  if (use_equiv_p)
-    {
-      if (only_ranges
-          && (ret = vrp_evaluate_conditional_warnv_with_ops_using_ranges
-	              (code, op0, op1, strict_overflow_p)))
-	return ret;
-      *only_ranges = false;
-      if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
-	return compare_names (code, op0, op1, strict_overflow_p);
-      else if (TREE_CODE (op0) == SSA_NAME)
-	return compare_name_with_value (code, op0, op1, strict_overflow_p);
-      else if (TREE_CODE (op1) == SSA_NAME)
-	return (compare_name_with_value
-		(swap_tree_comparison (code), op1, op0, strict_overflow_p));
-    }
-  else
-    return vrp_evaluate_conditional_warnv_with_ops_using_ranges (code, op0, op1,
-								 strict_overflow_p);
+  if ((ret = vrp_evaluate_conditional_warnv_with_ops_using_ranges
+	       (code, op0, op1, strict_overflow_p)))
+    return ret;
+  if (only_ranges)
+    *only_ranges = false;
+  /* Do not use compare_names during propagation, it's quadratic.  */
+  if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME
+      && use_equiv_p)
+    return compare_names (code, op0, op1, strict_overflow_p);
+  else if (TREE_CODE (op0) == SSA_NAME)
+    return compare_name_with_value (code, op0, op1,
+				    strict_overflow_p, use_equiv_p);
+  else if (TREE_CODE (op1) == SSA_NAME)
+    return compare_name_with_value (swap_tree_comparison (code), op1, op0,
+				    strict_overflow_p, use_equiv_p);
   return NULL_TREE;
 }