https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55212
--- Comment #364 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Kazumoto Kojima from comment #345) > (In reply to Oleg Endo from comment #341) > > Do you have any idea how that might work? The only thing I can think of > > right now is to remove R0 from list of allocatable registers and add an RTL > > pass before RA which will insert "pseudo -> R0" before R0 constrained insns > > and "R0 -> pseudo" after constrained insns. I think this should be almost > > bullet-proof, but at the expense of potentially losing one register (R0). > > No, I don't have any specific idea, though I was envisioning the approach > what you suggested. I think this idea could be problematic, too. I've noticed that with LRA some of the atomic "imask" type patterns fail to combine with GBR memory addressing. For example, after the IRA pass, there might be the insn: (insn 6 5 9 2 (parallel [ (set (reg:QI 166) (mem/v:QI (plus:SI (reg:SI 144 gbr) (const_int 4 [0x4])) [-1 S1 A8])) (set (mem/v:QI (plus:SI (reg:SI 144 gbr) (const_int 4 [0x4])) [-1 S1 A8]) (unspec:QI [ (and:QI (mem/v:QI (plus:SI (reg:SI 144 gbr) (const_int 4 [0x4])) [-1 S1 A8]) (const_int 1 [0x1])) ] UNSPEC_ATOMIC)) (clobber (reg:SI 0 r0)) (clobber (reg:QI 169)) ]) "../gcc/gcc/testsuite/gcc.target/sh/pr64661-0.h":50:173 discrim 1 538 {atomic_fetch_andqi_soft_imask} (expr_list:REG_DEAD (reg:SI 144 gbr) (expr_list:REG_UNUSED (reg:QI 169) (expr_list:REG_UNUSED (reg:SI 0 r0) (nil))))) Notice that it already has the hard-reg GBR assigned. Yet for some reason I don't understand, the following LRA pass then pulls that out and replaces GBR with R3: (insn 6 22 9 2 (parallel [ (set (reg:QI 1 r1 [166]) (mem/v:QI (plus:SI (reg:SI 3 r3 [171]) (const_int 4 [0x4])) [-1 S1 A8])) (set (mem/v:QI (plus:SI (reg:SI 3 r3 [171]) (const_int 4 [0x4])) [-1 S1 A8]) (unspec:QI [ (and:QI (mem/v:QI (plus:SI (reg:SI 3 r3 [171]) (const_int 4 [0x4])) [-1 S1 A8]) (const_int 1 [0x1])) ] UNSPEC_ATOMIC)) (clobber (reg:SI 0 r0)) (clobber (reg:QI 2 r2 [169])) ]) "../gcc/gcc/testsuite/gcc.target/sh/pr64661-0.h":50:173 discrim 1 538 {atomic_fetch_andqi_soft_imask} (nil)) I've tried adding a constraint to that pattern, which would explicitly allow an GBR address, but it still does that transformation. It sounds a bit like the sfunc issue before, where it would re-allocate operands that already have hard-regs assigned. Why does it do that?