https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117064
Bug ID: 117064 Summary: target hook HARD_REGNO_RENAME_OK is too limiting Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: matz at gcc dot gnu.org Target Milestone: --- This came up during fixing PR116650. Essentially it's possible for regrename choosing a new register N for a chain (having old register O) where N and O have unequal number of hard-regs to represent all modes occuring in the chain. In the above bug that lead to checking freeness of new candidates only in terms of the old register. But even with that fixed the target hook HARD_REGNO_RENAME_OK has an incomplete interface only taking hardreg numbers. Right now it's used in regrename.cc:check_new_reg_p like so: for (i = nregs - 1; i >= 0; --) ... || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)) I.e. it assumes that old and new reg agree in the number of necessary hardregs. That simply isn't the case always. Even if it were it's not quite clear how the later register numbers should be interpreted inside the target hook. E.g. assume that regrename decides to rename r16:DF into r2:DF, and also assume that r0-15 are SImode (hence we need two for DFmode) and r16 onwards are DFmode regs (only needs one). Now the question towards the backend certainly needs to be at least: "can r16 be renamed into r2, in principle?". So: TARGETHOOK (r16, r2) But asking also "TARGETHOOK (r16, r3)" doesn't make much sense here. And asking "TARGETHOOK (r17, r3)" is completely wrong. So, something needs to give way. An idea was to add a mode argument to the target hook and only ask the starting register number: TARGETHOOK (DFmode, r16, r2) (then the target can either do something with the mode or not. Most targets currently only inspect the src or target regnumber to not be "special", like being a callee saved register that wasn't in fact saved.) Something to keep in mind with that proposal (adding a mode argument) would be that regrename can rename multi-mode chains. I.e. a web of connected defs/uses of a hardreg that have not just a single mode. The proposal would still work in light of that when the hooks would be called as part of the loop over all uses of the chain (instead of within the loop over all nregs): for (tmp = this_head->first; tmp; tmp = tmp->next_use) ... if (!TARGETHOOK (GET_MODE (*tmp->loc), reg, new_reg)) ... new_reg can't be used ...