Skip to content

Commit c682d32

Browse files
committed
cmd/compile: convert constants to interfaces without allocating
The order pass is responsible for ensuring that values passed to runtime functions, including convT2E/convT2I, are addressable. Prior to this CL, this was always accomplished by creating a temp, which frequently escaped to the heap, causing allocations, perhaps most notably in code like: fmt.Println(1, 2, 3) // allocates three times None of the runtime routines modify the contents of the pointers they receive, so in the case of constants, instead of creating a temp value, we can create a static value. (Marking the static value as read-only provides protection against accidental attempts by the runtime to modify the constant data.) This improves code generation for code like: panic("abc") c <- 2 // c is a chan int which can now simply refer to "abc" and 2, rather than going by way of a temporary. It also allows us to optimize convT2E/convT2I, by recognizing static readonly values and directly constructing the interface. This CL adds ~0.5% to binary size, despite decreasing the size of many functions, because it also adds many static symbols. This binary size regression could be recovered in future (but currently unplanned) work. There is a lot of content-duplication in these symbols; this statement generates six new symbols, three containing an int 1 and three containing a pointer to the string "a": fmt.Println(1, 1, 1, "a", "a", "a") These symbols could be made content-addressable. Furthermore, these symbols are small, so the alignment and naming overhead is large. As with the go.strings section, these symbols could be hidden and have their alignment reduced. The changes to test/live.go make it impossible (at least with current optimization techniques) to place the values being passed to the runtime in static symbols, preserving autotmp creation. Fixes #18704 Benchmarks from fmt and go-kit's logging package: github.com/go-kit/kit/log name old time/op new time/op delta JSONLoggerSimple-8 1.91µs ± 2% 2.11µs ±22% ~ (p=1.000 n=9+10) JSONLoggerContextual-8 2.60µs ± 6% 2.43µs ± 2% -6.29% (p=0.000 n=9+10) Discard-8 101ns ± 2% 34ns ±14% -66.33% (p=0.000 n=10+9) OneWith-8 161ns ± 1% 102ns ±16% -36.78% (p=0.000 n=10+10) TwoWith-8 175ns ± 3% 106ns ± 7% -39.36% (p=0.000 n=10+9) TenWith-8 293ns ± 3% 227ns ±15% -22.44% (p=0.000 n=9+10) LogfmtLoggerSimple-8 704ns ± 2% 608ns ± 2% -13.65% (p=0.000 n=10+9) LogfmtLoggerContextual-8 962ns ± 1% 860ns ±17% -10.57% (p=0.003 n=9+10) NopLoggerSimple-8 188ns ± 1% 120ns ± 1% -36.39% (p=0.000 n=9+10) NopLoggerContextual-8 379ns ± 1% 243ns ± 0% -35.77% (p=0.000 n=9+10) ValueBindingTimestamp-8 577ns ± 1% 499ns ± 1% -13.51% (p=0.000 n=10+10) ValueBindingCaller-8 898ns ± 2% 844ns ± 2% -6.00% (p=0.000 n=10+10) name old alloc/op new alloc/op delta JSONLoggerSimple-8 904B ± 0% 872B ± 0% -3.54% (p=0.000 n=10+10) JSONLoggerContextual-8 1.20kB ± 0% 1.14kB ± 0% -5.33% (p=0.000 n=10+10) Discard-8 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=10+10) OneWith-8 96.0B ± 0% 64.0B ± 0% -33.33% (p=0.000 n=10+10) TwoWith-8 160B ± 0% 128B ± 0% -20.00% (p=0.000 n=10+10) TenWith-8 672B ± 0% 640B ± 0% -4.76% (p=0.000 n=10+10) LogfmtLoggerSimple-8 128B ± 0% 96B ± 0% -25.00% (p=0.000 n=10+10) LogfmtLoggerContextual-8 304B ± 0% 240B ± 0% -21.05% (p=0.000 n=10+10) NopLoggerSimple-8 128B ± 0% 96B ± 0% -25.00% (p=0.000 n=10+10) NopLoggerContextual-8 304B ± 0% 240B ± 0% -21.05% (p=0.000 n=10+10) ValueBindingTimestamp-8 159B ± 0% 127B ± 0% -20.13% (p=0.000 n=10+10) ValueBindingCaller-8 112B ± 0% 80B ± 0% -28.57% (p=0.000 n=10+10) name old allocs/op new allocs/op delta JSONLoggerSimple-8 19.0 ± 0% 17.0 ± 0% -10.53% (p=0.000 n=10+10) JSONLoggerContextual-8 25.0 ± 0% 21.0 ± 0% -16.00% (p=0.000 n=10+10) Discard-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10) OneWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10) TwoWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10) TenWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10) LogfmtLoggerSimple-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10) LogfmtLoggerContextual-8 7.00 ± 0% 3.00 ± 0% -57.14% (p=0.000 n=10+10) NopLoggerSimple-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10) NopLoggerContextual-8 7.00 ± 0% 3.00 ± 0% -57.14% (p=0.000 n=10+10) ValueBindingTimestamp-8 5.00 ± 0% 3.00 ± 0% -40.00% (p=0.000 n=10+10) ValueBindingCaller-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10) fmt name old time/op new time/op delta SprintfPadding-8 88.9ns ± 3% 79.1ns ± 1% -11.09% (p=0.000 n=10+7) SprintfEmpty-8 12.6ns ± 3% 12.8ns ± 3% ~ (p=0.136 n=10+10) SprintfString-8 38.7ns ± 5% 26.9ns ± 6% -30.65% (p=0.000 n=10+10) SprintfTruncateString-8 56.7ns ± 2% 47.0ns ± 3% -17.05% (p=0.000 n=10+10) SprintfQuoteString-8 164ns ± 2% 153ns ± 2% -7.01% (p=0.000 n=10+10) SprintfInt-8 38.9ns ±15% 26.5ns ± 2% -31.93% (p=0.000 n=10+9) SprintfIntInt-8 60.3ns ± 9% 38.2ns ± 1% -36.67% (p=0.000 n=10+8) SprintfPrefixedInt-8 58.6ns ±13% 51.2ns ±11% -12.66% (p=0.001 n=10+10) SprintfFloat-8 71.4ns ± 3% 64.2ns ± 3% -10.08% (p=0.000 n=8+10) SprintfComplex-8 175ns ± 3% 159ns ± 2% -9.03% (p=0.000 n=10+10) SprintfBoolean-8 33.5ns ± 4% 25.7ns ± 5% -23.28% (p=0.000 n=10+10) SprintfHexString-8 65.3ns ± 3% 51.7ns ± 5% -20.86% (p=0.000 n=10+9) SprintfHexBytes-8 67.2ns ± 5% 67.9ns ± 4% ~ (p=0.383 n=10+10) SprintfBytes-8 129ns ± 7% 124ns ± 7% ~ (p=0.074 n=9+10) SprintfStringer-8 127ns ± 4% 126ns ± 8% ~ (p=0.506 n=9+10) SprintfStructure-8 357ns ± 3% 359ns ± 3% ~ (p=0.469 n=10+10) ManyArgs-8 203ns ± 6% 126ns ± 3% -37.94% (p=0.000 n=10+10) FprintInt-8 119ns ±10% 74ns ± 3% -37.54% (p=0.000 n=10+10) FprintfBytes-8 122ns ± 4% 120ns ± 3% ~ (p=0.124 n=10+10) FprintIntNoAlloc-8 78.2ns ± 5% 74.1ns ± 3% -5.28% (p=0.000 n=10+10) ScanInts-8 349µs ± 1% 349µs ± 0% ~ (p=0.606 n=9+8) ScanRecursiveInt-8 43.8ms ± 7% 40.1ms ± 2% -8.42% (p=0.000 n=10+10) ScanRecursiveIntReaderWrapper-8 43.5ms ± 4% 40.4ms ± 2% -7.16% (p=0.000 n=10+9) name old alloc/op new alloc/op delta SprintfPadding-8 24.0B ± 0% 16.0B ± 0% -33.33% (p=0.000 n=10+10) SprintfEmpty-8 0.00B 0.00B ~ (all equal) SprintfString-8 21.0B ± 0% 5.0B ± 0% -76.19% (p=0.000 n=10+10) SprintfTruncateString-8 32.0B ± 0% 16.0B ± 0% -50.00% (p=0.000 n=10+10) SprintfQuoteString-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=10+10) SprintfInt-8 16.0B ± 0% 1.0B ± 0% -93.75% (p=0.000 n=10+10) SprintfIntInt-8 24.0B ± 0% 3.0B ± 0% -87.50% (p=0.000 n=10+10) SprintfPrefixedInt-8 72.0B ± 0% 64.0B ± 0% -11.11% (p=0.000 n=10+10) SprintfFloat-8 16.0B ± 0% 8.0B ± 0% -50.00% (p=0.000 n=10+10) SprintfComplex-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=10+10) SprintfBoolean-8 8.00B ± 0% 4.00B ± 0% -50.00% (p=0.000 n=10+10) SprintfHexString-8 96.0B ± 0% 80.0B ± 0% -16.67% (p=0.000 n=10+10) SprintfHexBytes-8 112B ± 0% 112B ± 0% ~ (all equal) SprintfBytes-8 96.0B ± 0% 96.0B ± 0% ~ (all equal) SprintfStringer-8 32.0B ± 0% 32.0B ± 0% ~ (all equal) SprintfStructure-8 256B ± 0% 256B ± 0% ~ (all equal) ManyArgs-8 80.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10) FprintInt-8 8.00B ± 0% 0.00B -100.00% (p=0.000 n=10+10) FprintfBytes-8 32.0B ± 0% 32.0B ± 0% ~ (all equal) FprintIntNoAlloc-8 0.00B 0.00B ~ (all equal) ScanInts-8 15.2kB ± 0% 15.2kB ± 0% ~ (p=0.248 n=9+10) ScanRecursiveInt-8 21.6kB ± 0% 21.6kB ± 0% ~ (all equal) ScanRecursiveIntReaderWrapper-8 21.7kB ± 0% 21.7kB ± 0% ~ (all equal) name old allocs/op new allocs/op delta SprintfPadding-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfEmpty-8 0.00 0.00 ~ (all equal) SprintfString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfTruncateString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfQuoteString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfInt-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfIntInt-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10) SprintfPrefixedInt-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfFloat-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfComplex-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfBoolean-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfHexString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) SprintfHexBytes-8 2.00 ± 0% 2.00 ± 0% ~ (all equal) SprintfBytes-8 2.00 ± 0% 2.00 ± 0% ~ (all equal) SprintfStringer-8 4.00 ± 0% 4.00 ± 0% ~ (all equal) SprintfStructure-8 7.00 ± 0% 7.00 ± 0% ~ (all equal) ManyArgs-8 8.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10) FprintInt-8 1.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10) FprintfBytes-8 1.00 ± 0% 1.00 ± 0% ~ (all equal) FprintIntNoAlloc-8 0.00 0.00 ~ (all equal) ScanInts-8 1.60k ± 0% 1.60k ± 0% ~ (all equal) ScanRecursiveInt-8 1.71k ± 0% 1.71k ± 0% ~ (all equal) ScanRecursiveIntReaderWrapper-8 1.71k ± 0% 1.71k ± 0% ~ (all equal) Change-Id: I7ba72a25fea4140a0ba40a9f443103ed87cc69b5 Reviewed-on: https://go-review.googlesource.com/35554 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
1 parent f395e87 commit c682d32

