The following fixes a long-standing VRP regression now that we can
safely use some equivalences during propagation.

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

Richard.

2016-03-03  Richard Biener  <rguent...@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.

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c      (revision 233902)
+++ gcc/tree-vrp.c      (working copy)
@@ -7161,7 +7161,7 @@ get_vr_for_comparison (int i)
 
 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 @@ compare_name_with_value (enum tree_code
 
   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 @@ vrp_evaluate_conditional_warnv_with_ops
       && !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;
 }
 
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp06.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/vrp06.c       (revision 233901)
+++ gcc/testsuite/gcc.dg/tree-ssa/vrp06.c       (working copy)
@@ -30,4 +30,4 @@ foo (int i, int j, int a)
 
 /* { 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" } } */

Reply via email to