cmd/compile: ensure spills of int/float reg args land in abi slots

We noticed a while ago that register argument spills were not always
landing where they should.

Updates #40724.

Change-Id: I0b7c3279a2f6270577481c252bae4568cbb6e796
Reviewed-on: https://go-review.googlesource.com/c/go/+/308510
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
David Chase 2021-04-07 09:58:02 -04:00
parent d138ee2cfb
commit a690a5d75f

View file

@ -218,8 +218,15 @@ func (s *stackAllocState) stackalloc() {
// If this is a named value, try to use the name as // If this is a named value, try to use the name as
// the spill location. // the spill location.
var name LocalSlot var name LocalSlot
interfere := false
if v.Op == OpStoreReg { if v.Op == OpStoreReg {
name = names[v.Args[0].ID] a := v.Args[0]
name = names[a.ID]
if name.N == nil && (a.Op == OpArgIntReg || a.Op == OpArgFloatReg) {
// Try harder to spill to the abi-provided spill slot, even if the names are messed up.
nameOff := a.Aux.(*AuxNameOffset)
name = LocalSlot{N: nameOff.Name, Type: v.Type, Off: nameOff.Offset}
}
} else { } else {
name = names[v.ID] name = names[v.ID]
} }
@ -230,6 +237,7 @@ func (s *stackAllocState) stackalloc() {
// A variable can interfere with itself. // A variable can interfere with itself.
// It is rare, but it can happen. // It is rare, but it can happen.
s.nSelfInterfere++ s.nSelfInterfere++
interfere = true
goto noname goto noname
} }
} }
@ -271,7 +279,11 @@ func (s *stackAllocState) stackalloc() {
// Use the stack variable at that index for v. // Use the stack variable at that index for v.
loc := locs[i] loc := locs[i]
if f.pass.debug > stackDebug { if f.pass.debug > stackDebug {
fmt.Printf("stackalloc %s to %s\n", v, loc) reason := "noname"
if interfere {
reason = "interfere"
}
fmt.Printf("stackalloc (%s) %s to %s\n", reason, v, loc)
} }
f.setHome(v, loc) f.setHome(v, loc)
slots[v.ID] = i slots[v.ID] = i