diff --git a/src/cmd/compile/internal/ssa/schedule.go b/src/cmd/compile/internal/ssa/schedule.go index 246376c767..4cd60d714c 100644 --- a/src/cmd/compile/internal/ssa/schedule.go +++ b/src/cmd/compile/internal/ssa/schedule.go @@ -130,8 +130,10 @@ func schedule(f *Func) { // We want all the phis first. score[v.ID] = ScorePhi case v.Op == OpArgIntReg || v.Op == OpArgFloatReg: - // In-register args must be scheduled as early as possible to ensure that the - // context register is not stomped. They should only appear in the entry block. + // In-register args must be scheduled as early as possible to ensure that they + // are not stomped (similar to the closure pointer above). + // In particular, they need to come before regular OpArg operations because + // of how regalloc places spill code (see regalloc.go:placeSpills:mustBeFirst). if b != f.Entry { f.Fatalf("%s appeared outside of entry block, b=%s", v.Op, b.String()) } diff --git a/test/live_regabi.go b/test/live_regabi.go index 6a8ff5d68a..bae319d2fd 100644 --- a/test/live_regabi.go +++ b/test/live_regabi.go @@ -11,6 +11,8 @@ package main +import "runtime" + func printnl() //go:noescape @@ -718,3 +720,23 @@ func f44(f func() [2]*int) interface{} { // ERROR "live at entry to f44: f" ret.s[0] = f() return ret } + +func f45(a, b, c, d, e, f, g, h, i, j, k, l *byte) { // ERROR "live at entry to f45: a b c d e f g h i j k l" + f46(a, b, c, d, e, f, g, h, i, j, k, l) // ERROR "live at call to f46: a b c d e f g h i j k l" + runtime.KeepAlive(a) + runtime.KeepAlive(b) + runtime.KeepAlive(c) + runtime.KeepAlive(d) + runtime.KeepAlive(e) + runtime.KeepAlive(f) + runtime.KeepAlive(g) + runtime.KeepAlive(h) + runtime.KeepAlive(i) + runtime.KeepAlive(j) + runtime.KeepAlive(k) + runtime.KeepAlive(l) +} + +//go:noinline +func f46(a, b, c, d, e, f, g, h, i, j, k, l *byte) { +}