mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: sign-extend the 2nd argument of the LoweredAtomicCas32 on loong64,mips64x,riscv64
The function LoweredAtomicCas32 is implemented using the LL-SC instruction pair
on loong64, mips64x, riscv64. However,the LL instruction on loong64, mips64x,
riscv64 is sign-extended, so it is necessary to sign-extend the 2nd parameter
"old" of the LoweredAtomicCas32, so that the instruction BNE after LL can get
the desired result.
The function prototype of LoweredAtomicCas32 in golang:
func Cas32(ptr *uint32, old, new uint32) bool
When using an intrinsify implementation:
case 1: (*ptr) <= 0x80000000 && old < 0x80000000
E.g: (*ptr) = 0x7FFFFFFF, old = Rarg1= 0x7FFFFFFF
After run the instruction "LL (Rarg0), Rtmp": Rtmp = 0x7FFFFFFF
Rtmp ! = Rarg1(old) is false, the result we expect
case 2: (*ptr) >= 0x80000000 && old >= 0x80000000
E.g: (*ptr) = 0x80000000, old = Rarg1= 0x80000000
After run the instruction "LL (Rarg0), Rtmp": Rtmp = 0xFFFFFFFF_80000000
Rtmp ! = Rarg1(old) is true, which we do not expect
When using an non-intrinsify implementation:
Because Rarg1 is loaded from the stack using sign-extended instructions
ld.w, the situation described in Case 2 above does not occur
Benchmarks on linux/loong64:
name old time/op new time/op delta
Cas 50.0ns ± 0% 50.1ns ± 0% ~ (p=1.000 n=1+1)
Cas64 50.0ns ± 0% 50.1ns ± 0% ~ (p=1.000 n=1+1)
Cas-4 56.0ns ± 0% 56.0ns ± 0% ~ (p=1.000 n=1+1)
Cas64-4 56.0ns ± 0% 56.0ns ± 0% ~ (p=1.000 n=1+1)
Benchmarks on Loongson 3A4000 (GOARCH=mips64le, 1.8GHz)
name old time/op new time/op delta
Cas 70.4ns ± 0% 70.3ns ± 0% ~ (p=1.000 n=1+1)
Cas64 70.7ns ± 0% 70.6ns ± 0% ~ (p=1.000 n=1+1)
Cas-4 81.1ns ± 0% 80.8ns ± 0% ~ (p=1.000 n=1+1)
Cas64-4 80.9ns ± 0% 80.9ns ± 0% ~ (p=1.000 n=1+1)
Fixes #57282
Change-Id: I190a7fc648023b15fa392f7fdda5ac18c1561bac
Reviewed-on: https://go-review.googlesource.com/c/go/+/457135
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Wayne Zuo <wdvxdr@golangcn.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
8bcc490667
commit
0b2ad1d815
7 changed files with 101 additions and 9 deletions
|
|
@ -61,8 +61,7 @@ func rewriteValueRISCV64(v *Value) bool {
|
|||
case OpAtomicAnd8:
|
||||
return rewriteValueRISCV64_OpAtomicAnd8(v)
|
||||
case OpAtomicCompareAndSwap32:
|
||||
v.Op = OpRISCV64LoweredAtomicCas32
|
||||
return true
|
||||
return rewriteValueRISCV64_OpAtomicCompareAndSwap32(v)
|
||||
case OpAtomicCompareAndSwap64:
|
||||
v.Op = OpRISCV64LoweredAtomicCas64
|
||||
return true
|
||||
|
|
@ -776,6 +775,27 @@ func rewriteValueRISCV64_OpAtomicAnd8(v *Value) bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueRISCV64_OpAtomicCompareAndSwap32(v *Value) bool {
|
||||
v_3 := v.Args[3]
|
||||
v_2 := v.Args[2]
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (AtomicCompareAndSwap32 ptr old new mem)
|
||||
// result: (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
|
||||
for {
|
||||
ptr := v_0
|
||||
old := v_1
|
||||
new := v_2
|
||||
mem := v_3
|
||||
v.reset(OpRISCV64LoweredAtomicCas32)
|
||||
v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
|
||||
v0.AddArg(old)
|
||||
v.AddArg4(ptr, v0, new, mem)
|
||||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueRISCV64_OpAtomicOr8(v *Value) bool {
|
||||
v_2 := v.Args[2]
|
||||
v_1 := v.Args[1]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue