[dev.regabi] cmd/compile: intercept the making of OADDR nodes

This is a mechanical change to intercept the construction of
all OADDR nodes. We will use the new nodAddr and nodAddrAt
functions to compute the Addrtaken bit.

Change-Id: I90ee3acb8e32540a198a9999284573418729f422
Reviewed-on: https://go-review.googlesource.com/c/go/+/275694
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
Keith Randall 2020-11-28 15:53:32 -08:00
parent 617383377f
commit fea898a4b0
11 changed files with 66 additions and 56 deletions

View File

@ -323,7 +323,7 @@ func genhash(t *types.Type) *obj.LSym {
nx := ir.Nod(ir.OINDEX, np, ni)
nx.SetBounded(true)
na := ir.Nod(ir.OADDR, nx, nil)
na := nodAddr(nx)
call.PtrList().Append(na)
call.PtrList().Append(nh)
loop.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
@ -347,7 +347,7 @@ func genhash(t *types.Type) *obj.LSym {
hashel := hashfor(f.Type)
call := ir.Nod(ir.OCALL, hashel, nil)
nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
na := ir.Nod(ir.OADDR, nx, nil)
na := nodAddr(nx)
call.PtrList().Append(na)
call.PtrList().Append(nh)
fn.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
@ -362,7 +362,7 @@ func genhash(t *types.Type) *obj.LSym {
hashel := hashmem(f.Type)
call := ir.Nod(ir.OCALL, hashel, nil)
nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
na := ir.Nod(ir.OADDR, nx, nil)
na := nodAddr(nx)
call.PtrList().Append(na)
call.PtrList().Append(nh)
call.PtrList().Append(nodintconst(size))
@ -868,8 +868,8 @@ func eqinterface(s, t ir.Node) (eqtab, eqdata ir.Node) {
// eqmem returns the node
// memequal(&p.field, &q.field [, size])
func eqmem(p ir.Node, q ir.Node, field *types.Sym, size int64) ir.Node {
nx := ir.Nod(ir.OADDR, nodSym(ir.OXDOT, p, field), nil)
ny := ir.Nod(ir.OADDR, nodSym(ir.OXDOT, q, field), nil)
nx := nodAddr(nodSym(ir.OXDOT, p, field))
ny := nodAddr(nodSym(ir.OXDOT, q, field))
nx = typecheck(nx, ctxExpr)
ny = typecheck(ny, ctxExpr)

View File

@ -199,7 +199,7 @@ func capturevars(fn *ir.Func) {
v.SetByval(true)
} else {
outermost.Name().SetAddrtaken(true)
outer = ir.Nod(ir.OADDR, outer, nil)
outer = nodAddr(outer)
}
if base.Flag.LowerM > 1 {
@ -309,7 +309,7 @@ func transformclosure(fn *ir.Func) {
v.Heapaddr = addr
var src ir.Node = cr
if v.Byval() {
src = ir.Nod(ir.OADDR, cr, nil)
src = nodAddr(cr)
}
body = append(body, ir.Nod(ir.OAS, addr, src))
}
@ -396,7 +396,7 @@ func walkclosure(clo ir.Node, init *ir.Nodes) ir.Node {
clos.SetEsc(clo.Esc())
clos.PtrList().Set(append([]ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
clos = ir.Nod(ir.OADDR, clos, nil)
clos = nodAddr(clos)
clos.SetEsc(clo.Esc())
// Force type conversion from *struct to the func type.
@ -475,7 +475,7 @@ func makepartialcall(dot ir.Node, t0 *types.Type, meth *types.Sym) *ir.Func {
body = append(body, ir.Nod(ir.OAS, ptr, cr))
} else {
ptr.SetType(types.NewPtr(rcvrtype))
body = append(body, ir.Nod(ir.OAS, ptr, ir.Nod(ir.OADDR, cr, nil)))
body = append(body, ir.Nod(ir.OAS, ptr, nodAddr(cr)))
}
call := ir.Nod(ir.OCALL, nodSym(ir.OXDOT, ptr, meth), nil)
@ -544,7 +544,7 @@ func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node {
clos.SetEsc(n.Esc())
clos.PtrList().Set2(ir.Nod(ir.OCFUNC, n.Func().Nname, nil), n.Left())
clos = ir.Nod(ir.OADDR, clos, nil)
clos = nodAddr(clos)
clos.SetEsc(n.Esc())
// Force type conversion from *struct to the func type.

View File

@ -943,8 +943,10 @@ func (r *importReader) node() ir.Node {
return n
// unary expressions
case ir.OPLUS, ir.ONEG, ir.OADDR, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
return ir.NodAt(r.pos(), op, r.expr(), nil)
case ir.OADDR:
return nodAddrAt(r.pos(), r.expr())
// binary expressions
case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,

View File

@ -878,7 +878,7 @@ func mkinlcall(n ir.Node, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool,
addr.SetType(types.NewPtr(v.Type()))
ia := typecheck(inlvar(addr), ctxExpr)
ninit.Append(ir.Nod(ir.ODCL, ia, nil))
ninit.Append(typecheck(ir.Nod(ir.OAS, ia, ir.Nod(ir.OADDR, o, nil)), ctxStmt))
ninit.Append(typecheck(ir.Nod(ir.OAS, ia, nodAddr(o)), ctxStmt))
inlvars[addr] = ia
// When capturing by reference, all occurrence of the captured var

View File

@ -274,7 +274,7 @@ func walkrange(nrange ir.Node) ir.Node {
hp := temp(types.NewPtr(nrange.Type().Elem()))
tmp := ir.Nod(ir.OINDEX, ha, nodintconst(0))
tmp.SetBounded(true)
init = append(init, ir.Nod(ir.OAS, hp, ir.Nod(ir.OADDR, tmp, nil)))
init = append(init, ir.Nod(ir.OAS, hp, nodAddr(tmp)))
// Use OAS2 to correctly handle assignments
// of the form "v1, a[v1] := range".
@ -305,12 +305,12 @@ func walkrange(nrange ir.Node) ir.Node {
fn := syslook("mapiterinit")
fn = substArgTypes(fn, t.Key(), t.Elem(), th)
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, ir.Nod(ir.OADDR, hit, nil)))
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, nodAddr(hit)))
nfor.SetLeft(ir.Nod(ir.ONE, nodSym(ir.ODOT, hit, keysym), nodnil()))
fn = syslook("mapiternext")
fn = substArgTypes(fn, th)
nfor.SetRight(mkcall1(fn, nil, nil, ir.Nod(ir.OADDR, hit, nil)))
nfor.SetRight(mkcall1(fn, nil, nil, nodAddr(hit)))
key := nodSym(ir.ODOT, hit, keysym)
key = ir.Nod(ir.ODEREF, key, nil)
@ -572,7 +572,7 @@ func arrayClear(loop, v1, v2, a ir.Node) ir.Node {
tmp := ir.Nod(ir.OINDEX, a, nodintconst(0))
tmp.SetBounded(true)
tmp = ir.Nod(ir.OADDR, tmp, nil)
tmp = nodAddr(tmp)
tmp = convnop(tmp, types.Types[types.TUNSAFEPTR])
n.PtrBody().Append(ir.Nod(ir.OAS, hp, tmp))

View File

@ -996,7 +996,7 @@ func typename(t *types.Type) ir.Node {
s.Def = n
}
n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
n := nodAddr(ir.AsNode(s.Def))
n.SetType(types.NewPtr(s.Def.Type()))
n.SetTypecheck(1)
return n
@ -1016,7 +1016,7 @@ func itabname(t, itype *types.Type) ir.Node {
itabs = append(itabs, itabEntry{t: t, itype: itype, lsym: s.Linksym()})
}
n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
n := nodAddr(ir.AsNode(s.Def))
n.SetType(types.NewPtr(s.Def.Type()))
n.SetTypecheck(1)
return n
@ -1880,7 +1880,7 @@ func zeroaddr(size int64) ir.Node {
x.SetTypecheck(1)
s.Def = x
}
z := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
z := nodAddr(ir.AsNode(s.Def))
z.SetType(types.NewPtr(types.Types[types.TUINT8]))
z.SetTypecheck(1)
return z

View File

@ -171,18 +171,18 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
switch n.Op() {
case ir.OSEND:
n.SetRight(ir.Nod(ir.OADDR, n.Right(), nil))
n.SetRight(nodAddr(n.Right()))
n.SetRight(typecheck(n.Right(), ctxExpr))
case ir.OSELRECV:
if !ir.IsBlank(n.Left()) {
n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil))
n.SetLeft(nodAddr(n.Left()))
n.SetLeft(typecheck(n.Left(), ctxExpr))
}
case ir.OSELRECV2:
if !ir.IsBlank(n.List().First()) {
n.List().SetIndex(0, ir.Nod(ir.OADDR, n.List().First(), nil))
n.List().SetIndex(0, nodAddr(n.List().First()))
n.List().SetIndex(0, typecheck(n.List().First(), ctxExpr))
}
}
@ -225,7 +225,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
if ir.IsBlank(elem) {
elem = nodnil()
}
receivedp := ir.Nod(ir.OADDR, n.List().Second(), nil)
receivedp := nodAddr(n.List().Second())
receivedp = typecheck(receivedp, ctxExpr)
call = mkcall1(chanfn("selectnbrecv2", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), elem, receivedp, ch)
}
@ -257,7 +257,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
var pc0, pcs ir.Node
if base.Flag.Race {
pcs = temp(types.NewArray(types.Types[types.TUINTPTR], int64(ncas)))
pc0 = typecheck(ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, pcs, nodintconst(0)), nil), ctxExpr)
pc0 = typecheck(nodAddr(ir.Nod(ir.OINDEX, pcs, nodintconst(0))), ctxExpr)
} else {
pc0 = nodnil()
}
@ -314,7 +314,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
// TODO(mdempsky): There should be a cleaner way to
// handle this.
if base.Flag.Race {
r = mkcall("selectsetpc", nil, nil, ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, pcs, nodintconst(int64(i))), nil))
r = mkcall("selectsetpc", nil, nil, nodAddr(ir.Nod(ir.OINDEX, pcs, nodintconst(int64(i)))))
init = append(init, r)
}
}
@ -372,7 +372,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
// bytePtrToIndex returns a Node representing "(*byte)(&n[i])".
func bytePtrToIndex(n ir.Node, i int64) ir.Node {
s := ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, n, nodintconst(i)), nil)
s := nodAddr(ir.Nod(ir.OINDEX, n, nodintconst(i)))
t := types.NewPtr(types.Types[types.TUINT8])
return convnop(s, t)
}

View File

@ -675,7 +675,7 @@ func slicelit(ctxt initContext, n ir.Node, var_ ir.Node, init *ir.Nodes) {
init.Append(ir.Nod(ir.OVARDEF, x, nil))
}
a = ir.Nod(ir.OADDR, x, nil)
a = nodAddr(x)
} else if n.Esc() == EscNone {
a = temp(t)
if vstat == nil {
@ -687,7 +687,7 @@ func slicelit(ctxt initContext, n ir.Node, var_ ir.Node, init *ir.Nodes) {
init.Append(ir.Nod(ir.OVARDEF, a, nil))
}
a = ir.Nod(ir.OADDR, a, nil)
a = nodAddr(a)
} else {
a = ir.Nod(ir.ONEW, ir.TypeNode(t), nil)
}
@ -888,7 +888,7 @@ func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
if n.Right() != nil {
// n.Right is stack temporary used as backing store.
init.Append(ir.Nod(ir.OAS, n.Right(), nil)) // zero backing store, just in case (#18410)
r = ir.Nod(ir.OADDR, n.Right(), nil)
r = nodAddr(n.Right())
r = typecheck(r, ctxExpr)
} else {
r = ir.Nod(ir.ONEW, ir.TypeNode(n.Left().Type()), nil)

View File

@ -135,6 +135,14 @@ func importdot(opkg *types.Pkg, pack *ir.PkgName) {
}
}
// nodAddr returns a node representing &n.
func nodAddr(n ir.Node) ir.Node {
return ir.Nod(ir.OADDR, n, nil)
}
func nodAddrAt(pos src.XPos, n ir.Node) ir.Node {
return ir.NodAt(pos, ir.OADDR, n, nil)
}
// newname returns a new ONAME Node associated with symbol s.
func NewName(s *types.Sym) *ir.Name {
n := ir.NewNameAt(base.Pos, s)
@ -1158,7 +1166,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
dot = dot.Left() // skip final .M
// TODO(mdempsky): Remove dependency on dotlist.
if !dotlist[0].field.Type.IsPtr() {
dot = ir.Nod(ir.OADDR, dot, nil)
dot = nodAddr(dot)
}
as := ir.Nod(ir.OAS, nthis, convnop(dot, rcvr))
fn.PtrBody().Append(as)

View File

@ -1274,7 +1274,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
return n
}
n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil))
n.SetLeft(nodAddr(n.Left()))
n.Left().SetImplicit(true)
n.SetLeft(typecheck(n.Left(), ctxExpr))
l = n.Left()
@ -2462,7 +2462,7 @@ func lookdot(n ir.Node, t *types.Type, dostrcmp int) *types.Field {
if !types.Identical(rcvr, tt) {
if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) {
checklvalue(n.Left(), "call pointer method on")
n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil))
n.SetLeft(nodAddr(n.Left()))
n.Left().SetImplicit(true)
n.SetLeft(typecheck(n.Left(), ctxType|ctxExpr))
} else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) {
@ -2747,7 +2747,7 @@ func pushtype(n ir.Node, t *types.Type) ir.Node {
// For *T, return &T{...}.
n.SetRight(ir.TypeNode(t.Elem()))
n = ir.NodAt(n.Pos(), ir.OADDR, n, nil)
n = nodAddrAt(n.Pos(), n)
n.SetImplicit(true)
}

View File

@ -615,7 +615,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
return mkcall("gopanic", nil, init, n.Left())
case ir.ORECOVER:
return mkcall("gorecover", n.Type(), init, ir.Nod(ir.OADDR, nodfp, nil))
return mkcall("gorecover", n.Type(), init, nodAddr(nodfp))
case ir.OCLOSUREREAD, ir.OCFUNC:
return n
@ -694,7 +694,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// order.stmt made sure x is addressable.
n.Right().SetLeft(walkexpr(n.Right().Left(), init))
n1 := ir.Nod(ir.OADDR, n.Left(), nil)
n1 := nodAddr(n.Left())
r := n.Right().Left() // the channel
return mkcall1(chanfn("chanrecv1", 2, r.Type()), nil, init, r, n1)
@ -767,7 +767,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if ir.IsBlank(n.List().First()) {
n1 = nodnil()
} else {
n1 = ir.Nod(ir.OADDR, n.List().First(), nil)
n1 = nodAddr(n.List().First())
}
fn := chanfn("chanrecv2", 2, r.Left().Type())
ok := n.List().Second()
@ -793,7 +793,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
} else {
// standard version takes key by reference
// order.expr made sure key is addressable.
key = ir.Nod(ir.OADDR, r.Right(), nil)
key = nodAddr(r.Right())
}
// from:
@ -846,7 +846,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
fast := mapfast(t)
if fast == mapslow {
// order.stmt made sure key is addressable.
key = ir.Nod(ir.OADDR, key, nil)
key = nodAddr(key)
}
return mkcall1(mapfndel(mapdelete[fast], t), nil, init, typename(t), map_, key)
@ -924,7 +924,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if value != nil {
// Value is identical to n.Left.
// Construct the interface directly: {type/itab, &value}.
l := ir.Nod(ir.OEFACE, typeword(), typecheck(ir.Nod(ir.OADDR, value, nil), ctxExpr))
l := ir.Nod(ir.OEFACE, typeword(), typecheck(nodAddr(value), ctxExpr))
l.SetType(toType)
l.SetTypecheck(n.Typecheck())
return l
@ -998,7 +998,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if !islvalue(v) {
v = copyexpr(v, v.Type(), init)
}
v = ir.Nod(ir.OADDR, v, nil)
v = nodAddr(v)
}
dowidth(fromType)
@ -1145,7 +1145,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if fast == mapslow {
// standard version takes key by reference.
// order.expr made sure key is addressable.
key = ir.Nod(ir.OADDR, key, nil)
key = nodAddr(key)
}
n = mkcall1(mapfn(mapassign[fast], t), nil, init, typename(t), map_, key)
} else {
@ -1154,7 +1154,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if fast == mapslow {
// standard version takes key by reference.
// order.expr made sure key is addressable.
key = ir.Nod(ir.OADDR, key, nil)
key = nodAddr(key)
}
if w := t.Elem().Width; w <= zeroValSize {
@ -1226,7 +1226,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
r = ir.Nod(ir.OAS, r, nil) // zero temp
r = typecheck(r, ctxStmt)
init.Append(r)
r = ir.Nod(ir.OADDR, r.Left(), nil)
r = nodAddr(r.Left())
return typecheck(r, ctxExpr)
}
return callnew(n.Type().Elem())
@ -1281,7 +1281,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
zero = typecheck(zero, ctxStmt)
init.Append(zero)
// h = &hv
h = ir.Nod(ir.OADDR, hv, nil)
h = nodAddr(hv)
// Allocate one bucket pointed to by hmap.buckets on stack if hint
// is not larger than BUCKETSIZE. In case hint is larger than
@ -1309,7 +1309,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
nif.PtrBody().Append(zero)
// b = &bv
b := ir.Nod(ir.OADDR, bv, nil)
b := nodAddr(bv)
// h.buckets = b
bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
@ -1515,7 +1515,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
a := nodnil()
if n.Esc() == EscNone {
t := types.NewArray(types.Types[types.TUINT8], 4)
a = ir.Nod(ir.OADDR, temp(t), nil)
a = nodAddr(temp(t))
}
// intstring(*[4]byte, rune)
return mkcall("intstring", n.Type(), init, a, conv(n.Left(), types.Types[types.TINT64]))
@ -1525,7 +1525,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if n.Esc() == EscNone {
// Create temporary buffer for string on stack.
t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
a = ir.Nod(ir.OADDR, temp(t), nil)
a = nodAddr(temp(t))
}
if n.Op() == ir.ORUNES2STR {
// slicerunetostring(*[32]byte, []rune) string
@ -1557,7 +1557,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
t := types.NewArray(types.Types[types.TUINT8], int64(len(sc)))
var a ir.Node
if n.Esc() == EscNone && len(sc) <= int(maxImplicitStackVarSize) {
a = ir.Nod(ir.OADDR, temp(t), nil)
a = nodAddr(temp(t))
} else {
a = callnew(t)
}
@ -1585,7 +1585,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if n.Esc() == EscNone {
// Create temporary buffer for slice on stack.
t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
a = ir.Nod(ir.OADDR, temp(t), nil)
a = nodAddr(temp(t))
}
// stringtoslicebyte(*32[byte], string) []byte
return mkcall("stringtoslicebyte", n.Type(), init, a, conv(s, types.Types[types.TSTRING]))
@ -1606,7 +1606,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if n.Esc() == EscNone {
// Create temporary buffer for slice on stack.
t := types.NewArray(types.Types[types.TINT32], tmpstringbufsize)
a = ir.Nod(ir.OADDR, temp(t), nil)
a = nodAddr(temp(t))
}
// stringtoslicerune(*[32]rune, string) []rune
return mkcall("stringtoslicerune", n.Type(), init, a, conv(n.Left(), types.Types[types.TSTRING]))
@ -1627,7 +1627,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
n1 := n.Right()
n1 = assignconv(n1, n.Left().Type().Elem(), "chan send")
n1 = walkexpr(n1, init)
n1 = ir.Nod(ir.OADDR, n1, nil)
n1 = nodAddr(n1)
return mkcall1(chanfn("chansend1", 2, n.Left().Type()), nil, init, n.Left(), n1)
case ir.OCLOSURE:
@ -2699,7 +2699,7 @@ func addstr(n ir.Node, init *ir.Nodes) ir.Node {
if sz < tmpstringbufsize {
// Create temporary buffer for result string on stack.
t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
buf = ir.Nod(ir.OADDR, temp(t), nil)
buf = nodAddr(temp(t))
}
}
@ -2842,7 +2842,7 @@ func appendslice(n ir.Node, init *ir.Nodes) ir.Node {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
nptr1.SetBounded(true)
nptr1 = ir.Nod(ir.OADDR, nptr1, nil)
nptr1 = nodAddr(nptr1)
nptr2 := ir.Nod(ir.OSPTR, l2, nil)
@ -2988,7 +2988,7 @@ func extendslice(n ir.Node, init *ir.Nodes) ir.Node {
// hp := &s[len(l1)]
hp := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
hp.SetBounded(true)
hp = ir.Nod(ir.OADDR, hp, nil)
hp = nodAddr(hp)
hp = convnop(hp, types.Types[types.TUNSAFEPTR])
// hn := l2 * sizeof(elem(s))
@ -3372,8 +3372,8 @@ func walkcompare(n ir.Node, init *ir.Nodes) ir.Node {
fn, needsize := eqfor(t)
call := ir.Nod(ir.OCALL, fn, nil)
call.PtrList().Append(ir.Nod(ir.OADDR, cmpl, nil))
call.PtrList().Append(ir.Nod(ir.OADDR, cmpr, nil))
call.PtrList().Append(nodAddr(cmpl))
call.PtrList().Append(nodAddr(cmpr))
if needsize {
call.PtrList().Append(nodintconst(t.Width))
}