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" } } */