mirror of
https://github.com/golang/go
synced 2024-11-22 03:14:41 -07:00
cmd/compile: pull multiple adds out of an unsafe.Pointer<->uintptr conversion
This came up in some swissmap code. Change-Id: I3c6705a5cafec8cb4953dfa9535cf0b45255cc83 Reviewed-on: https://go-review.googlesource.com/c/go/+/629516 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
fab2b8b0fa
commit
f0b0109242
@ -988,6 +988,9 @@
|
||||
// Get rid of Convert ops for pointer arithmetic on unsafe.Pointer.
|
||||
(Convert (Add(64|32) (Convert ptr mem) off) mem) => (AddPtr ptr off)
|
||||
(Convert (Convert ptr mem) mem) => ptr
|
||||
// Note: it is important that the target rewrite is ptr+(off1+off2), not (ptr+off1)+off2.
|
||||
// We must ensure that no intermediate computations are invalid pointers.
|
||||
(Convert a:(Add(64|32) (Add(64|32) (Convert ptr mem) off1) off2) mem) => (AddPtr ptr (Add(64|32) <a.Type> off1 off2))
|
||||
|
||||
// strength reduction of divide by a constant.
|
||||
// See ../magic.go for a detailed description of these algorithms.
|
||||
|
@ -5759,6 +5759,7 @@ func rewriteValuegeneric_OpConstString(v *Value) bool {
|
||||
func rewriteValuegeneric_OpConvert(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
// match: (Convert (Add64 (Convert ptr mem) off) mem)
|
||||
// result: (AddPtr ptr off)
|
||||
for {
|
||||
@ -5823,6 +5824,80 @@ func rewriteValuegeneric_OpConvert(v *Value) bool {
|
||||
v.copyOf(ptr)
|
||||
return true
|
||||
}
|
||||
// match: (Convert a:(Add64 (Add64 (Convert ptr mem) off1) off2) mem)
|
||||
// result: (AddPtr ptr (Add64 <a.Type> off1 off2))
|
||||
for {
|
||||
a := v_0
|
||||
if a.Op != OpAdd64 {
|
||||
break
|
||||
}
|
||||
_ = a.Args[1]
|
||||
a_0 := a.Args[0]
|
||||
a_1 := a.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, a_0, a_1 = _i0+1, a_1, a_0 {
|
||||
if a_0.Op != OpAdd64 {
|
||||
continue
|
||||
}
|
||||
_ = a_0.Args[1]
|
||||
a_0_0 := a_0.Args[0]
|
||||
a_0_1 := a_0.Args[1]
|
||||
for _i1 := 0; _i1 <= 1; _i1, a_0_0, a_0_1 = _i1+1, a_0_1, a_0_0 {
|
||||
if a_0_0.Op != OpConvert {
|
||||
continue
|
||||
}
|
||||
mem := a_0_0.Args[1]
|
||||
ptr := a_0_0.Args[0]
|
||||
off1 := a_0_1
|
||||
off2 := a_1
|
||||
if mem != v_1 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpAddPtr)
|
||||
v0 := b.NewValue0(v.Pos, OpAdd64, a.Type)
|
||||
v0.AddArg2(off1, off2)
|
||||
v.AddArg2(ptr, v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// match: (Convert a:(Add32 (Add32 (Convert ptr mem) off1) off2) mem)
|
||||
// result: (AddPtr ptr (Add32 <a.Type> off1 off2))
|
||||
for {
|
||||
a := v_0
|
||||
if a.Op != OpAdd32 {
|
||||
break
|
||||
}
|
||||
_ = a.Args[1]
|
||||
a_0 := a.Args[0]
|
||||
a_1 := a.Args[1]
|
||||
for _i0 := 0; _i0 <= 1; _i0, a_0, a_1 = _i0+1, a_1, a_0 {
|
||||
if a_0.Op != OpAdd32 {
|
||||
continue
|
||||
}
|
||||
_ = a_0.Args[1]
|
||||
a_0_0 := a_0.Args[0]
|
||||
a_0_1 := a_0.Args[1]
|
||||
for _i1 := 0; _i1 <= 1; _i1, a_0_0, a_0_1 = _i1+1, a_0_1, a_0_0 {
|
||||
if a_0_0.Op != OpConvert {
|
||||
continue
|
||||
}
|
||||
mem := a_0_0.Args[1]
|
||||
ptr := a_0_0.Args[0]
|
||||
off1 := a_0_1
|
||||
off2 := a_1
|
||||
if mem != v_1 {
|
||||
continue
|
||||
}
|
||||
v.reset(OpAddPtr)
|
||||
v0 := b.NewValue0(v.Pos, OpAdd32, a.Type)
|
||||
v0.AddArg2(off1, off2)
|
||||
v.AddArg2(ptr, v0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpCtz16(v *Value) bool {
|
||||
|
16
test/codegen/unsafe.go
Normal file
16
test/codegen/unsafe.go
Normal file
@ -0,0 +1,16 @@
|
||||
// asmcheck
|
||||
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package codegen
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func f(p unsafe.Pointer, x, y uintptr) int64 {
|
||||
p = unsafe.Pointer(uintptr(p) + x + y)
|
||||
// amd64:`MOVQ\s\(.*\)\(.*\*1\), `
|
||||
// arm64:`MOVD\s\(R[0-9]+\)\(R[0-9]+\), `
|
||||
return *(*int64)(p)
|
||||
}
|
Loading…
Reference in New Issue
Block a user