Skip to content

Commit 0ae8468

Browse files
andreybokhankocherrymui
authored andcommitted
cmd/compile,cmd/go,cmd/internal,runtime: remove dynamic checks for atomics for ARM64 targets that support LSE
Remove dynamic checks for atomic instructions for ARM64 targets that support LSE extension. For #66131 Change-Id: I0ec1b183a3f4ea4c8a537430646e6bc4b4f64271 Reviewed-on: https://go-review.googlesource.com/c/go/+/569536 Reviewed-by: Mauri de Souza Meneguzzo <[email protected]> Reviewed-by: Cherry Mui <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Fannie Zhang <[email protected]> Reviewed-by: Shu-Chun Weng <[email protected]>
1 parent aa1b50e commit 0ae8468

File tree

8 files changed

+146
-35
lines changed

8 files changed

+146
-35
lines changed

src/cmd/compile/internal/ssagen/ssa.go

+29-25
Original file line numberDiff line numberDiff line change
@@ -4387,31 +4387,35 @@ func InitTables() {
43874387
makeAtomicGuardedIntrinsicARM64 := func(op0, op1 ssa.Op, typ, rtyp types.Kind, emit atomicOpEmitter) intrinsicBuilder {
43884388

43894389
return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
4390-
// Target Atomic feature is identified by dynamic detection
4391-
addr := s.entryNewValue1A(ssa.OpAddr, types.Types[types.TBOOL].PtrTo(), ir.Syms.ARM64HasATOMICS, s.sb)
4392-
v := s.load(types.Types[types.TBOOL], addr)
4393-
b := s.endBlock()
4394-
b.Kind = ssa.BlockIf
4395-
b.SetControl(v)
4396-
bTrue := s.f.NewBlock(ssa.BlockPlain)
4397-
bFalse := s.f.NewBlock(ssa.BlockPlain)
4398-
bEnd := s.f.NewBlock(ssa.BlockPlain)
4399-
b.AddEdgeTo(bTrue)
4400-
b.AddEdgeTo(bFalse)
4401-
b.Likely = ssa.BranchLikely
4402-
4403-
// We have atomic instructions - use it directly.
4404-
s.startBlock(bTrue)
4405-
emit(s, n, args, op1, typ)
4406-
s.endBlock().AddEdgeTo(bEnd)
4407-
4408-
// Use original instruction sequence.
4409-
s.startBlock(bFalse)
4410-
emit(s, n, args, op0, typ)
4411-
s.endBlock().AddEdgeTo(bEnd)
4412-
4413-
// Merge results.
4414-
s.startBlock(bEnd)
4390+
if buildcfg.GOARM64.LSE {
4391+
emit(s, n, args, op1, typ)
4392+
} else {
4393+
// Target Atomic feature is identified by dynamic detection
4394+
addr := s.entryNewValue1A(ssa.OpAddr, types.Types[types.TBOOL].PtrTo(), ir.Syms.ARM64HasATOMICS, s.sb)
4395+
v := s.load(types.Types[types.TBOOL], addr)
4396+
b := s.endBlock()
4397+
b.Kind = ssa.BlockIf
4398+
b.SetControl(v)
4399+
bTrue := s.f.NewBlock(ssa.BlockPlain)
4400+
bFalse := s.f.NewBlock(ssa.BlockPlain)
4401+
bEnd := s.f.NewBlock(ssa.BlockPlain)
4402+
b.AddEdgeTo(bTrue)
4403+
b.AddEdgeTo(bFalse)
4404+
b.Likely = ssa.BranchLikely
4405+
4406+
// We have atomic instructions - use it directly.
4407+
s.startBlock(bTrue)
4408+
emit(s, n, args, op1, typ)
4409+
s.endBlock().AddEdgeTo(bEnd)
4410+
4411+
// Use original instruction sequence.
4412+
s.startBlock(bFalse)
4413+
emit(s, n, args, op0, typ)
4414+
s.endBlock().AddEdgeTo(bEnd)
4415+
4416+
// Merge results.
4417+
s.startBlock(bEnd)
4418+
}
44154419
if rtyp == types.TNIL {
44164420
return nil
44174421
} else {

src/cmd/go/internal/cfg/cfg.go

+3
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ var (
402402

403403
// Used in envcmd.MkEnv and build ID computations.
404404
GOARM = envOr("GOARM", fmt.Sprint(buildcfg.GOARM))
405+
GOARM64 = envOr("GOARM64", fmt.Sprint(buildcfg.GOARM64))
405406
GO386 = envOr("GO386", buildcfg.GO386)
406407
GOAMD64 = envOr("GOAMD64", fmt.Sprintf("%s%d", "v", buildcfg.GOAMD64))
407408
GOMIPS = envOr("GOMIPS", buildcfg.GOMIPS)
@@ -429,6 +430,8 @@ func GetArchEnv() (key, val string) {
429430
switch Goarch {
430431
case "arm":
431432
return "GOARM", GOARM
433+
case "arm64":
434+
return "GOARM64", GOARM64
432435
case "386":
433436
return "GO386", GO386
434437
case "amd64":

src/cmd/go/internal/work/gc.go

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"bufio"
99
"bytes"
1010
"fmt"
11+
"internal/buildcfg"
1112
"internal/platform"
1213
"io"
1314
"log"
@@ -378,6 +379,13 @@ func asmArgs(a *Action, p *load.Package) []any {
378379
}
379380
}
380381

382+
if cfg.Goarch == "arm64" {
383+
g, err := buildcfg.ParseGoarm64(cfg.GOARM64)
384+
if err == nil && g.LSE {
385+
args = append(args, "-D", "GOARM64_LSE")
386+
}
387+
}
388+
381389
return args
382390
}
383391

src/cmd/internal/testdir/testdir_test.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,19 @@ var (
14591459
// Regexp to extract an architecture check: architecture name (or triplet),
14601460
// followed by semi-colon, followed by a comma-separated list of opcode checks.
14611461
// Extraneous spaces are ignored.
1462-
rxAsmPlatform = regexp.MustCompile(`(\w+)(/\w+)?(/\w*)?\s*:\s*(` + reMatchCheck + `(?:\s*,\s*` + reMatchCheck + `)*)`)
1462+
//
1463+
// An example: arm64/v8.1 : -`ADD` , `SUB`
1464+
// "(\w+)" matches "arm64" (architecture name)
1465+
// "(/[\w.]+)?" matches "v8.1" (architecture version)
1466+
// "(/\w*)?" doesn't match anything here (it's an optional part of the triplet)
1467+
// "\s*:\s*" matches " : " (semi-colon)
1468+
// "(" starts a capturing group
1469+
// first reMatchCheck matches "-`ADD`"
1470+
// `(?:" starts a non-capturing group
1471+
// "\s*,\s*` matches " , "
1472+
// second reMatchCheck matches "`SUB`"
1473+
// ")*)" closes started groups; "*" means that there might be other elements in the comma-separated list
1474+
rxAsmPlatform = regexp.MustCompile(`(\w+)(/[\w.]+)?(/\w*)?\s*:\s*(` + reMatchCheck + `(?:\s*,\s*` + reMatchCheck + `)*)`)
14631475

14641476
// Regexp to extract a single opcoded check
14651477
rxAsmCheck = regexp.MustCompile(reMatchCheck)
@@ -1471,7 +1483,7 @@ var (
14711483
"386": {"GO386", "sse2", "softfloat"},
14721484
"amd64": {"GOAMD64", "v1", "v2", "v3", "v4"},
14731485
"arm": {"GOARM", "5", "6", "7", "7,softfloat"},
1474-
"arm64": {},
1486+
"arm64": {"GOARM64", "v8.0", "v8.1"},
14751487
"loong64": {},
14761488
"mips": {"GOMIPS", "hardfloat", "softfloat"},
14771489
"mips64": {"GOMIPS64", "hardfloat", "softfloat"},

src/internal/buildcfg/cfg.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func goarm() (g goarmFeatures) {
127127
return
128128
}
129129

130-
type goarm64Features struct {
130+
type Goarm64Features struct {
131131
Version string
132132
// Large Systems Extension
133133
LSE bool
@@ -139,7 +139,7 @@ type goarm64Features struct {
139139
Crypto bool
140140
}
141141

142-
func (g goarm64Features) String() string {
142+
func (g Goarm64Features) String() string {
143143
arm64Str := g.Version
144144
if g.LSE {
145145
arm64Str += ",lse"
@@ -150,7 +150,7 @@ func (g goarm64Features) String() string {
150150
return arm64Str
151151
}
152152

153-
func parseGoarm64(v string) (g goarm64Features) {
153+
func ParseGoarm64(v string) (g Goarm64Features, e error) {
154154
const (
155155
lseOpt = ",lse"
156156
cryptoOpt = ",crypto"
@@ -184,21 +184,22 @@ func parseGoarm64(v string) (g goarm64Features) {
184184
// LSE extension is mandatory starting from 8.1
185185
g.LSE = true
186186
default:
187-
Error = fmt.Errorf("invalid GOARM64: must start with v8.{0-9} or v9.{0-5} and may optionally end in %q and/or %q",
187+
e = fmt.Errorf("invalid GOARM64: must start with v8.{0-9} or v9.{0-5} and may optionally end in %q and/or %q",
188188
lseOpt, cryptoOpt)
189189
g.Version = defaultGOARM64
190190
}
191191

192192
return
193193
}
194194

195-
func goarm64() goarm64Features {
196-
return parseGoarm64(envOr("GOARM64", defaultGOARM64))
195+
func goarm64() (g Goarm64Features) {
196+
g, Error = ParseGoarm64(envOr("GOARM64", defaultGOARM64))
197+
return
197198
}
198199

199200
// Returns true if g supports giving ARM64 ISA
200201
// Note that this function doesn't accept / test suffixes (like ",lse" or ",crypto")
201-
func (g goarm64Features) Supports(s string) bool {
202+
func (g Goarm64Features) Supports(s string) bool {
202203
// We only accept "v{8-9}.{0-9}. Everything else is malformed.
203204
if len(s) != 4 {
204205
return false

src/internal/buildcfg/cfg_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func TestConfigFlags(t *testing.T) {
7575
}
7676

7777
func TestGoarm64FeaturesSupports(t *testing.T) {
78-
g := parseGoarm64("v9.3")
78+
g, _ := ParseGoarm64("v9.3")
7979

8080
if !g.Supports("v9.3") {
8181
t.Errorf("Wrong goarm64Features.Supports for v9.3, v9.3")

0 commit comments

Comments
 (0)