golang/go

cmd/compile: unexpected memequal call in short string comparison

Open

#24,765 opened on Apr 8, 2018

View on GitHub
 (12 comments) (0 reactions) (0 assignees)Go (19,008 forks)batch import
NeedsFixPerformanceSuggestedcompiler/runtimehelp wanted

Repository metrics

Stars
 (133,883 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

(Using Go tip, 8818b4d27)

Compiling this code on amd64,

type BoxType [4]byte

func (t BoxType) EqualString(s string) bool {
        return string(t[:]) == s
}

I would expect that to compile to something pretty minimal, since the memory comparison must always be 4 bytes, but instead I see a call to memequal:

"".BoxType.EqualString STEXT size=103 args=0x20 locals=0x28
        0x0000 00000 (./bmff/bmff.go:62)        TEXT    "".BoxType.EqualString(SB), $40-32
        0x0000 00000 (./bmff/bmff.go:62)        MOVQ    (TLS), CX
        0x0009 00009 (./bmff/bmff.go:62)        CMPQ    SP, 16(CX)
        0x000d 00013 (./bmff/bmff.go:62)        JLS     96
        0x000f 00015 (./bmff/bmff.go:62)        SUBQ    $40, SP
        0x0013 00019 (./bmff/bmff.go:62)        MOVQ    BP, 32(SP)
        0x0018 00024 (./bmff/bmff.go:62)        LEAQ    32(SP), BP
        0x001d 00029 (./bmff/bmff.go:62)        FUNCDATA        $0, gclocals·a20105803dd226ab8faa525f9ceddf12(SB)
        0x001d 00029 (./bmff/bmff.go:62)        FUNCDATA        $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
        0x001d 00029 (./bmff/bmff.go:63)        MOVQ    "".s+64(SP), AX
        0x0022 00034 (./bmff/bmff.go:63)        CMPQ    AX, $4
        0x0026 00038 (./bmff/bmff.go:63)        JEQ     56
        0x0028 00040 (./bmff/bmff.go:63)        XORL    AX, AX
        0x002a 00042 (./bmff/bmff.go:63)        MOVB    AL, "".~r1+72(SP)
        0x002e 00046 (./bmff/bmff.go:63)        MOVQ    32(SP), BP
        0x0033 00051 (./bmff/bmff.go:63)        ADDQ    $40, SP
        0x0037 00055 (./bmff/bmff.go:63)        RET
        0x0038 00056 (./bmff/bmff.go:63)        LEAQ    "".t+48(SP), AX
        0x003d 00061 (./bmff/bmff.go:63)        MOVQ    AX, (SP)
        0x0041 00065 (./bmff/bmff.go:63)        MOVQ    "".s+56(SP), AX
        0x0046 00070 (./bmff/bmff.go:63)        MOVQ    AX, 8(SP)
        0x004b 00075 (./bmff/bmff.go:63)        MOVQ    $4, 16(SP)
        0x0054 00084 (./bmff/bmff.go:63)        PCDATA  $0, $1
        0x0054 00084 (./bmff/bmff.go:63)        CALL    runtime.memequal(SB)
        0x0059 00089 (./bmff/bmff.go:63)        MOVBLZX 24(SP), AX
        0x005e 00094 (./bmff/bmff.go:63)        JMP     42
        0x0060 00096 (./bmff/bmff.go:63)        NOP
        0x0060 00096 (./bmff/bmff.go:62)        PCDATA  $0, $-1
        0x0060 00096 (./bmff/bmff.go:62)        CALL    runtime.morestack_noctxt(SB)
        0x0065 00101 (./bmff/bmff.go:62)        JMP     0

Ideally we'd just do a 4 byte (potentially unaligned) load from the string into a register and compare with the receiver?

/cc @josharian @randall77 @rasky

Contributor guide