Skip to content

cmd/compile: Go 1.27 regression in BigEndian.Uint32 load combining with array copy #81839

Closed

Description

@cespare

Go version

go version go1.27.1 linux/amd64

Output of go env in your module/workspace:

n/a

What did you do?

We noticed a substantial slowdown in microbenchmarks for a specialized hash table implementation.

Here's a minimized reproducer:

package slowload

import (
	"encoding/binary"
	"testing"
)

//go:noinline
func f(k [4]byte) uint32 {
	q := k
	return binary.BigEndian.Uint32(q[:])
}

func BenchmarkIndex(b *testing.B) {
	k := [4]byte{1, 2, 3, 4}
	for b.Loop() {
		f(k)
	}
}

What did you see happen?

There's a slowdown on amd64:

goos: linux
goarch: amd64
pkg: github.com/cespare/misc/slowload
cpu: AMD Ryzen 9 3900X 12-Core Processor
         │ amd64/126.txt │            amd64/127.txt            │
         │    sec/op     │   sec/op     vs base                │
Index-24     1.906n ± 3%   2.185n ± 3%  +14.66% (p=0.000 n=10)

If we look at the generated code, we see:

1.26.7:

  MOVL  0x4(SP), CX
  BSWAP CX

1.27.1:

  MOVZX 0x22(SP), BX
  ROLW  $0x8, BX
  MOVZX BX, BX
  MOVZX 0x21(SP), SI
  MOVQ  CX, 0x4(SP)
  MOVL  DX, 0xc(SP)
  SHLL  $0x10, SI
  ORL   SI, BX
  MOVZX 0x4(SP), CX
  SHLL  $0x18, CX
  ORL   BX, CX

On arm64 (my test machine is Graviton 5) we see a much more dramatic slowdown:

goos: linux
goarch: arm64
pkg: github.com/cespare/misc/slowload
         │ arm64/126.txt │            arm64/127.txt             │
         │    sec/op     │   sec/op     vs base                 │
Index-48     1.856n ± 0%   4.229n ± 1%  +127.86% (p=0.000 n=10)

The generated code:

1.26.7:

  MOVWU 40(RSP), R1
  MOVW  R1, 20(RSP)
  MOVWU 20(RSP), R1
  REVW  R1, R0

1.27.1:

  MOVWU  40(RSP), R1
  MOVHU  42(RSP), R2
  REV16W R2, R2
  UBFX   $0, R2, $16, R2
  MOVBU  41(RSP), R3
  MOVW   R1, 20(RSP)
  ORR    R3<<16, R2, R1
  MOVBU  20(RSP), R2
  ORR    R2<<24, R1, R0

What did you expect to see?

No regression.

The weird-looking array copy (q := k) is important. In our real code, the copy happens due to a function call.

I bisected this regression to CL 748200 ("cmd/compile: forward small Load through Move to avoid redundant copies"). Issue #80980 is also complaining about a regression from that CL (I'm not sure if this should be considered a dup of #80980 or not).

/cc @Dorbmon @randall77

Activity

  1. self-assigned this
    on Sep 29, 2026
  2. gopherbot commented on Sep 29, 2026

    @gopherbot
    Contributor

    Change https://go.dev/cl/841105 mentions this issue: cmd/compile: forward the whole of a copy's loads through a Move

  3. added
    FixPendingIssues that have a fix which has not yet been reviewed or submitted.
    on Oct 6, 2026
  4. added this to the Go1.28 milestone on Oct 6, 2026
  5. added a commit that references this issue on Oct 6, 2026
    bfc0f54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

FixPendingIssues that have a fix which has not yet been reviewed or submitted.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions