Skip to content

Commit 3dfb92f

Browse files
committed
cmd/compile: ensure args are live in tail calls for LR machines
On link-register machines we uses RET (sym), instead of JMP (sym), for tail call (so the assembler knows and may rewrite it to restore link register if necessary). Add RET to the analysis. Fixes #17186. Fixes #16016 on link-register machines. Change-Id: I8690ac57dd9d49beeea76a5f291988e9a1d3afe5 Reviewed-on: https://go-review.googlesource.com/29570 Run-TryBot: Cherry Zhang <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 254169d commit 3dfb92f

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

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

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,22 @@ func progeffects(prog *obj.Prog, vars []*Node, uevar bvec, varkill bvec, avarini
549549
bvresetall(varkill)
550550
bvresetall(avarinit)
551551

552+
// A return instruction with a p.to is a tail return, which brings
553+
// the stack pointer back up (if it ever went down) and then jumps
554+
// to a new function entirely. That form of instruction must read
555+
// all the parameters for correctness, and similarly it must not
556+
// read the out arguments - they won't be set until the new
557+
// function runs.
558+
if (prog.As == obj.AJMP || prog.As == obj.ARET) && prog.To.Type == obj.TYPE_MEM && prog.To.Name == obj.NAME_EXTERN {
559+
// This is a tail call. Ensure the arguments are still alive.
560+
// See issue 16016.
561+
for i, node := range vars {
562+
if node.Class == PPARAM {
563+
bvset(uevar, int32(i))
564+
}
565+
}
566+
}
567+
552568
if prog.As == obj.ARET {
553569
// Return instructions read all of the out arguments.
554570
for i, node := range vars {
@@ -569,21 +585,6 @@ func progeffects(prog *obj.Prog, vars []*Node, uevar bvec, varkill bvec, avarini
569585

570586
return
571587
}
572-
// A return instruction with a p.to is a tail return, which brings
573-
// the stack pointer back up (if it ever went down) and then jumps
574-
// to a new function entirely. That form of instruction must read
575-
// all the parameters for correctness, and similarly it must not
576-
// read the out arguments - they won't be set until the new
577-
// function runs.
578-
if prog.As == obj.AJMP && prog.To.Type == obj.TYPE_MEM && prog.To.Name == obj.NAME_EXTERN {
579-
// This is a tail call. Ensure the arguments are still alive.
580-
// See issue 16016.
581-
for i, node := range vars {
582-
if node.Class == PPARAM {
583-
bvset(uevar, int32(i))
584-
}
585-
}
586-
}
587588

588589
if prog.As == obj.ATEXT {
589590
// A text instruction marks the entry point to a function and

0 commit comments

Comments
 (0)