https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95252
Jim Wilson <wilson at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Last reconfirmed| |2020-05-25 Status|UNCONFIRMED |NEW --- Comment #1 from Jim Wilson <wilson at gcc dot gnu.org> --- It appears to be failing in the rename register (rnreg) pass. This is because the unspec patterns for the save/restore calls don't mention the registers that they use/modify. This confuses rename reg into thinking that live regs are dead, and it accidentally clobbers them before the save call. This worked OK when save/restore calls could only be at the beginning or end of a function. But now that this works with tail calls and shrink wrapping, we can get them in inner blocks. Since the different save/restore calls use/modify different sets of registers, fixing this gets a little complicated. Maybe we can just use the max list of registers because listing extra ones shouldn't matter? Another solution is to disable the rename register pass when -msave-restore is used. This isn't doing any checking for whether regs can be used in compressed instructions or not. This is currently encoded in REG_ALLOC_ORDER which this pass doesn't use. The result is that this is probably increasing code size which is undesirable when -msave-restore it used. Disabling this would reduce code size and fix the -msave-restore problem. The rename register pass does use the PREFERRED_RENAME_CLASS hook that we haven't defined. We should try defining this to convert registers classes to subsets that only include the regs that can be used in compressed instructions. This might result in a code size decrease. If this works, then the rename reg pass should not be disabled, and we should find a way to fix the save/restore pattern register lists instead. I need to do some builds and experiments to verify this info.