Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/cmd/compile/internal/ssa/ssa2llvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,14 @@ func (lfc *LLVMFuncContext) llvmLifetimeStart(slot llvmStackSlot) {
lfc.b.CreateCall(sig, fn, []llvm.Value{slot.Value}, "")
}

func (lfc *LLVMFuncContext) llvmFakeUse(value llvm.Value) {
sig := llvm.FunctionType(GlobalCtxt.VoidType(), nil, true)
fn := getOrInsertLLVMIntrinsic("llvm.fake.use", sig)
lfc.b.CreateCall(sig, fn, []llvm.Value{value}, "")
func (lfc *LLVMFuncContext) llvmKeepAlive(value llvm.Value) {
// An operand bundle is a real SSA use that follows the call through
// inlining. llvm.donothing survives long enough for the statepoint pass to
// consume that liveness, then code generation emits no instruction for it.
fn := getLLVMIntrinsicDeclaration("llvm.donothing")
bundle := llvm.NewOperandBundle("go.keepalive", []llvm.Value{value})
lfc.b.CreateCallWithOperandBundles(fn.GlobalValueType(), fn, nil, []llvm.OperandBundle{bundle}, "")
bundle.Dispose()
}

func (lfc *LLVMFuncContext) llvmUnaryIntrinsic(v *Value, name string) llvm.Value {
Expand Down Expand Up @@ -1577,12 +1581,12 @@ func (lfc *LLVMFuncContext) GenLV(v *Value) llvm.Value {
lVal = arg0()
if name, ok := v.Aux.(*ir.Name); ok {
if slot, ok := lfc.Locals[llvmLocalKeyForName(name)]; ok && slot.Type.HasPointers() {
lfc.llvmFakeUse(slot.Value)
lfc.llvmKeepAlive(slot.Value)
}
}
case OpKeepAlive:
lVal = arg1()
lfc.llvmFakeUse(arg0())
lfc.llvmKeepAlive(arg0())
case OpLocalAddr:
if v.Uses == 0 {
break
Expand Down
38 changes: 38 additions & 0 deletions src/cmd/vendor/github.com/goallc/go-llvm/ir.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions test/codegen/llvm_memory_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@

package codegen

import "runtime"

var llvmMemoryOrderRoot *int

func llvmSemanticKeepAlive(value *int) {
runtime.KeepAlive(value)
}

//go:noinline
func llvmMemoryOrderStore(value *int) {
llvmMemoryOrderRoot = value
Expand All @@ -22,6 +28,10 @@ func llvmMemoryOrderStore(value *int) {
// LLVM-OPT: call ptr @llvm.go.gc.write.barrier(i32 2)
// LLVM-OPT: store ptr %[[VALUE]], ptr @codegen.llvmMemoryOrderRoot
// LLVM-OPT: ret ptr %[[VALUE]]
// LLVM-LABEL: define goabiinternal void @codegen.llvmSemanticKeepAlive(
// LLVM: call void @llvm.donothing() [ "go.keepalive"(ptr %{{.*}}) ]
// LLVM-OPT-LABEL: define goabiinternal void @codegen.llvmSemanticKeepAlive(
// LLVM-OPT: call void @llvm.donothing() [ "go.keepalive"(ptr %{{.*}}) ]
func llvmMemoryOrderLoad(value *int) *int {
llvmMemoryOrderStore(value)
return llvmMemoryOrderRoot
Expand Down