Skip to content

Commit 954fdcc

Browse files
xen0nabner-chenc
authored andcommitted
cmd/compile: declare no output register for loong64 LoweredAtomic{And,Or}32 ops
The ICE seen on loong64 while compiling the `(*gcWork).tryStealSpan` function was due to an `LoweredAtomicAnd32` op (inlined from the `(pMask).clear` implementation) being incorrectly assigned an output register while it shouldn't have. Because the op is of mem type, it has needRegister() == false; hence in the shuffle phase of regalloc, its bogus output register has no associated `orig` value recorded. The bug was introduced in CL 482756, but only recently exposed by CL 696035. Since the old-style atomic ops need no return value (and is even documented so besides the loong64 ssa op definition), just fix the register info for both. While at it, add a note in the ssa op definition file about the architectural necessity of resultNotInArgs for loong64 atomic ops, because the practice is not seen in several other arches I have checked. Updates golang#75776 Change-Id: I087f51b8a2825d7b00fc3965b0afcc8b02cad277 Reviewed-on: https://go-review.googlesource.com/c/go/+/710475 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Pratt <[email protected]> Reviewed-by: abner chenc <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 19a30ea commit 954fdcc

File tree

2 files changed

+9
-8
lines changed

2 files changed

+9
-8
lines changed

src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ func init() {
143143
gp2load = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
144144
gpstore = regInfo{inputs: []regMask{gpspsbg, gpg}}
145145
gpstore2 = regInfo{inputs: []regMask{gpspsbg, gpg, gpg | rz}}
146+
gpoldatom = regInfo{inputs: []regMask{gpspsbg, gpg}}
146147
gpxchg = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
147148
gpcas = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
148149
preldreg = regInfo{inputs: []regMask{gpspg}}
@@ -431,6 +432,12 @@ func init() {
431432
faultOnNilArg1: true,
432433
},
433434

435+
// Atomic operations.
436+
//
437+
// resultNotInArgs is needed by all ops lowering to LoongArch
438+
// atomic memory access instructions, because these instructions
439+
// are defined to require rd != rj && rd != rk per the ISA spec.
440+
434441
// atomic loads.
435442
// load from arg0. arg1=mem.
436443
// returns <value,memory> so they can be properly ordered with other loads.
@@ -500,8 +507,8 @@ func init() {
500507

501508
// Atomic 32 bit AND/OR.
502509
// *arg0 &= (|=) arg1. arg2=mem. returns nil.
503-
{name: "LoweredAtomicAnd32", argLength: 3, reg: gpxchg, asm: "AMANDDBW", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
504-
{name: "LoweredAtomicOr32", argLength: 3, reg: gpxchg, asm: "AMORDBW", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
510+
{name: "LoweredAtomicAnd32", argLength: 3, reg: gpoldatom, asm: "AMANDDBW", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
511+
{name: "LoweredAtomicOr32", argLength: 3, reg: gpoldatom, asm: "AMORDBW", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
505512

506513
// Atomic 32,64 bit AND/OR.
507514
// *arg0 &= (|=) arg1. arg2=mem. returns <old content of *arg0, memory>. auxint must be zero.

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

Lines changed: 0 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)