cmd/compile: allow InlMark operations to be speculatively executed

Although InlMark takes a memory argument it ultimately becomes a
NOP and therefore is safe to speculatively execute.

Fixes #74915

Change-Id: I64317dd433e300ac28de2bcf201845083ec2ac82
Reviewed-on: https://go-review.googlesource.com/c/go/+/693795
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
This commit is contained in:
Michael Munday 2025-08-06 22:43:05 +01:00
parent a62f72f7a7
commit 084c0f8494
2 changed files with 30 additions and 2 deletions

View file

@ -436,8 +436,15 @@ func canSpeculativelyExecute(b *Block) bool {
// don't fuse memory ops, Phi ops, divides (can panic),
// or anything else with side-effects
for _, v := range b.Values {
if v.Op == OpPhi || isDivMod(v.Op) || isPtrArithmetic(v.Op) || v.Type.IsMemory() ||
v.MemoryArg() != nil || opcodeTable[v.Op].hasSideEffects {
if v.Op == OpPhi || isDivMod(v.Op) || isPtrArithmetic(v.Op) ||
v.Type.IsMemory() || opcodeTable[v.Op].hasSideEffects {
return false
}
// Allow inlining markers to be speculatively executed
// even though they have a memory argument.
// See issue #74915.
if v.Op != OpInlMark && v.MemoryArg() != nil {
return false
}
}

View file

@ -195,3 +195,24 @@ func ui4d(c <-chan uint8) {
for x := <-c; x < 126 || x >= 128; x = <-c {
}
}
// ------------------------------------ //
// regressions //
// ------------------------------------ //
func gte4(x uint64) bool {
return x >= 4
}
func lt20(x uint64) bool {
return x < 20
}
func issue74915(c <-chan uint64) {
// Check that the optimization is not blocked by function inlining.
// amd64:"CMPQ\t.+, [$]16","ADDQ\t[$]-4,"
// s390x:"CLGIJ\t[$]4, R[0-9]+, [$]16","ADD\t[$]-4,"
for x := <-c; gte4(x) && lt20(x); x = <-c {
}
}