Following up https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01233.html and fixing the regressions this caused as soon as I removed the dispatch to fold_unary (and more regressions it would have caused if I managed to finish the idea to also remove the dispatches to fold_binary and fold_ternary...) the following patch makes CCP and VRP follow selected SSA edges again when gimple_fold_stmt_to_constant_1 dispatches to gimple_simplify.
The valueization for gimple_simplify of SSA propagator users may both valueize to anything (in particular constants) and it may signal to follow SSA edges if the destination will never be visited again by the propagator (thus its lattice value is stable). Esp. cutting out valueizing SSA names to constants is what caused the regressions. Note that this highlights the fact that overloading the valueization result with the signal to (not) follow SSA edges isn't the very best thing to do - for example we can't valueize to a SSA name (like for looking through SSA copies) but at the same time say that gimple_simplify shouldn't follow the edge to its definition. This shouldn't be a serious limitation for CCP and VRP which care about constants only - but it shows a defect in the gimple_simplify interface. I haven't yet concluded on a better one though - options go from adding a secondary return to the valueize hook to adding a second hook maybe with additionally adding a simple flag to turn off SSA edge following globally. Anyway - the following patch should fix the immediate regression and allows to go forward with removing GENERIC folding from both fold_stmt and gimple_fold_stmt_to_constant. Just not for this stage1 which will end too soon. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Thanks, Richard. 2014-11-14 Richard Biener <rguent...@suse.de> * gimple-fold.h (gimple_fold_stmt_to_constant_1): Add 2nd valueization hook defaulted to no_follow_ssa_edges. * gimple-fold.c (gimple_fold_stmt_to_constant_1): Pass 2nd valueization hook to gimple_simplify. * tree-ssa-ccp.c (valueize_op_1): New function to be used for gimple_simplify called via gimple_fold_stmt_to_constant_1. (ccp_fold): Adjust. * tree-vrp.c (vrp_valueize_1): New function to be used for gimple_simplify called via gimple_fold_stmt_to_constant_1. (vrp_visit_assignment_or_call): Adjust. Index: gcc/gimple-fold.c =================================================================== --- gcc/gimple-fold.c (svn+ssh://rgue...@gcc.gnu.org/svn/gcc/trunk/gcc/gimple-fold.c) (revision 217545) +++ gcc/gimple-fold.c (.../gcc/gimple-fold.c) (working copy) @@ -4467,7 +4411,8 @@ maybe_fold_or_comparisons (enum tree_cod to avoid the indirect function call overhead. */ tree -gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) +gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree), + tree (*gvalueize) (tree)) { code_helper rcode; tree ops[3] = {}; @@ -4475,7 +4420,7 @@ gimple_fold_stmt_to_constant_1 (gimple s edges if there are intermediate VARYING defs. For this reason do not follow SSA edges here even though SCCVN can technically just deal fine with that. */ - if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges) + if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize) && rcode.is_tree_code () && (TREE_CODE_LENGTH ((tree_code) rcode) == 0 || ((tree_code) rcode) == ADDR_EXPR) Index: gcc/gimple-fold.h =================================================================== --- gcc/gimple-fold.h (svn+ssh://rgue...@gcc.gnu.org/svn/gcc/trunk/gcc/gimple-fold.h) (revision 217545) +++ gcc/gimple-fold.h (.../gcc/gimple-fold.h) (working copy) @@ -36,7 +36,8 @@ extern bool arith_overflowed_p (enum tre const_tree); extern tree no_follow_ssa_edges (tree); extern tree follow_single_use_edges (tree); -extern tree gimple_fold_stmt_to_constant_1 (gimple, tree (*) (tree)); +extern tree gimple_fold_stmt_to_constant_1 (gimple, tree (*) (tree), + tree (*) (tree) = no_follow_ssa_edges); extern tree gimple_fold_stmt_to_constant (gimple, tree (*) (tree)); extern tree fold_const_aggregate_ref_1 (tree, tree (*) (tree)); extern tree fold_const_aggregate_ref (tree); Index: gcc/tree-ssa-ccp.c =================================================================== --- gcc/tree-ssa-ccp.c (svn+ssh://rgue...@gcc.gnu.org/svn/gcc/trunk/gcc/tree-ssa-ccp.c) (revision 217545) +++ gcc/tree-ssa-ccp.c (.../gcc/tree-ssa-ccp.c) (working copy) @@ -1126,6 +1126,27 @@ valueize_op (tree op) return op; } +/* Return the constant value for OP, but signal to not follow SSA + edges if the definition may be simulated again. */ + +static tree +valueize_op_1 (tree op) +{ + if (TREE_CODE (op) == SSA_NAME) + { + tree tem = get_constant_value (op); + if (tem) + return tem; + /* If the definition may be simulated again we cannot follow + this SSA edge as the SSA propagator does not necessarily + re-visit the use. */ + gimple def_stmt = SSA_NAME_DEF_STMT (op); + if (prop_simulate_again_p (def_stmt)) + return NULL_TREE; + } + return op; +} + /* CCP specific front-end to the non-destructive constant folding routines. @@ -1158,7 +1179,8 @@ ccp_fold (gimple stmt) case GIMPLE_ASSIGN: case GIMPLE_CALL: - return gimple_fold_stmt_to_constant_1 (stmt, valueize_op); + return gimple_fold_stmt_to_constant_1 (stmt, + valueize_op, valueize_op_1); default: gcc_unreachable (); Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c (svn+ssh://rgue...@gcc.gnu.org/svn/gcc/trunk/gcc/tree-vrp.c) (revision 217545) +++ gcc/tree-vrp.c (.../gcc/tree-vrp.c) (working copy) @@ -7025,6 +7025,27 @@ vrp_valueize (tree name) return name; } +/* Return the singleton value-range for NAME if that is a constant + but signal to not follow SSA edges. */ + +static inline tree +vrp_valueize_1 (tree name) +{ + if (TREE_CODE (name) == SSA_NAME) + { + value_range_t *vr = get_value_range (name); + if (range_int_cst_singleton_p (vr)) + return vr->min; + /* If the definition may be simulated again we cannot follow + this SSA edge as the SSA propagator does not necessarily + re-visit the use. */ + gimple def_stmt = SSA_NAME_DEF_STMT (name); + if (prop_simulate_again_p (def_stmt)) + return NULL_TREE; + } + return name; +} + /* Visit assignment STMT. If it produces an interesting range, record the SSA name in *OUTPUT_P. */ @@ -7048,8 +7069,9 @@ vrp_visit_assignment_or_call (gimple stm value_range_t new_vr = VR_INITIALIZER; /* Try folding the statement to a constant first. */ - tree tem = gimple_fold_stmt_to_constant (stmt, vrp_valueize); - if (tem) + tree tem = gimple_fold_stmt_to_constant_1 (stmt, vrp_valueize, + vrp_valueize_1); + if (tem && is_gimple_min_invariant (tem)) set_value_range_to_value (&new_vr, tem, NULL); /* Then dispatch to value-range extracting functions. */ else if (code == GIMPLE_CALL)