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.

Reply via email to