Skip to content

cmd/compile: suboptimal bits.Rotate* on arm64 #48465

@greatroar

Description

@greatroar

What version of Go are you using (go version)?

$ go version
go version go1.17.1 linux/amd64

Does this issue reproduce with the latest release?

Reproduces with

$ gotip version
go version devel go1.18-771b8ea4f4c Sun Sep 19 02:43:09 2021 +0000 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH=arm64

What did you do?

func rotxor1(x, y uint64) uint64 {
	y = (y << 7) | (y >> 57)
	return x ^ y
}

func rotxor2(x, y uint64) uint64 {
	return x ^ bits.RotateLeft64(y, 7)
}

What did you expect to see?

Would have been nice to see a fused rotate-xor (#48002), but at least the generated asm should be the same.

What did you see instead?

For rotxor1:

MOVD	"".y+8(FP), R0
ROR	$57, R0, R0
MOVD	"".x(FP), R1
EOR	R0, R1, R0

For rotxor2:

MOVD	"".y+8(FP), R0
MOVD	$-7, R1
ROR	R1, R0, R0
MOVD	"".x(FP), R1
EOR	R0, R1, R0

The compiler inserts a mov and allocates a register for the shift constant when the intrinsic is used. This is a regression introduced in Go 1.12. It's not limited to these tiny functions: I spotted this when inspecting the generated asm for SipHash.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions