]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: clean up eq and hash implementations
authorKeith Randall <khr@golang.org>
Fri, 5 Dec 2025 22:20:00 +0000 (14:20 -0800)
committerKeith Randall <khr@golang.org>
Sat, 24 Jan 2026 04:58:20 +0000 (20:58 -0800)
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 <cuong.manhle.vn@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
src/cmd/compile/internal/compare/compare.go
src/cmd/compile/internal/reflectdata/alg.go
src/cmd/compile/internal/typecheck/_builtin/runtime.go
src/cmd/compile/internal/typecheck/builtin.go
src/cmd/compile/internal/walk/compare.go

index 638eb37a6221098ef8f999f349a1cb80e36134c8..11793fc85ba102c74210173f9ae665f2dd7b5456 100644 (file)
@@ -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)
index 872a37c21a7e71718afedd2391ffdb7702d8f513..b281b4c37f0fcc655b34c128d0410d464e969ef6 100644 (file)
@@ -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.
index a7603c3e33c69c868636139508ebaabb05203388..a1945ae1f46c53a039338bfeaa048df5545db04d 100644 (file)
@@ -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
index 955e65e5988420b8a1c0bf4513b62ce5a4e81973..82d0ca26b8936bdbca410d27640e4784ab64579b 100644 (file)
@@ -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[:]
 }
 
index 46adbce3fd82e269c3f102c4c9767ee7839563f0..445fbb0889b184d463c6362ef2ad4c870895acd9 100644 (file)
@@ -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()))
                }