]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: allow InlMark operations to be speculatively executed
authorMichael Munday <mndygolang+git@gmail.com>
Wed, 6 Aug 2025 21:43:05 +0000 (22:43 +0100)
committerMichael Munday <mndygolang+git@gmail.com>
Mon, 11 Aug 2025 07:52:23 +0000 (00:52 -0700)
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>
src/cmd/compile/internal/ssa/branchelim.go
test/codegen/fuse.go

index f16959dd572973e62fb46a8ab1a61522b173b1ec..a7d339cad064ac35f363bf467122fc46096d93d2 100644 (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
                }
        }
index 79dd337dee223495c7182bf33cdab4b92b27e150..8d6ea3c5c74664d2bbdad6601d5da54bad622446 100644 (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 {
+       }
+}