]> Cypherpunks repositories - gostls13.git/commitdiff
test: test that we schedule OpArgIntReg early
authorKeith Randall <khr@golang.org>
Fri, 20 Jan 2023 21:54:36 +0000 (13:54 -0800)
committerKeith Randall <khr@google.com>
Sat, 21 Jan 2023 21:08:30 +0000 (21:08 +0000)
If OpArgIntReg is incorrectly scheduled, that causes it to be spilled
incorrectly, which causes the argument to not be considered live
at the start of the function.

This is the test for CL 462858

Add a brief mention of why CL 462858 is needed in the scheduling code.

Change-Id: Id199456f88d9ee5ca46d7b0353a3c2049709880e
Reviewed-on: https://go-review.googlesource.com/c/go/+/462899
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>

src/cmd/compile/internal/ssa/schedule.go
test/live_regabi.go

index 246376c76744f2d26b8aeb53127f7c91f7098334..4cd60d714c9ed1d10d4505ab35288901ea8f31f1 100644 (file)
@@ -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())
                                }
index 6a8ff5d68abb091662972fc78da80ca36dac6718..bae319d2fd70243b7f982960d5d83e575a1bb0a1 100644 (file)
@@ -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) {
+}