https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124643
--- Comment #13 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The trunk branch has been updated by Richard Sandiford <[email protected]>: https://gcc.gnu.org/g:68920b1f14dc6b27428a92d9c0d3c8237bb361f9 commit r16-8754-g68920b1f14dc6b27428a92d9c0d3c8237bb361f9 Author: Richard Sandiford <[email protected]> Date: Sun Apr 19 20:27:21 2026 +0100 cse: Validate subreg replacements [PR124643] The PR is about an ICE on sh caused by an "invalid" subreg. cse replaced a pseudo register with the hard T register within: (zero_extend:SI (subreg:QI (reg:SI pseudo) 3)) Since this is a register-for-register replacement, cse just relied on recog to reject anything that wasn't valid. However, if validate_subreg had been asked, it would have said that: (subreg:QI (reg:SI T) 3) is not valid. This means that even simplify_gen_subreg would have refused to generate it. In that sense, cse should not even be trying to match this replacement. It's not recog's job to reject all invalid rtl. recog is just supposed to say whether the machine supports a given piece of valid rtl. In this particular case, the sh port does specifically match: (zero_extend:SI (subreg:QI (reg:SI T) 3)) even though, by forbidding T from having QImode, the port also effectively forbids the subreg. See the discussion in the PR trail about that. But I think the point still stands that cse should verify the subregs that it creates. It should also try to simplify them down to hard registers where possible. I suppose a more complete fix would be to rewrite canon_reg to use a helper that recursively replaces and simplifies, but that seems somewhat dangerous at this stage. The scope for non-subreg simplification should also be pretty limited in practice. gcc/ PR rtl-optimization/124643 * cse.cc (canon_reg): Handle and canonicalize subregs. gcc/testsuite/ PR rtl-optimization/124643 * gcc.c-torture/compile/pr124643.c: New test.
