This fixes EVRP to also set range-info/nonnull for PHI results as well as not doing useless work in setting such info for SSA defs we'll propagate out later.
Bootstrapped and tested on x86_64-unknown-linux-gnu, installed. Richard. 2017-01-11 Richard Biener <rguent...@suse.de> * tree-vrp.c (evrp_dom_walker::before_dom_children): Also set range/nonnull info for PHI results. Do not set it on stmts marked for removal. * gcc.dg/tree-ssa/pr61743-1.c: Adjust. Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c (revision 244259) +++ gcc/tree-vrp.c (working copy) @@ -10862,7 +11029,29 @@ evrp_dom_walker::before_dom_children (ba /* Mark PHIs whose lhs we fully propagate for removal. */ tree val = op_with_constant_singleton_value_range (lhs); if (val && may_propagate_copy (lhs, val)) - stmts_to_remove.safe_push (phi); + { + stmts_to_remove.safe_push (phi); + continue; + } + + /* Set the SSA with the value range. */ + if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))) + { + if ((vr_result.type == VR_RANGE + || vr_result.type == VR_ANTI_RANGE) + && (TREE_CODE (vr_result.min) == INTEGER_CST) + && (TREE_CODE (vr_result.max) == INTEGER_CST)) + set_range_info (lhs, + vr_result.type, vr_result.min, vr_result.max); + } + else if (POINTER_TYPE_P (TREE_TYPE (lhs)) + && ((vr_result.type == VR_RANGE + && range_includes_zero_p (vr_result.min, + vr_result.max) == 0) + || (vr_result.type == VR_ANTI_RANGE + && range_includes_zero_p (vr_result.min, + vr_result.max) == 1))) + set_ptr_nonnull (lhs); } edge taken_edge = NULL; @@ -10908,6 +11097,17 @@ evrp_dom_walker::before_dom_children (ba update_value_range (output, &vr); vr = *get_value_range (output); + /* Mark stmts whose output we fully propagate for removal. */ + tree val; + if ((val = op_with_constant_singleton_value_range (output)) + && may_propagate_copy (output, val) + && !stmt_could_throw_p (stmt) + && !gimple_has_side_effects (stmt)) + { + stmts_to_remove.safe_push (stmt); + continue; + } + /* Set the SSA with the value range. */ if (INTEGRAL_TYPE_P (TREE_TYPE (output))) { @@ -10925,17 +11125,6 @@ evrp_dom_walker::before_dom_children (ba && range_includes_zero_p (vr.min, vr.max) == 1))) set_ptr_nonnull (output); - - /* Mark stmts whose output we fully propagate for removal. */ - tree val; - if ((val = op_with_constant_singleton_value_range (output)) - && may_propagate_copy (output, val) - && !stmt_could_throw_p (stmt) - && !gimple_has_side_effects (stmt)) - { - stmts_to_remove.safe_push (stmt); - continue; - } } else set_defs_to_varying (stmt); Index: gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c (revision 244303) +++ gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -funroll-loops -fno-tree-vectorize -fdump-tree-cunroll-details -fno-peel-loops" } */ +/* { dg-options "-O3 -funroll-loops -fno-tree-vectorize -fdump-tree-cunroll-details -fdump-tree-cunrolli-details -fno-peel-loops" } */ #define N 8 #define M 14 @@ -48,5 +48,5 @@ int foo1 (e_u8 a[4][N], int b1, int b2, return 0; } -/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 2 "cunroll" } } */ -/* { dg-final { scan-tree-dump-times "loop with 8 iterations completely unrolled" 2 "cunroll" } } */ +/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 8 "cunroll" } } */ +/* { dg-final { scan-tree-dump-times "loop with 9 iterations completely unrolled" 2 "cunrolli" } } */