From 2ac1f9cbc3eb2b97ad82730569199ba6ffea956d Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Fri, 28 Nov 2025 17:19:42 +0700 Subject: [PATCH] cmd/compile: avoid unnecessary interface conversion in bloop Fixes #76482 Change-Id: I076568d8ae92ad6c9e0a5797cfe5bbfb615f63d2 Reviewed-on: https://go-review.googlesource.com/c/go/+/725180 LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Dmitri Shuralyov Auto-Submit: Cuong Manh Le --- src/cmd/compile/internal/bloop/bloop.go | 4 ++-- test/bloop.go | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cmd/compile/internal/bloop/bloop.go b/src/cmd/compile/internal/bloop/bloop.go index e4a86d89142..761b07abd4d 100644 --- a/src/cmd/compile/internal/bloop/bloop.go +++ b/src/cmd/compile/internal/bloop/bloop.go @@ -74,7 +74,7 @@ func getNameFromNode(n ir.Node) *ir.Name { } // keepAliveAt returns a statement that is either curNode, or a -// block containing curNode followed by a call to runtime.keepAlive for each +// block containing curNode followed by a call to runtime.KeepAlive for each // node in ns. These calls ensure that nodes in ns will be live until // after curNode's execution. func keepAliveAt(ns []ir.Node, curNode ir.Node) ir.Node { @@ -94,7 +94,7 @@ func keepAliveAt(ns []ir.Node, curNode ir.Node) ir.Node { if n.Sym().IsBlank() { continue } - arg := ir.NewConvExpr(pos, ir.OCONV, types.Types[types.TINTER], n) + arg := ir.NewConvExpr(pos, ir.OCONV, types.Types[types.TUNSAFEPTR], typecheck.NodAddr(n)) if !n.Type().IsInterface() { srcRType0 := reflectdata.TypePtrAt(pos, n.Type()) arg.TypeWord = srcRType0 diff --git a/test/bloop.go b/test/bloop.go index a19d8345b00..fd22132dbfa 100644 --- a/test/bloop.go +++ b/test/bloop.go @@ -31,23 +31,23 @@ func test(b *testing.B, localsink, cond int) { // ERROR ".*" } somethingptr := &something for b.Loop() { // ERROR "inlining call to testing\.\(\*B\)\.Loop" - caninline(1) // ERROR "inlining call to caninline" "function result will be kept alive" ".* does not escape" - caninlineNoRet(1) // ERROR "inlining call to caninlineNoRet" "function arg will be kept alive" ".* does not escape" + caninline(1) // ERROR "inlining call to caninline" "function result will be kept alive" + caninlineNoRet(1) // ERROR "inlining call to caninlineNoRet" "function arg will be kept alive" caninlineVariadic(1) // ERROR "inlining call to caninlineVariadic" "function arg will be kept alive" ".* does not escape" caninlineVariadic(localsink) // ERROR "inlining call to caninlineVariadic" "localsink will be kept alive" ".* does not escape" - localsink = caninline(1) // ERROR "inlining call to caninline" "localsink will be kept alive" ".* does not escape" - localsink += 5 // ERROR "localsink will be kept alive" ".* does not escape" - localsink, cond = 1, 2 // ERROR "localsink will be kept alive" "cond will be kept alive" ".* does not escape" + localsink = caninline(1) // ERROR "inlining call to caninline" "localsink will be kept alive" + localsink += 5 // ERROR "localsink will be kept alive" + localsink, cond = 1, 2 // ERROR "localsink will be kept alive" "cond will be kept alive" *somethingptr = 1 // ERROR "dereference will be kept alive" if cond > 0 { - caninline(1) // ERROR "inlining call to caninline" "function result will be kept alive" ".* does not escape" + caninline(1) // ERROR "inlining call to caninline" "function result will be kept alive" } switch cond { case 2: - caninline(1) // ERROR "inlining call to caninline" "function result will be kept alive" ".* does not escape" + caninline(1) // ERROR "inlining call to caninline" "function result will be kept alive" } { - caninline(1) // ERROR "inlining call to caninline" "function result will be kept alive" ".* does not escape" + caninline(1) // ERROR "inlining call to caninline" "function result will be kept alive" } } }