src/cmd/compile/internal/liveness/mergelocals.go | 19 ++++++++++++++++--- src/cmd/compile/internal/ssa/_gen/ARMOps.go | 2 ++ src/cmd/compile/internal/ssa/_gen/S390XOps.go | 2 ++ src/cmd/compile/internal/ssa/opGen.go | 2 ++ diff --git a/src/cmd/compile/internal/liveness/mergelocals.go b/src/cmd/compile/internal/liveness/mergelocals.go index 28d034a90e87d3840abc3cddc7d3a7393905b045..b9be0dd4c9768dadad1ae5b4a95ea81469098608 100644 --- a/src/cmd/compile/internal/liveness/mergelocals.go +++ b/src/cmd/compile/internal/liveness/mergelocals.go @@ -516,9 +516,22 @@ } for idx, arg := range v.Args { if nc, ok := pendingUses[arg.ID]; ok { if !v.AddrSinkArg(idx) { - // If this op may propagate the argument address to its output, - // then give up. See issue 80127. - continue + // If this op may propagate its input address + // to somewhere else, we must track where that + // somewhere else might be. See issue 80127. + if v.Type.IsMemory() { + // Might be stored to memory. Give up. + continue + } + // Some sort of address arithmetic. + if _, ok := pendingUses[v.ID]; ok { + // v has used multiple addresses, which is something + // we can't keep track of. Give up. + continue + } + // Treat this op as producing the address of the same variable + // that its argument was the address of. + pendingUses[v.ID] = nameCount{n: nc.n, count: v.Uses} } // We found a use of some value that took the // address of nc.n. Record this inst as a diff --git a/src/cmd/compile/internal/ssa/_gen/ARMOps.go b/src/cmd/compile/internal/ssa/_gen/ARMOps.go index c40bdb30681e54e4868f724aae34c169cd362082..624d1d956e5d107432b0438bf1fab1d9fd02df31 100644 --- a/src/cmd/compile/internal/ssa/_gen/ARMOps.go +++ b/src/cmd/compile/internal/ssa/_gen/ARMOps.go @@ -507,6 +507,7 @@ }, clobberFlags: true, faultOnNilArg0: true, addrSinkArg0: true, + addrSinkArg1: true, }, // large or unaligned move @@ -532,6 +533,7 @@ faultOnNilArg0: true, faultOnNilArg1: true, addrSinkArg0: true, addrSinkArg1: true, + // TODO: could use addrSinkArg2 here. }, // Scheduler ensures LoweredGetClosurePtr occurs only in entry block, diff --git a/src/cmd/compile/internal/ssa/_gen/S390XOps.go b/src/cmd/compile/internal/ssa/_gen/S390XOps.go index 7774ac14edff4c4ffa3c9c5b5d0381cc12dbca89..76e5d86f0a212635a4216aa0f3bfab0950f59d48 100644 --- a/src/cmd/compile/internal/ssa/_gen/S390XOps.go +++ b/src/cmd/compile/internal/ssa/_gen/S390XOps.go @@ -754,6 +754,7 @@ faultOnNilArg0: true, faultOnNilArg1: true, addrSinkArg0: true, addrSinkArg1: true, + // TODO: could use addrSinkArg2 here. }, // large clear @@ -780,6 +781,7 @@ clobberFlags: true, typ: "Mem", faultOnNilArg0: true, addrSinkArg0: true, + addrSinkArg1: true, }, } diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index e54be4360e8bb68d168ee3bba31b2c3b057fc554..25a6db99ba5c68a1705fa4ac4bc56e0723084dc9 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -65242,6 +65242,7 @@ argLen: 4, clobberFlags: true, faultOnNilArg0: true, addrSinkArg0: true, + addrSinkArg1: true, reg: regInfo{ inputs: []inputInfo{ {0, 2}, // R1 @@ -85725,6 +85726,7 @@ argLen: 3, clobberFlags: true, faultOnNilArg0: true, addrSinkArg0: true, + addrSinkArg1: true, reg: regInfo{ inputs: []inputInfo{ {0, 2}, // R1