diff --git a/interp/interp_test.go b/interp/interp_test.go index b1223e0816..30b8dab135 100644 --- a/interp/interp_test.go +++ b/interp/interp_test.go @@ -22,6 +22,7 @@ func TestInterp(t *testing.T) { "store", "alloc", "slicedata", + "aggregate", } { t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/interp/interpreter.go b/interp/interpreter.go index 4c8c36fe75..af4757abab 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -928,11 +928,9 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me llvmFn := operands[len(operands)-1] args := operands[:len(operands)-1] for _, op := range operands { - if op.Type().TypeKind() == llvm.PointerTypeKind { - err := mem.markExternalStore(op) - if err != nil { - return r.errorAt(inst, err) - } + err := mem.markExternalStore(op) + if err != nil { + return r.errorAt(inst, err) } } result = r.builder.CreateCall(inst.llvmInst.CalledFunctionType(), llvmFn, args, inst.name) diff --git a/interp/testdata/aggregate.ll b/interp/testdata/aggregate.ll new file mode 100644 index 0000000000..4f3d9067cc --- /dev/null +++ b/interp/testdata/aggregate.ll @@ -0,0 +1,27 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64--linux" + +declare void @externalAggregate({ ptr }) + +@main.value = global i32 1 +@main.result = global i32 0 + +define void @runtime.initAll() unnamed_addr { +entry: + call void @main.init(ptr undef) + ret void +} + +define internal void @main.init(ptr %context) unnamed_addr { +entry: + ; The pointer is hidden inside an aggregate argument. + %arg = insertvalue { ptr } undef, ptr @main.value, 0 + + ; This call runs at runtime and may modify @main.value. + call void @externalAggregate({ ptr } %arg) + + ; Therefore this load must also remain at runtime. + %value = load i32, ptr @main.value + store i32 %value, ptr @main.result + ret void +} diff --git a/interp/testdata/aggregate.out.ll b/interp/testdata/aggregate.out.ll new file mode 100644 index 0000000000..d1d3cc6380 --- /dev/null +++ b/interp/testdata/aggregate.out.ll @@ -0,0 +1,15 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64--linux" + +@main.value = global i32 1 +@main.result = local_unnamed_addr global i32 0 + +declare void @externalAggregate({ ptr }) local_unnamed_addr + +define void @runtime.initAll() unnamed_addr { +entry: + call void @externalAggregate({ ptr } { ptr @main.value }) + %value = load i32, ptr @main.value, align 4 + store i32 %value, ptr @main.result, align 4 + ret void +}