File tree

4 files changed

+61
-30
lines changed

4 files changed

+61
-30
lines changed

src/cmd/compile/internal/gc/order.go

+16
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,23 @@ func isaddrokay(n *Node) bool {
183183
// Orderaddrtemp ensures that n is okay to pass by address to runtime routines.
184184
// If the original argument n is not okay, orderaddrtemp creates a tmp, emits
185185
// tmp = n, and then returns tmp.
186+
// The result of orderaddrtemp MUST be assigned back to n, e.g.
187+
// n.Left = orderaddrtemp(n.Left, order)
186188
func orderaddrtemp(n *Node, order *Order) *Node {
189+
if consttype(n) >= 0 {
190+
// TODO: expand this to all static composite literal nodes?
191+
n = defaultlit(n, nil)
192+
dowidth(n.Type)
193+
vstat := staticname(n.Type)
194+
vstat.Name.Readonly = true
195+
var out []*Node
196+
staticassign(vstat, n, &out)
197+
if out != nil {
198+
Fatalf("staticassign of const generated code: %+v", n)
199+
}
200+
vstat = typecheck(vstat, Erv)
201+
return vstat
202+
}
187203
if isaddrokay(n) {
188204
return n
189205
}

src/cmd/compile/internal/gc/walk.go

+17-8
Original file line numberDiff line numberDiff line change
@@ -889,20 +889,29 @@ opswitch:
889889
n = l
890890
break
891891
}
892-
// Optimize convT2{E,I} when T is not pointer-shaped.
893-
// We make the interface by initializing a stack temporary to
894-
// the value we want to put in the interface, then using the address of
895-
// that stack temporary for the interface data word.
896-
if !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024 {
897-
tmp := temp(n.Left.Type)
898-
init.Append(typecheck(nod(OAS, tmp, n.Left), Etop))
892+
893+
// Optimize convT2{E,I} when T is not pointer-shaped,
894+
// but the value does not escape or is a readonly global.
895+
var value *Node
896+
switch {
897+
case !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024:
898+
// Initializing a stack temporary to the value we want to put in the interface,
899+
// then using the address of that stack temporary for the interface data word.
900+
value = temp(n.Left.Type)
901+
init.Append(typecheck(nod(OAS, value, n.Left), Etop))
902+
case n.Left.Class == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly:
903+
// readonly global; use directly.
904+
value = n.Left
905+
}
906+
907+
if value != nil {
899908
var t *Node
900909
if n.Type.IsEmptyInterface() {
901910
t = typename(n.Left.Type)
902911
} else {
903912
t = itabname(n.Left.Type, n.Type)
904913
}
905-
l := nod(OEFACE, t, typecheck(nod(OADDR, tmp, nil), Erv))
914+
l := nod(OEFACE, t, typecheck(nod(OADDR, value, nil), Erv))
906915
l.Type = n.Type
907916
l.Typecheck = n.Typecheck
908917
n = l

src/cmd/internal/obj/data.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (s *LSym) GrowCap(c int64) {
7070
// prepwrite prepares to write data of size siz into s at offset off.
7171
func (s *LSym) prepwrite(ctxt *Link, off int64, siz int) {
7272
if off < 0 || siz < 0 || off >= 1<<30 {
73-
log.Fatalf("prepwrite: bad off=%d siz=%d", off, siz)
73+
log.Fatalf("prepwrite: bad off=%d siz=%d s=%v", off, siz, s)
7474
}
7575
if s.Type == SBSS || s.Type == STLSBSS {
7676
ctxt.Diag("cannot supply data for BSS var")

test/live.go

+27-21
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ var i9 interface{}
141141
func f9() bool {
142142
g8()
143143
x := i9
144-
y := interface{}(99.0i) // ERROR "live at call to convT2E: x.data x.type$"
144+
y := interface{}(str()) // ERROR "live at call to convT2E: .autotmp_[0-9]+ x.data x.type$" "live at call to str: x.data x.type$"
145145
i9 = y // make y escape so the line above has to call convT2E
146146
return x != y
147147
}
@@ -256,12 +256,15 @@ func g15() string
256256

257257
var m map[string]int
258258

259+
// str is used to ensure that a temp is required for runtime calls below.
260+
func str() string
261+
259262
func f16() {
260263
if b {
261-
delete(m, "hi") // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
264+
delete(m, str()) // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
262265
}
263-
delete(m, "hi") // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
264-
delete(m, "hi") // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
266+
delete(m, str()) // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
267+
delete(m, str()) // ERROR "live at call to mapdelete: .autotmp_[0-9]+$"
265268
}
266269

267270
var m2s map[string]*byte
@@ -280,19 +283,19 @@ func f17a(p *byte) { // ERROR "live at entry to f17a: p$"
280283
func f17b(p *byte) { // ERROR "live at entry to f17b: p$"
281284
// key temporary
282285
if b {
283-
m2s["x"] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$"
286+
m2s[str()] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$" "live at call to str: p$"
284287
}
285-
m2s["x"] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$"
286-
m2s["x"] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$"
288+
m2s[str()] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$" "live at call to str: p$"
289+
m2s[str()] = p // ERROR "live at call to mapassign: p .autotmp_[0-9]+$" "live at call to str: p$"
287290
}
288291

289292
func f17c() {
290293
// key and value temporaries
291294
if b {
292-
m2s["x"] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
295+
m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
293296
}
294-
m2s["x"] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
295-
m2s["x"] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
297+
m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
298+
m2s[str()] = f17d() // ERROR "live at call to f17d: .autotmp_[0-9]+$" "live at call to mapassign: .autotmp_[0-9]+ .autotmp_[0-9]+$"
296299
}
297300

298301
func f17d() *byte
@@ -313,6 +316,9 @@ func f18() {
313316

314317
var ch chan *byte
315318

319+
// byteptr is used to ensure that a temp is required for runtime calls below.
320+
func byteptr() *byte
321+
316322
func f19() {
317323
// dest temporary for channel receive.
318324
var z *byte
@@ -328,10 +334,10 @@ func f19() {
328334
func f20() {
329335
// src temporary for channel send
330336
if b {
331-
ch <- nil // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
337+
ch <- byteptr() // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
332338
}
333-
ch <- nil // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
334-
ch <- nil // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
339+
ch <- byteptr() // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
340+
ch <- byteptr() // ERROR "live at call to chansend1: .autotmp_[0-9]+$"
335341
}
336342

337343
func f21() {
@@ -488,13 +494,13 @@ func f30(b bool) {
488494

489495
func f31(b1, b2, b3 bool) {
490496
if b1 {
491-
g31("a") // ERROR "live at call to convT2E: .autotmp_[0-9]+$" "live at call to g31: .autotmp_[0-9]+$"
497+
g31(str()) // ERROR "live at call to convT2E: .autotmp_[0-9]+$" "live at call to g31: .autotmp_[0-9]+$"
492498
}
493499
if b2 {
494-
h31("b") // ERROR "live at call to convT2E: .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to h31: .autotmp_[0-9]+$" "live at call to newobject: .autotmp_[0-9]+$"
500+
h31(str()) // ERROR "live at call to convT2E: .autotmp_[0-9]+ .autotmp_[0-9]+$" "live at call to h31: .autotmp_[0-9]+$" "live at call to newobject: .autotmp_[0-9]+$"
495501
}
496502
if b3 {
497-
panic("asdf") // ERROR "live at call to convT2E: .autotmp_[0-9]+$" "live at call to gopanic: .autotmp_[0-9]+$"
503+
panic(str()) // ERROR "live at call to convT2E: .autotmp_[0-9]+$" "live at call to gopanic: .autotmp_[0-9]+$"
498504
}
499505
print(b3)
500506
}
@@ -529,7 +535,7 @@ func call32(func())
529535
var m33 map[interface{}]int
530536

531537
func f33() {
532-
if m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
538+
if m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
533539
printnl()
534540
return
535541
} else {
@@ -539,31 +545,31 @@ func f33() {
539545
}
540546

541547
func f34() {
542-
if m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
548+
if m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
543549
printnl()
544550
return
545551
}
546552
printnl()
547553
}
548554

549555
func f35() {
550-
if m33[nil] == 0 && m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
556+
if m33[byteptr()] == 0 && m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
551557
printnl()
552558
return
553559
}
554560
printnl()
555561
}
556562

557563
func f36() {
558-
if m33[nil] == 0 || m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
564+
if m33[byteptr()] == 0 || m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
559565
printnl()
560566
return
561567
}
562568
printnl()
563569
}
564570

565571
func f37() {
566-
if (m33[nil] == 0 || m33[nil] == 0) && m33[nil] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
572+
if (m33[byteptr()] == 0 || m33[byteptr()] == 0) && m33[byteptr()] == 0 { // ERROR "live at call to mapaccess1: .autotmp_[0-9]+$"
567573
printnl()
568574
return
569575
}

0 commit comments

Comments
 (0)