// 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
}
}
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 {
+ }
+}