diff --git a/interp/interpreter.go b/interp/interpreter.go index a691e975..304f6517 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -941,6 +941,7 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me agg := operands[0] for i := 0; i < len(indices)-1; i++ { agg = r.builder.CreateExtractValue(agg, int(indices[i]), inst.name+".agg") + mem.instructions = append(mem.instructions, agg) } result = r.builder.CreateExtractValue(agg, int(indices[len(indices)-1]), inst.name) case llvm.InsertValue: @@ -953,11 +954,15 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me for i := 0; i < len(indices)-1; i++ { agg = r.builder.CreateExtractValue(agg, int(indices[i]), inst.name+".agg"+strconv.Itoa(i)) aggregates = append(aggregates, agg) + mem.instructions = append(mem.instructions, agg) } result = operands[1] for i := len(indices) - 1; i >= 0; i-- { agg := aggregates[i] result = r.builder.CreateInsertValue(agg, result, int(indices[i]), inst.name+".insertvalue"+strconv.Itoa(i)) + if i != 0 { // don't add last result to mem.instructions as it will be done at the end already + mem.instructions = append(mem.instructions, result) + } } case llvm.Add: diff --git a/interp/testdata/revert.ll b/interp/testdata/revert.ll index 41fb6a81..d2b3007d 100644 --- a/interp/testdata/revert.ll +++ b/interp/testdata/revert.ll @@ -5,9 +5,12 @@ declare void @externalCall(i64) @foo.knownAtRuntime = global i64 0 @bar.knownAtRuntime = global i64 0 +@baz.someGlobal = external global [3 x {i64, i32}] +@baz.someInt = global i32 0 define void @runtime.initAll() unnamed_addr { entry: + call void @baz.init(i8* undef, i8* undef) call void @foo.init(i8* undef, i8* undef) call void @bar.init(i8* undef, i8* undef) call void @main.init(i8* undef, i8* undef) @@ -25,6 +28,14 @@ define internal void @bar.init(i8* %context, i8* %parentHandle) unnamed_addr { ret void } +define internal void @baz.init(i8* %context, i8* %parentHandle) unnamed_addr { + ; Test extractvalue/insertvalue with more than one index. + %val = load [3 x {i64, i32}], [3 x {i64, i32}]* @baz.someGlobal + %part = extractvalue [3 x {i64, i32}] %val, 0, 1 + %val2 = insertvalue [3 x {i64, i32}] %val, i32 5, 2, 1 + unreachable ; trigger revert +} + define internal void @main.init(i8* %context, i8* %parentHandle) unnamed_addr { entry: call void @externalCall(i64 3) diff --git a/interp/testdata/revert.out.ll b/interp/testdata/revert.out.ll index 4f38e4c4..edc474d5 100644 --- a/interp/testdata/revert.out.ll +++ b/interp/testdata/revert.out.ll @@ -3,11 +3,14 @@ target triple = "x86_64--linux" @foo.knownAtRuntime = local_unnamed_addr global i64 0 @bar.knownAtRuntime = local_unnamed_addr global i64 0 +@baz.someGlobal = external local_unnamed_addr global [3 x { i64, i32 }] +@baz.someInt = local_unnamed_addr global i32 0 declare void @externalCall(i64) local_unnamed_addr define void @runtime.initAll() unnamed_addr { entry: + call fastcc void @baz.init(i8* undef, i8* undef) call fastcc void @foo.init(i8* undef, i8* undef) %val = load i64, i64* @foo.knownAtRuntime, align 8 store i64 %val, i64* @bar.knownAtRuntime, align 8 @@ -19,3 +22,7 @@ define internal fastcc void @foo.init(i8* %context, i8* %parentHandle) unnamed_a store i64 5, i64* @foo.knownAtRuntime, align 8 unreachable } + +define internal fastcc void @baz.init(i8* %context, i8* %parentHandle) unnamed_addr { + unreachable +}