Skip to content

Commit 084c0f8

Browse files
author
Michael Munday
committed
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 <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent a62f72f commit 084c0f8

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/cmd/compile/internal/ssa/branchelim.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,15 @@ func canSpeculativelyExecute(b *Block) bool {
436436
// don't fuse memory ops, Phi ops, divides (can panic),
437437
// or anything else with side-effects
438438
for _, v := range b.Values {
439-
if v.Op == OpPhi || isDivMod(v.Op) || isPtrArithmetic(v.Op) || v.Type.IsMemory() ||
440-
v.MemoryArg() != nil || opcodeTable[v.Op].hasSideEffects {
439+
if v.Op == OpPhi || isDivMod(v.Op) || isPtrArithmetic(v.Op) ||
440+
v.Type.IsMemory() || opcodeTable[v.Op].hasSideEffects {
441+
return false
442+
}
443+
444+
// Allow inlining markers to be speculatively executed
445+
// even though they have a memory argument.
446+
// See issue #74915.
447+
if v.Op != OpInlMark && v.MemoryArg() != nil {
441448
return false
442449
}
443450
}

test/codegen/fuse.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,24 @@ func ui4d(c <-chan uint8) {
195195
for x := <-c; x < 126 || x >= 128; x = <-c {
196196
}
197197
}
198+
199+
// ------------------------------------ //
200+
// regressions //
201+
// ------------------------------------ //
202+
203+
func gte4(x uint64) bool {
204+
return x >= 4
205+
}
206+
207+
func lt20(x uint64) bool {
208+
return x < 20
209+
}
210+
211+
func issue74915(c <-chan uint64) {
212+
// Check that the optimization is not blocked by function inlining.
213+
214+
// amd64:"CMPQ\t.+, [$]16","ADDQ\t[$]-4,"
215+
// s390x:"CLGIJ\t[$]4, R[0-9]+, [$]16","ADD\t[$]-4,"
216+
for x := <-c; gte4(x) && lt20(x); x = <-c {
217+
}
218+
}

0 commit comments

Comments
 (0)