From cca64d0f5ccc6ae88d36ee5ef388b8617d4d425d Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Fri, 5 Dec 2025 14:20:00 -0800 Subject: [PATCH] cmd/compile: clean up eq and hash implementations Use unsafe.Pointer instead of *any as the argument type. Now that we're using signatures, we don't have exact types so we might as well use unsafe.Pointer everywhere. Simplify hash function choice a bit. Change-Id: If1a07091031c4b966fde3a1d66295a04fd5a838c Reviewed-on: https://go-review.googlesource.com/c/go/+/727501 Reviewed-by: Cuong Manh Le Reviewed-by: Dmitri Shuralyov LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall --- src/cmd/compile/internal/compare/compare.go | 6 +- src/cmd/compile/internal/reflectdata/alg.go | 90 +++------- .../internal/typecheck/_builtin/runtime.go | 30 ++-- src/cmd/compile/internal/typecheck/builtin.go | 166 +++++++++--------- src/cmd/compile/internal/walk/compare.go | 11 +- 5 files changed, 129 insertions(+), 174 deletions(-) diff --git a/src/cmd/compile/internal/compare/compare.go b/src/cmd/compile/internal/compare/compare.go index 638eb37a62..11793fc85b 100644 --- a/src/cmd/compile/internal/compare/compare.go +++ b/src/cmd/compile/internal/compare/compare.go @@ -257,8 +257,8 @@ func EqStruct(t *types.Type, np, nq ir.Node) ([]ir.Node, bool) { func EqString(s, t ir.Node) (eqlen *ir.BinaryExpr, eqmem *ir.CallExpr) { s = typecheck.Conv(s, types.Types[types.TSTRING]) t = typecheck.Conv(t, types.Types[types.TSTRING]) - sptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, s) - tptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, t) + sptr := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], ir.NewUnaryExpr(base.Pos, ir.OSPTR, s)) + tptr := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], ir.NewUnaryExpr(base.Pos, ir.OSPTR, t)) slen := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, s), types.Types[types.TUINTPTR]) tlen := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, t), types.Types[types.TUINTPTR]) @@ -293,7 +293,7 @@ func EqString(s, t ir.Node) (eqlen *ir.BinaryExpr, eqmem *ir.CallExpr) { cmplen = tlen } - fn := typecheck.LookupRuntime("memequal", types.Types[types.TUINT8], types.Types[types.TUINT8]) + fn := typecheck.LookupRuntime("memequal") call := typecheck.Call(base.Pos, fn, []ir.Node{sptr, tptr, ir.Copy(cmplen)}, false).(*ir.CallExpr) cmp := ir.NewBinaryExpr(base.Pos, ir.OEQ, slen, tlen) diff --git a/src/cmd/compile/internal/reflectdata/alg.go b/src/cmd/compile/internal/reflectdata/alg.go index 872a37c21a..b281b4c37f 100644 --- a/src/cmd/compile/internal/reflectdata/alg.go +++ b/src/cmd/compile/internal/reflectdata/alg.go @@ -154,20 +154,19 @@ func hashFunc(sig string) *ir.Func { // offset from np that we're currently working on var off int64 - // Return np+off cast to a t (t must be a pointer-y type). - ptr := func(t *types.Type) ir.Node { + // Return np+off (as an unsafe.Pointer). + ptr := func() ir.Node { c := ir.NewBasicLit(pos, types.Types[types.TUINTPTR], constant.MakeInt64(off)) - p := ir.NewBinaryExpr(pos, ir.OUNSAFEADD, np, c) - return ir.NewConvExpr(pos, ir.OCONVNOP, t, p) + return ir.NewBinaryExpr(pos, ir.OUNSAFEADD, np, c) } - // hash data of type t at np+off. - // Increment off by the size of t. - hash := func(t *types.Type) { - p := ptr(t.PtrTo()) - hashFn := hashfor(t) + // hash data using function name at np+off. + // Increment off by size. + hash := func(name string, size int64) { + p := ptr() + hashFn := typecheck.LookupRuntime(name) call := ir.NewCallExpr(pos, ir.OCALL, hashFn, []ir.Node{p, nh}) fn.Body.Append(ir.NewAssignStmt(pos, nh, call)) - off += t.Size() + off += size } for len(sig) > 0 { @@ -179,34 +178,33 @@ func hashFunc(sig string) *ir.Func { n, sig = parseNum(sig) switch { case n == 4: - p := ptr(types.Types[types.TUNSAFEPTR]) + p := ptr() memhash := typecheck.LookupRuntime("memhash32") call := ir.NewCallExpr(pos, ir.OCALL, memhash, []ir.Node{p, nh}) fn.Body.Append(ir.NewAssignStmt(pos, nh, call)) case n == 8: - p := ptr(types.Types[types.TUNSAFEPTR]) + p := ptr() memhash := typecheck.LookupRuntime("memhash64") call := ir.NewCallExpr(pos, ir.OCALL, memhash, []ir.Node{p, nh}) fn.Body.Append(ir.NewAssignStmt(pos, nh, call)) default: - p := ptr(types.Types[types.TUINT8].PtrTo()) - memhash := typecheck.LookupRuntime("memhash", types.Types[types.TUINT8]) + p := ptr() + memhash := typecheck.LookupRuntime("memhash") size := ir.NewBasicLit(pos, types.Types[types.TUINTPTR], constant.MakeInt64(n)) call := ir.NewCallExpr(pos, ir.OCALL, memhash, []ir.Node{p, nh, size}) fn.Body.Append(ir.NewAssignStmt(pos, nh, call)) } off += n case sigFloat32: - hash(types.Types[types.TFLOAT32]) + hash("f32hash", 4) case sigFloat64: - hash(types.Types[types.TFLOAT64]) + hash("f64hash", 8) case sigString: - hash(types.Types[types.TSTRING]) + hash("strhash", 2*int64(types.PtrSize)) case sigEface: - hash(types.NewInterface(nil)) + hash("nilinterhash", 2*int64(types.PtrSize)) case sigIface: - // arg kinda hacky. TODO: clean this up. - hash(types.NewInterface([]*types.Field{types.NewField(pos, typecheck.Lookup("A"), types.Types[types.TBOOL])})) + hash("interhash", 2*int64(types.PtrSize)) case sigSkip: var n int64 n, sig = parseNum(sig) @@ -274,33 +272,6 @@ func hashFunc(sig string) *ir.Func { return fn } -func runtimeHashFor(name string, t *types.Type) *ir.Name { - return typecheck.LookupRuntime(name, t) -} - -// hashfor returns the function to compute the hash of a value of type t. -func hashfor(t *types.Type) *ir.Name { - switch types.AlgType(t) { - default: - base.Fatalf("hashfor with bad type %v", t) - return nil - case types.AINTER: - return runtimeHashFor("interhash", t) - case types.ANILINTER: - return runtimeHashFor("nilinterhash", t) - case types.ASTRING: - return runtimeHashFor("strhash", t) - case types.AFLOAT32: - return runtimeHashFor("f32hash", t) - case types.AFLOAT64: - return runtimeHashFor("f64hash", t) - case types.ACPLX64: - return runtimeHashFor("c64hash", t) - case types.ACPLX128: - return runtimeHashFor("c128hash", t) - } -} - // sysClosure returns a closure which will call the // given runtime function (with no closed-over variables). func sysClosure(name string) *obj.LSym { @@ -483,13 +454,12 @@ func eqFunc(sig string) *ir.Func { defer func(saveOff int64) { off = saveOff }(off) - byte := types.Types[types.TUINT8] for _, x := range pendingStrings { off = x - ptrA, ptrB := load(byte.PtrTo()) + ptrA, ptrB := load(types.Types[types.TUNSAFEPTR]) len, _ := load(types.Types[types.TUINTPTR]) // Note: we already checked that the lengths are equal. - memeq := typecheck.LookupRuntime("memequal", byte, byte) + memeq := typecheck.LookupRuntime("memequal") test(typecheck.Call(pos, memeq, []ir.Node{ptrA, ptrB, len}, false)) hasCall = true } @@ -509,11 +479,8 @@ func eqFunc(sig string) *ir.Func { p := ir.NewBinaryExpr(pos, ir.OUNSAFEADD, np, c) q := ir.NewBinaryExpr(pos, ir.OUNSAFEADD, nq, c) len := ir.NewBasicLit(pos, types.Types[types.TUINTPTR], constant.MakeInt64(n)) - byte := types.Types[types.TUINT8] - p2 := ir.NewConvExpr(pos, ir.OCONVNOP, byte.PtrTo(), p) - q2 := ir.NewConvExpr(pos, ir.OCONVNOP, byte.PtrTo(), q) - memeq := typecheck.LookupRuntime("memequal", byte, byte) - test(typecheck.Call(pos, memeq, []ir.Node{p2, q2, len}, false)) + memeq := typecheck.LookupRuntime("memequal") + test(typecheck.Call(pos, memeq, []ir.Node{p, q, len}, false)) hasCall = true off += n n = 0 @@ -688,21 +655,16 @@ func eqFunc(sig string) *ir.Func { // EqFor returns ONAME node represents type t's equal function, and a boolean // to indicates whether a length needs to be passed when calling the function. -// Also returns the argument type of the function (TODO: remove somehow). -func EqFor(t *types.Type) (ir.Node, bool, *types.Type) { +func EqFor(t *types.Type) (ir.Node, bool) { switch types.AlgType(t) { case types.AMEM: - return typecheck.LookupRuntime("memequal", t, t), true, t.PtrTo() + return typecheck.LookupRuntime("memequal"), true case types.ASPECIAL: fn := eqFunc(eqSignature(t)) - return fn.Nname, false, types.Types[types.TUNSAFEPTR] + return fn.Nname, false } base.Fatalf("EqFor %v", t) - return nil, false, nil -} - -func hashmem(t *types.Type) ir.Node { - return typecheck.LookupRuntime("memhash", t) + return nil, false } // eqSignature returns a signature of the equality function for type t. diff --git a/src/cmd/compile/internal/typecheck/_builtin/runtime.go b/src/cmd/compile/internal/typecheck/_builtin/runtime.go index a7603c3e33..a1945ae1f4 100644 --- a/src/cmd/compile/internal/typecheck/_builtin/runtime.go +++ b/src/cmd/compile/internal/typecheck/_builtin/runtime.go @@ -215,13 +215,13 @@ func memmove(to *any, frm *any, length uintptr) func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) func memclrHasPointers(ptr unsafe.Pointer, n uintptr) -func memequal(x, y *any, size uintptr) bool -func memequal0(x, y *any) bool -func memequal8(x, y *any) bool -func memequal16(x, y *any) bool -func memequal32(x, y *any) bool -func memequal64(x, y *any) bool -func memequal128(x, y *any) bool +func memequal(x, y unsafe.Pointer, size uintptr) bool +func memequal0(x, y unsafe.Pointer) bool +func memequal8(x, y unsafe.Pointer) bool +func memequal16(x, y unsafe.Pointer) bool +func memequal32(x, y unsafe.Pointer) bool +func memequal64(x, y unsafe.Pointer) bool +func memequal128(x, y unsafe.Pointer) bool func f32equal(p, q unsafe.Pointer) bool func f64equal(p, q unsafe.Pointer) bool func c64equal(p, q unsafe.Pointer) bool @@ -230,20 +230,20 @@ func strequal(p, q unsafe.Pointer) bool func interequal(p, q unsafe.Pointer) bool func nilinterequal(p, q unsafe.Pointer) bool -func memhash(x *any, h uintptr, size uintptr) uintptr +func memhash(x unsafe.Pointer, h uintptr, size uintptr) uintptr func memhash0(p unsafe.Pointer, h uintptr) uintptr func memhash8(p unsafe.Pointer, h uintptr) uintptr func memhash16(p unsafe.Pointer, h uintptr) uintptr func memhash32(p unsafe.Pointer, h uintptr) uintptr func memhash64(p unsafe.Pointer, h uintptr) uintptr func memhash128(p unsafe.Pointer, h uintptr) uintptr -func f32hash(p *any, h uintptr) uintptr -func f64hash(p *any, h uintptr) uintptr -func c64hash(p *any, h uintptr) uintptr -func c128hash(p *any, h uintptr) uintptr -func strhash(a *any, h uintptr) uintptr -func interhash(p *any, h uintptr) uintptr -func nilinterhash(p *any, h uintptr) uintptr +func f32hash(p unsafe.Pointer, h uintptr) uintptr +func f64hash(p unsafe.Pointer, h uintptr) uintptr +func c64hash(p unsafe.Pointer, h uintptr) uintptr +func c128hash(p unsafe.Pointer, h uintptr) uintptr +func strhash(a unsafe.Pointer, h uintptr) uintptr +func interhash(p unsafe.Pointer, h uintptr) uintptr +func nilinterhash(p unsafe.Pointer, h uintptr) uintptr // only used on 32-bit func int64div(int64, int64) int64 diff --git a/src/cmd/compile/internal/typecheck/builtin.go b/src/cmd/compile/internal/typecheck/builtin.go index 955e65e598..82d0ca26b8 100644 --- a/src/cmd/compile/internal/typecheck/builtin.go +++ b/src/cmd/compile/internal/typecheck/builtin.go @@ -184,64 +184,64 @@ var runtimeDecls = [...]struct { {"memequal32", funcTag, 138}, {"memequal64", funcTag, 138}, {"memequal128", funcTag, 138}, - {"f32equal", funcTag, 139}, - {"f64equal", funcTag, 139}, - {"c64equal", funcTag, 139}, - {"c128equal", funcTag, 139}, - {"strequal", funcTag, 139}, - {"interequal", funcTag, 139}, - {"nilinterequal", funcTag, 139}, - {"memhash", funcTag, 140}, - {"memhash0", funcTag, 141}, - {"memhash8", funcTag, 141}, - {"memhash16", funcTag, 141}, - {"memhash32", funcTag, 141}, - {"memhash64", funcTag, 141}, - {"memhash128", funcTag, 141}, - {"f32hash", funcTag, 142}, - {"f64hash", funcTag, 142}, - {"c64hash", funcTag, 142}, - {"c128hash", funcTag, 142}, - {"strhash", funcTag, 142}, - {"interhash", funcTag, 142}, - {"nilinterhash", funcTag, 142}, - {"int64div", funcTag, 143}, - {"uint64div", funcTag, 144}, - {"int64mod", funcTag, 143}, - {"uint64mod", funcTag, 144}, - {"float64toint64", funcTag, 145}, - {"float64touint64", funcTag, 146}, - {"float64touint32", funcTag, 147}, - {"int64tofloat64", funcTag, 148}, - {"int64tofloat32", funcTag, 149}, - {"uint64tofloat64", funcTag, 150}, - {"uint64tofloat32", funcTag, 151}, - {"uint32tofloat64", funcTag, 152}, - {"complex128div", funcTag, 153}, + {"f32equal", funcTag, 138}, + {"f64equal", funcTag, 138}, + {"c64equal", funcTag, 138}, + {"c128equal", funcTag, 138}, + {"strequal", funcTag, 138}, + {"interequal", funcTag, 138}, + {"nilinterequal", funcTag, 138}, + {"memhash", funcTag, 139}, + {"memhash0", funcTag, 140}, + {"memhash8", funcTag, 140}, + {"memhash16", funcTag, 140}, + {"memhash32", funcTag, 140}, + {"memhash64", funcTag, 140}, + {"memhash128", funcTag, 140}, + {"f32hash", funcTag, 140}, + {"f64hash", funcTag, 140}, + {"c64hash", funcTag, 140}, + {"c128hash", funcTag, 140}, + {"strhash", funcTag, 140}, + {"interhash", funcTag, 140}, + {"nilinterhash", funcTag, 140}, + {"int64div", funcTag, 141}, + {"uint64div", funcTag, 142}, + {"int64mod", funcTag, 141}, + {"uint64mod", funcTag, 142}, + {"float64toint64", funcTag, 143}, + {"float64touint64", funcTag, 144}, + {"float64touint32", funcTag, 145}, + {"int64tofloat64", funcTag, 146}, + {"int64tofloat32", funcTag, 147}, + {"uint64tofloat64", funcTag, 148}, + {"uint64tofloat32", funcTag, 149}, + {"uint32tofloat64", funcTag, 150}, + {"complex128div", funcTag, 151}, {"racefuncenter", funcTag, 33}, {"racefuncexit", funcTag, 9}, {"raceread", funcTag, 33}, {"racewrite", funcTag, 33}, - {"racereadrange", funcTag, 154}, - {"racewriterange", funcTag, 154}, - {"msanread", funcTag, 154}, - {"msanwrite", funcTag, 154}, - {"msanmove", funcTag, 155}, - {"asanread", funcTag, 154}, - {"asanwrite", funcTag, 154}, - {"checkptrAlignment", funcTag, 156}, - {"checkptrArithmetic", funcTag, 158}, - {"libfuzzerTraceCmp1", funcTag, 159}, - {"libfuzzerTraceCmp2", funcTag, 160}, - {"libfuzzerTraceCmp4", funcTag, 161}, - {"libfuzzerTraceCmp8", funcTag, 162}, - {"libfuzzerTraceConstCmp1", funcTag, 159}, - {"libfuzzerTraceConstCmp2", funcTag, 160}, - {"libfuzzerTraceConstCmp4", funcTag, 161}, - {"libfuzzerTraceConstCmp8", funcTag, 162}, - {"libfuzzerHookStrCmp", funcTag, 163}, - {"libfuzzerHookEqualFold", funcTag, 163}, - {"addCovMeta", funcTag, 165}, + {"racereadrange", funcTag, 152}, + {"racewriterange", funcTag, 152}, + {"msanread", funcTag, 152}, + {"msanwrite", funcTag, 152}, + {"msanmove", funcTag, 153}, + {"asanread", funcTag, 152}, + {"asanwrite", funcTag, 152}, + {"checkptrAlignment", funcTag, 154}, + {"checkptrArithmetic", funcTag, 156}, + {"libfuzzerTraceCmp1", funcTag, 157}, + {"libfuzzerTraceCmp2", funcTag, 158}, + {"libfuzzerTraceCmp4", funcTag, 159}, + {"libfuzzerTraceCmp8", funcTag, 160}, + {"libfuzzerTraceConstCmp1", funcTag, 157}, + {"libfuzzerTraceConstCmp2", funcTag, 158}, + {"libfuzzerTraceConstCmp4", funcTag, 159}, + {"libfuzzerTraceConstCmp8", funcTag, 160}, + {"libfuzzerHookStrCmp", funcTag, 161}, + {"libfuzzerHookEqualFold", funcTag, 161}, + {"addCovMeta", funcTag, 163}, {"x86HasAVX", varTag, 6}, {"x86HasFMA", varTag, 6}, {"x86HasPOPCNT", varTag, 6}, @@ -257,7 +257,7 @@ var runtimeDecls = [...]struct { } func runtimeTypes() []*types.Type { - var typs [166]*types.Type + var typs [164]*types.Type typs[0] = types.ByteType typs[1] = types.NewPtr(typs[0]) typs[2] = types.Types[types.TANY] @@ -395,35 +395,33 @@ func runtimeTypes() []*types.Type { typs[134] = newSig(params(typs[5], typs[1], typs[13]), params(typs[1], typs[13], typs[13])) typs[135] = newSig(params(typs[3], typs[3], typs[5]), nil) typs[136] = newSig(params(typs[7], typs[5]), nil) - typs[137] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6])) - typs[138] = newSig(params(typs[3], typs[3]), params(typs[6])) - typs[139] = newSig(params(typs[7], typs[7]), params(typs[6])) - typs[140] = newSig(params(typs[3], typs[5], typs[5]), params(typs[5])) - typs[141] = newSig(params(typs[7], typs[5]), params(typs[5])) - typs[142] = newSig(params(typs[3], typs[5]), params(typs[5])) - typs[143] = newSig(params(typs[22], typs[22]), params(typs[22])) - typs[144] = newSig(params(typs[24], typs[24]), params(typs[24])) - typs[145] = newSig(params(typs[18]), params(typs[22])) - typs[146] = newSig(params(typs[18]), params(typs[24])) - typs[147] = newSig(params(typs[18]), params(typs[67])) - typs[148] = newSig(params(typs[22]), params(typs[18])) - typs[149] = newSig(params(typs[22]), params(typs[20])) - typs[150] = newSig(params(typs[24]), params(typs[18])) - typs[151] = newSig(params(typs[24]), params(typs[20])) - typs[152] = newSig(params(typs[67]), params(typs[18])) - typs[153] = newSig(params(typs[26], typs[26]), params(typs[26])) - typs[154] = newSig(params(typs[5], typs[5]), nil) - typs[155] = newSig(params(typs[5], typs[5], typs[5]), nil) - typs[156] = newSig(params(typs[7], typs[1], typs[5]), nil) - typs[157] = types.NewSlice(typs[7]) - typs[158] = newSig(params(typs[7], typs[157]), nil) - typs[159] = newSig(params(typs[71], typs[71], typs[15]), nil) - typs[160] = newSig(params(typs[65], typs[65], typs[15]), nil) - typs[161] = newSig(params(typs[67], typs[67], typs[15]), nil) - typs[162] = newSig(params(typs[24], typs[24], typs[15]), nil) - typs[163] = newSig(params(typs[30], typs[30], typs[15]), nil) - typs[164] = types.NewArray(typs[0], 16) - typs[165] = newSig(params(typs[7], typs[67], typs[164], typs[30], typs[13], typs[71], typs[71]), params(typs[67])) + typs[137] = newSig(params(typs[7], typs[7], typs[5]), params(typs[6])) + typs[138] = newSig(params(typs[7], typs[7]), params(typs[6])) + typs[139] = newSig(params(typs[7], typs[5], typs[5]), params(typs[5])) + typs[140] = newSig(params(typs[7], typs[5]), params(typs[5])) + typs[141] = newSig(params(typs[22], typs[22]), params(typs[22])) + typs[142] = newSig(params(typs[24], typs[24]), params(typs[24])) + typs[143] = newSig(params(typs[18]), params(typs[22])) + typs[144] = newSig(params(typs[18]), params(typs[24])) + typs[145] = newSig(params(typs[18]), params(typs[67])) + typs[146] = newSig(params(typs[22]), params(typs[18])) + typs[147] = newSig(params(typs[22]), params(typs[20])) + typs[148] = newSig(params(typs[24]), params(typs[18])) + typs[149] = newSig(params(typs[24]), params(typs[20])) + typs[150] = newSig(params(typs[67]), params(typs[18])) + typs[151] = newSig(params(typs[26], typs[26]), params(typs[26])) + typs[152] = newSig(params(typs[5], typs[5]), nil) + typs[153] = newSig(params(typs[5], typs[5], typs[5]), nil) + typs[154] = newSig(params(typs[7], typs[1], typs[5]), nil) + typs[155] = types.NewSlice(typs[7]) + typs[156] = newSig(params(typs[7], typs[155]), nil) + typs[157] = newSig(params(typs[71], typs[71], typs[15]), nil) + typs[158] = newSig(params(typs[65], typs[65], typs[15]), nil) + typs[159] = newSig(params(typs[67], typs[67], typs[15]), nil) + typs[160] = newSig(params(typs[24], typs[24], typs[15]), nil) + typs[161] = newSig(params(typs[30], typs[30], typs[15]), nil) + typs[162] = types.NewArray(typs[0], 16) + typs[163] = newSig(params(typs[7], typs[67], typs[162], typs[30], typs[13], typs[71], typs[71]), params(typs[67])) return typs[:] } diff --git a/src/cmd/compile/internal/walk/compare.go b/src/cmd/compile/internal/walk/compare.go index 46adbce3fd..445fbb0889 100644 --- a/src/cmd/compile/internal/walk/compare.go +++ b/src/cmd/compile/internal/walk/compare.go @@ -190,7 +190,7 @@ func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { // a struct/array containing a non-memory field/element. // Small memory is handled inline, and single non-memory // is handled by walkCompare. - fn, needsLength, ptrType := reflectdata.EqFor(t) + fn, needsLength := reflectdata.EqFor(t) call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, nil) addrCmpL := typecheck.NodAddr(cmpl) addrCmpR := typecheck.NodAddr(cmpr) @@ -202,13 +202,8 @@ func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { call.PtrInit().Append(mkcall1(raceFn, nil, init, ptrL, size)) call.PtrInit().Append(mkcall1(raceFn, nil, init, ptrR, size)) } - if ptrType != t.PtrTo() { - call.Args.Append(typecheck.Conv(typecheck.Conv(addrCmpL, types.Types[types.TUNSAFEPTR]), ptrType)) - call.Args.Append(typecheck.Conv(typecheck.Conv(addrCmpR, types.Types[types.TUNSAFEPTR]), ptrType)) - } else { - call.Args.Append(addrCmpL) - call.Args.Append(addrCmpR) - } + call.Args.Append(typecheck.Conv(addrCmpL, types.Types[types.TUNSAFEPTR])) + call.Args.Append(typecheck.Conv(addrCmpR, types.Types[types.TUNSAFEPTR])) if needsLength { call.Args.Append(ir.NewInt(base.Pos, t.Size())) } -- 2.52.0