http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50751
--- Comment #34 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Oleg Endo from comment #29) > (In reply to comment #28) > > I'm now trying to work around this by adding special insn_and_split patterns > > for the reload phase and removing the displacement addressing special cases > > in > > sh_secondary_reload.... > > ... without any useful results. > The failing test case is gcc.c-torture/compile/sync-1.c > > The problematic insns are: > > (insn 218 215 220 3 (set (reg:HI 448 [ D.41678+2 ]) > (subreg:HI (reg:SI 439 [ D.41678 ]) 2)) > (nil)) > > (insn 220 218 237 3 (parallel [ > (set (reg:SI 447) > (unspec_volatile:SI [ > (mem:HI (reg/f:SI 303) [0 S2 A16]) > (reg:HI 448 [ D.41678+2 ]) > (reg:HI 442 [ D.41685 ]) > ] UNSPECV_CMPXCHG_1)) > (set (mem:HI (reg/f:SI 303) [0 S2 A16]) > ... > > For example, when R0 is allocated for 448 (which is required to do the > displacement addressing) and then reload tries to allocate regs for 448 or > 442, it will try to allocate them in R0_REGS class only. This doesn't work > of course, because the atomic insns clobber R0, and it results in a spill > failure for the atomic insn. Then there is also the case, when subsequent > atomic insns refer to a a reg that was allocated to R0 before. > Ideally, reload should insert a reg-reg move and try to allocate regs > outside the R0_REGS class, but it doesn't. I've tried to reproduce this on trunk rev 205756 (4.9) and the problem seems to be gone.