https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103359
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- Which means the CCP difference is that we're failing to propagate out copies when they have a useful value: Visiting statement: _25 = _24; which is likely CONSTANT Lattice value changed to CONSTANT 0x0 (0xf). Adding SSA edges to worklist. ssa_edge_worklist: adding SSA use in _7 = _25; Simulating statement: _7 = _25; Visiting statement: _7 = _25; which is likely CONSTANT Lattice value changed to CONSTANT 0x0 (0xf). Adding SSA edges to worklist. that's because the copy and constant lattice are unified and we cannot track both. And while forwprop will propagate out copies since it does that when it visits uses it confuses itself with this. Propagating them out immediately fixes this but the obvious use of replace_uses_by causes excessive folding and redundant work as well as out-of-order debug stmt handling. The following would fix the testcase. Note there's still the appearant EVRP regression compared to GCC 11. The single_use test was added with g:2fde61e3caf4c4660743e53497f52b65da1fe760 as a fix for PR66916. diff --git a/gcc/match.pd b/gcc/match.pd index f059b477f58..b32cc4a9368 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5221,8 +5221,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && ((POINTER_TYPE_P (TREE_TYPE (@00)) && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@00)))) || (POINTER_TYPE_P (TREE_TYPE (@10)) - && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@10)))))) - && single_use (@0)) + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@10))))))) (if (TYPE_PRECISION (TREE_TYPE (@00)) == TYPE_PRECISION (TREE_TYPE (@0)) && (TREE_CODE (@10) == INTEGER_CST || @1 != @10)