I am testing the following patch that avoids putting non-final copies into the CCP lattice which eventually results in released SSA names in the IL.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2017-03-28 Richard Biener <[email protected]> PR tree-optimization/78644 * tree-ssa-ccp.c (evaluate_stmt): When we may not use the value of a simplification result we may not use it at all. * gcc.dg/pr78644-1.c: New testcase. * gcc.dg/pr78644-2.c: Likewise. Index: gcc/tree-ssa-ccp.c =================================================================== *** gcc/tree-ssa-ccp.c (revision 246527) --- gcc/tree-ssa-ccp.c (working copy) *************** evaluate_stmt (gimple *stmt) *** 1749,1766 **** fold_defer_overflow_warnings (); simplified = ccp_fold (stmt); if (simplified ! && TREE_CODE (simplified) == SSA_NAME /* We may not use values of something that may be simulated again, see valueize_op_1. */ ! && (SSA_NAME_IS_DEFAULT_DEF (simplified) ! || ! prop_simulate_again_p (SSA_NAME_DEF_STMT (simplified)))) ! { ! ccp_prop_value_t *val = get_value (simplified); ! if (val && val->lattice_val != VARYING) { ! fold_undefer_overflow_warnings (true, stmt, 0); ! return *val; } } is_constant = simplified && is_gimple_min_invariant (simplified); fold_undefer_overflow_warnings (is_constant, stmt, 0); --- 1749,1772 ---- fold_defer_overflow_warnings (); simplified = ccp_fold (stmt); if (simplified ! && TREE_CODE (simplified) == SSA_NAME) ! { /* We may not use values of something that may be simulated again, see valueize_op_1. */ ! if (SSA_NAME_IS_DEFAULT_DEF (simplified) ! || ! prop_simulate_again_p (SSA_NAME_DEF_STMT (simplified))) { ! ccp_prop_value_t *val = get_value (simplified); ! if (val && val->lattice_val != VARYING) ! { ! fold_undefer_overflow_warnings (true, stmt, 0); ! return *val; ! } } + else + /* We may also not place a non-valueized copy in the lattice + as that might become stale if we never re-visit this stmt. */ + simplified = NULL_TREE; } is_constant = simplified && is_gimple_min_invariant (simplified); fold_undefer_overflow_warnings (is_constant, stmt, 0); Index: gcc/testsuite/gcc.dg/pr78644-1.c =================================================================== *** gcc/testsuite/gcc.dg/pr78644-1.c (nonexistent) --- gcc/testsuite/gcc.dg/pr78644-1.c (working copy) *************** *** 0 **** --- 1,21 ---- + /* { dg-do compile { target int128 } } */ + /* { dg-options "-Og -fipa-cp -w -Wno-psabi" } */ + + typedef unsigned __int128 u128; + typedef unsigned __int128 V __attribute__ ((vector_size (64))); + + V x4; + + static V + bar (u128 x2, u128 x3) + { + while (x4[0]--) + x2 /= x3 >>= 1; + return x2 + x3 + x4; + } + + void + foo (void) + { + bar (0, 0); + } Index: gcc/testsuite/gcc.dg/pr78644-2.c =================================================================== *** gcc/testsuite/gcc.dg/pr78644-2.c (nonexistent) --- gcc/testsuite/gcc.dg/pr78644-2.c (working copy) *************** *** 0 **** --- 1,20 ---- + /* { dg-do compile { target int128 } } */ + /* { dg-options "-Og -finline-functions-called-once -w -Wno-psabi" } */ + + typedef unsigned V __attribute__ ((vector_size (64))); + typedef unsigned __int128 U __attribute__ ((vector_size (64))); + + U + bar4 (U u0, U u1) + { + if (u1[0]) + u1 <<= 1; + return u0 + u1; + } + + V + foo (U u, V v) + { + v |= (unsigned)bar4(u, (U){})[0]; + return v; + }
