mirror of
https://github.com/golang/go
synced 2024-11-26 16:16:57 -07:00
cmd/compile: mark some AMD64 atomic ops as clobberFlags
Fixes #16985. Change-Id: I5954db28f7b70dd3ac7768e471d5df871a5b20f9 Reviewed-on: https://go-review.googlesource.com/28510 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
6db13e071b
commit
f1ef5a06d2
@ -526,8 +526,8 @@ func init() {
|
|||||||
// *(arg1+auxint+aux) += arg0. arg2=mem.
|
// *(arg1+auxint+aux) += arg0. arg2=mem.
|
||||||
// Returns a tuple of <old contents of *(arg1+auxint+aux), memory>.
|
// Returns a tuple of <old contents of *(arg1+auxint+aux), memory>.
|
||||||
// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
|
// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
|
||||||
{name: "XADDLlock", argLength: 3, reg: gpstorexchg, asm: "XADDL", typ: "(UInt32,Mem)", aux: "SymOff", resultInArg0: true},
|
{name: "XADDLlock", argLength: 3, reg: gpstorexchg, asm: "XADDL", typ: "(UInt32,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true},
|
||||||
{name: "XADDQlock", argLength: 3, reg: gpstorexchg, asm: "XADDQ", typ: "(UInt64,Mem)", aux: "SymOff", resultInArg0: true},
|
{name: "XADDQlock", argLength: 3, reg: gpstorexchg, asm: "XADDQ", typ: "(UInt64,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true},
|
||||||
{name: "AddTupleFirst32", argLength: 2}, // arg0=tuple <x,y>. Returns <x+arg1,y>.
|
{name: "AddTupleFirst32", argLength: 2}, // arg0=tuple <x,y>. Returns <x+arg1,y>.
|
||||||
{name: "AddTupleFirst64", argLength: 2}, // arg0=tuple <x,y>. Returns <x+arg1,y>.
|
{name: "AddTupleFirst64", argLength: 2}, // arg0=tuple <x,y>. Returns <x+arg1,y>.
|
||||||
|
|
||||||
@ -550,12 +550,12 @@ func init() {
|
|||||||
// JEQ ...
|
// JEQ ...
|
||||||
// but we can't do that because memory-using ops can't generate flags yet
|
// but we can't do that because memory-using ops can't generate flags yet
|
||||||
// (flagalloc wants to move flag-generating instructions around).
|
// (flagalloc wants to move flag-generating instructions around).
|
||||||
{name: "CMPXCHGLlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGL", aux: "SymOff"},
|
{name: "CMPXCHGLlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGL", aux: "SymOff", clobberFlags: true},
|
||||||
{name: "CMPXCHGQlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGQ", aux: "SymOff"},
|
{name: "CMPXCHGQlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGQ", aux: "SymOff", clobberFlags: true},
|
||||||
|
|
||||||
// Atomic memory updates.
|
// Atomic memory updates.
|
||||||
{name: "ANDBlock", argLength: 3, reg: gpstore, asm: "ANDB", aux: "SymOff"}, // *(arg0+auxint+aux) &= arg1
|
{name: "ANDBlock", argLength: 3, reg: gpstore, asm: "ANDB", aux: "SymOff", clobberFlags: true}, // *(arg0+auxint+aux) &= arg1
|
||||||
{name: "ORBlock", argLength: 3, reg: gpstore, asm: "ORB", aux: "SymOff"}, // *(arg0+auxint+aux) |= arg1
|
{name: "ORBlock", argLength: 3, reg: gpstore, asm: "ORB", aux: "SymOff", clobberFlags: true}, // *(arg0+auxint+aux) |= arg1
|
||||||
}
|
}
|
||||||
|
|
||||||
var AMD64blocks = []blockData{
|
var AMD64blocks = []blockData{
|
||||||
|
@ -6872,6 +6872,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
resultInArg0: true,
|
resultInArg0: true,
|
||||||
|
clobberFlags: true,
|
||||||
asm: x86.AXADDL,
|
asm: x86.AXADDL,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
@ -6888,6 +6889,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
resultInArg0: true,
|
resultInArg0: true,
|
||||||
|
clobberFlags: true,
|
||||||
asm: x86.AXADDQ,
|
asm: x86.AXADDQ,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
@ -6913,6 +6915,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
name: "CMPXCHGLlock",
|
name: "CMPXCHGLlock",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
|
clobberFlags: true,
|
||||||
asm: x86.ACMPXCHGL,
|
asm: x86.ACMPXCHGL,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
@ -6931,6 +6934,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
name: "CMPXCHGQlock",
|
name: "CMPXCHGQlock",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
|
clobberFlags: true,
|
||||||
asm: x86.ACMPXCHGQ,
|
asm: x86.ACMPXCHGQ,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
@ -6949,6 +6953,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
name: "ANDBlock",
|
name: "ANDBlock",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
|
clobberFlags: true,
|
||||||
asm: x86.AANDB,
|
asm: x86.AANDB,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
@ -6961,6 +6966,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
name: "ORBlock",
|
name: "ORBlock",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
|
clobberFlags: true,
|
||||||
asm: x86.AORB,
|
asm: x86.AORB,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
|
37
test/fixedbugs/issue16985.go
Normal file
37
test/fixedbugs/issue16985.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// run
|
||||||
|
|
||||||
|
// Copyright 2016 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.
|
||||||
|
|
||||||
|
// issue 16985: intrinsified AMD64 atomic ops should clobber flags
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "sync/atomic"
|
||||||
|
|
||||||
|
var count uint32
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
buffer := []byte("T")
|
||||||
|
for i := 0; i < len(buffer); {
|
||||||
|
atomic.AddUint32(&count, 1)
|
||||||
|
_ = buffer[i]
|
||||||
|
i++
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(buffer); {
|
||||||
|
atomic.CompareAndSwapUint32(&count, 0, 1)
|
||||||
|
_ = buffer[i]
|
||||||
|
i++
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(buffer); {
|
||||||
|
atomic.SwapUint32(&count, 1)
|
||||||
|
_ = buffer[i]
|
||||||
|
i++
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user