Skip to content

cmd/compile: optimize code in the encoding/binary package #51724

@perillo

Description

@perillo

The encoding/binary package uses portable bit operations to read and write integers.

Using the program:

package test

func readUint64BigEndian(b []byte) uint64 {
	_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808

	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
}

and building with:

GOAMD64=v3 go1.18 build -o test.o test.go

the resulting assembly is:

SUBQ $0x18, SP		
MOVQ BP, 0x10(SP)	
LEAQ 0x10(SP), BP	
MOVQ AX, 0x20(SP)	
CMPQ $0x7, BX		
JBE 0x9ac		
MOVBE 0(AX), AX		
MOVQ 0x10(SP), BP	
ADDQ $0x18, SP		
RET			
MOVL $0x7, AX		
MOVQ BX, CX		
CALL 0x9b9		[1:5]R_CALL:runtime.panicIndex	
NOPL

The Zig compiler, with the same code and ReleaseSafe build mode, is able to generate the assembly:

movbe   rax, qword ptr [rdi]
ret

See https://godbolt.org/z/MPbE3P9j8.

Note that the movbe instruction was added in AMD64 v3 (https://en.wikipedia.org/wiki/X86-64).

Zig currently uses the LLVM backend, so I don't know if the cost/complexity of this optimization is high.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions