The following patch makes sure that CCP when it computes a lattice value to UNDEFINED ends up replacing uses with default defs (and thus removes such UNDEFINED producing defs). This optimizes the testcase below to
<bb 2>: return _6(D); in the first CCP. Note this patch isn't mainly for the optimization it does but for making it easier to discover cases where CCP gets UNDEFINED wrong (similar to VRP2 re-using the range-info that is still live on SSA names - that's to catch bogus range-info). If the experiment works out (read: bootstrap / test completes successfully) I'm going to enhance VRP and will also look at how value-numbering could do a similar job. It might also help removing unreachable (undefined) code earlier of course. Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2015-11-04 Richard Biener <rguent...@suse.de> * tree-ssa-ccp.c: Include tree-dfa.h. (get_constant_value_for_substitution): New function returning default defs for UNDEFINED. (ccp_finalize): Use get_constant_value_for_substitution for substitute_and_fold. Index: gcc/tree-ssa-ccp.c =================================================================== *** gcc/tree-ssa-ccp.c (revision 229734) --- gcc/tree-ssa-ccp.c (working copy) *************** along with GCC; see the file COPYING3. *** 139,144 **** --- 139,145 ---- #include "params.h" #include "builtins.h" #include "tree-chkp.h" + #include "tree-dfa.h" /* Possible lattice values. */ *************** get_constant_value (tree var) *** 365,370 **** --- 366,411 ---- return NULL_TREE; } + /* Return the constant tree value associated with VAR. */ + + static inline tree + get_constant_value_for_substitution (tree var) + { + ccp_prop_value_t *val; + if (TREE_CODE (var) != SSA_NAME) + { + if (is_gimple_min_invariant (var)) + return var; + return NULL_TREE; + } + val = get_value (var); + if (!val) + return NULL_TREE; + if (val->lattice_val == UNDEFINED) + { + /* At substitution time replace UNDEFINED values with a default + def. We delay creating of the default-def until we actually + require substitution. */ + tree def; + if (SSA_NAME_VAR (var) + && TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL) + def = get_or_create_ssa_default_def (cfun, SSA_NAME_VAR (var)); + else + def = get_or_create_ssa_default_def (cfun, + create_tmp_reg (TREE_TYPE (var))); + /* Adjust the lattice. */ + val->lattice_val = CONSTANT; + val->mask = -1; + val->value = def; + return def; + } + else if (val->lattice_val == CONSTANT + && (TREE_CODE (val->value) != INTEGER_CST + || val->mask == 0)) + return val->value; + return NULL_TREE; + } + /* Sets the value associated with VAR to VARYING. */ static inline void *************** ccp_finalize (void) *** 942,948 **** } /* Perform substitutions based on the known constant values. */ ! something_changed = substitute_and_fold (get_constant_value, ccp_fold_stmt, true); free (const_val); --- 983,989 ---- } /* Perform substitutions based on the known constant values. */ ! something_changed = substitute_and_fold (get_constant_value_for_substitution, ccp_fold_stmt, true); free (const_val); Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-40.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-40.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-40.c (working copy) *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-ccp1" } */ + + int foo (void) + { + int b; + int a = b + 1; + return a; + } + + /* b + 1 results in an undefined value and CCP should simply replace the + return stmt to return a default def so the addition can be DCEed. */ + + /* { dg-final { scan-tree-dump "return \[^_\]*_\[0-9\]\+\\(D\\);" "ccp1" } } */