https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111622
--- Comment #6 from Andrew Macleod <amacleod at redhat dot com> --- Interesting. The "fix" turns out to be: commit 9ea74d235c7e7816b996a17c61288f02ef767985 Author: Richard Biener <rguent...@suse.de> Date: Thu Sep 14 09:31:23 2023 +0200 tree-optimization/111294 - better DCE after forwprop The following adds more aggressive DCE to forwprop to clean up dead stmts when folding a stmt leaves some operands unused. The patch uses simple_dce_from_worklist for this purpose, queueing original operands before substitution and folding, but only if we folded the stmt. This removes one dead stmt biasing threading costs in a later pass but it doesn't resolve the optimization issue in the PR yet. Which implies something pathological was triggering in VRP, so I dug a little deeper... It seems to be a massive number of partial equivalencies generated by sequences like: _5 = (unsigned int) _1; _10 = (unsigned int) _1; _15 = (unsigned int) _1; _20 = (unsigned int) _1; _25 = (unsigned int) _1; <...> for a couple of hundred statements. these are all then members of a partial equivalence set, and we end up doing obscene amounts of pointless looping and recomputing of ranges of things in the set when say _1 may change. The intent of partial equivalence is to allow us to reflect known subranges thru casts, but not to build up large groups like in an equivalence. There should be a limit to the size. We start to lose most of the usefulness when the grouping gets too large.