https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88236
Senthil Kumar Selvaraj <saaadhu at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |saaadhu at gcc dot gnu.org --- Comment #2 from Senthil Kumar Selvaraj <saaadhu at gcc dot gnu.org> --- Created attachment 45119 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45119&action=edit Bug fix patch If reload choses r30 (or r31) as operand 0 of xload<mode>_8, the lpmx constraint alternative ends up generating wrong code, as avrt_out_xload would emit lpm r30, Z sbrc <operand1>, 7 ld r30, Z r30 gets clobbered by LPM, and LD with Z will therefore not work correctly. This happens even though operand 0 is marked as early clobber in the insn, presumably because of the hard coded (reg:HI REG_Z). If (reg:HI REG_Z) is replaced with (match_operand:HI 2 "register_operand" "z,z") then reload does respect the early clobber, but fails with "unable to find register to spill in pointer class POINTER_REGS_Z", probably because the xload8<mode>_A hardcodes REG_Z as the third operand. Adding a clobber for REG_Z prevents reload from assigning r30 as the output operand, even though REG_Z isn't technically clobbered. One other way to fix this would be to add a new register constraint that tells reload to use any register other than REG_Z. It likely won't make any difference in code gen, as REG_Z would have been clobbered by xload8<mode>_A anyway.