From: Keith Randall Date: Mon, 21 Jul 2025 17:09:35 +0000 (-0700) Subject: [release-branch.go1.24] cmd/compile: for arm64 epilog, do SP increment with a single... X-Git-Tag: go1.24.6~3 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6e1c4529e4e00ab58572deceab74cc4057e6f0b6;p=gostls13.git [release-branch.go1.24] cmd/compile: for arm64 epilog, do SP increment with a single instruction That way, the frame is atomically popped. Previously, for big frames the SP was unwound in two steps (because arm64 can only add constants up to 1<<12 in a single instruction). Fixes #74694 Change-Id: I382c249194ad7bc9fc19607c27487c58d90d49e5 Reviewed-on: https://go-review.googlesource.com/c/go/+/689235 LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Pratt Reviewed-by: Keith Randall (cherry picked from commit f7cc61e7d7f77521e073137c6045ba73f66ef902) Reviewed-on: https://go-review.googlesource.com/c/go/+/689596 --- diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go index 368a631ff5..ea1a35b097 100644 --- a/src/cmd/internal/obj/arm64/obj7.go +++ b/src/cmd/internal/obj/arm64/obj7.go @@ -907,18 +907,49 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.To.Reg = REGFP p.To.Offset = REGLINK - // ADD $aoffset, RSP, RSP - q = newprog() - q.As = AADD - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(aoffset) - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Spadj = -aoffset - q.Pos = p.Pos - q.Link = p.Link - p.Link = q - p = q + if aoffset < 1<<12 { + // ADD $aoffset, RSP, RSP + q = newprog() + q.As = AADD + q.From.Type = obj.TYPE_CONST + q.From.Offset = int64(aoffset) + q.To.Type = obj.TYPE_REG + q.To.Reg = REGSP + q.Spadj = -aoffset + q.Pos = p.Pos + q.Link = p.Link + p.Link = q + p = q + } else { + // Put frame size in a separate register and + // add it in with a single instruction, + // so we never have a partial frame during + // the epilog. See issue 73259. + + // MOVD $aoffset, REGTMP + q = newprog() + q.As = AMOVD + q.From.Type = obj.TYPE_CONST + q.From.Offset = int64(aoffset) + q.To.Type = obj.TYPE_REG + q.To.Reg = REGTMP + q.Pos = p.Pos + q.Link = p.Link + p.Link = q + p = q + // ADD REGTMP, RSP, RSP + q = newprog() + q.As = AADD + q.From.Type = obj.TYPE_REG + q.From.Reg = REGTMP + q.To.Type = obj.TYPE_REG + q.To.Reg = REGSP + q.Spadj = -aoffset + q.Pos = p.Pos + q.Link = p.Link + p.Link = q + p = q + } } // If enabled, this code emits 'MOV PC, R27' before every 'MOV LR, PC',