cmd/compile: use HasPointers in memcombine to match write barrier check

The memcombine load+store combining used IsPtr() to check for pointer
loads, but IsPtr() only matches regular Go pointers (*T) and explicitly
excludes unsafe.Pointer. This could allow memcombine to combine an
unsafe.Pointer field with an adjacent non-pointer field into a single
wide load+store, bypassing write barriers.

Fix by using HasPointers(), which is the same check that needwb in
writebarrier.go uses to decide whether a store needs a write barrier.

For #63131

Change-Id: Ica4b619cab8d4dbed57bb80d08a50bfd42a4e41a
Reviewed-on: https://go-review.googlesource.com/c/go/+/746380
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Carlos Amedee <carlos@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
This commit is contained in:
Jelle van den Hooff 2026-02-16 23:16:38 -08:00 committed by Gopher Robot
parent 7bb9bc64d0
commit deaf3e6789

View file

@ -626,11 +626,10 @@ func combineStores(root *Value) {
loadMem = nil
break
}
if load.Type.IsPtr() {
if load.Type.HasPointers() {
// Don't combine stores containing a pointer, as we need
// a write barrier for those. This can't currently happen,
// but might in the future if we ever have another
// 8-byte-reg/4-byte-ptr architecture like amd64p32.
// a write barrier for those. This can happen on an
// 8-byte-reg/4-byte-ptr architecture like wasm32.
loadMem = nil
break
}