From 40a9e00d4ce45437f583a1d72cfd2b4b5c3824d5 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 30 Apr 2024 16:15:36 +0800 Subject: [PATCH] llgo/ssa: Slice, IndexAddr bugfix --- cl/_testcgo/sum/out.ll | 13 ++++++++----- cl/_testdata/builtin/out.ll | 4 ++-- internal/build/build.go | 3 +-- internal/runtime/llgo_autogen.ll | 9 +++++++++ internal/runtime/z_slice.go | 5 +++++ ssa/expr.go | 15 ++++++++++++--- 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/cl/_testcgo/sum/out.ll b/cl/_testcgo/sum/out.ll index 7a8cda47..10750baf 100644 --- a/cl/_testcgo/sum/out.ll +++ b/cl/_testcgo/sum/out.ll @@ -31,7 +31,7 @@ _llgo_0: store i64 3, ptr %3, align 4 %4 = getelementptr inbounds i64, ptr %0, i64 3 store i64 4, ptr %4, align 4 - %5 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(i64 4, i64 4) + %5 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %0, i64 4, i64 4) %6 = call i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %7 = call i32 (ptr, ...) @printf(ptr @0, i64 %6) ret void @@ -43,16 +43,17 @@ _llgo_0: br label %_llgo_1 _llgo_1: ; preds = %_llgo_2, %_llgo_0 - %2 = phi i64 [ 0, %_llgo_0 ], [ %8, %_llgo_2 ] + %2 = phi i64 [ 0, %_llgo_0 ], [ %9, %_llgo_2 ] %3 = phi i64 [ -1, %_llgo_0 ], [ %4, %_llgo_2 ] %4 = add i64 %3, 1 %5 = icmp slt i64 %4, %1 br i1 %5, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_1 - %6 = getelementptr inbounds i64, %"github.com/goplus/llgo/internal/runtime.Slice" %0, i64 %4 - %7 = load i64, %"github.com/goplus/llgo/internal/runtime.Slice" %6, align 4 - %8 = add i64 %2, %7 + %6 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %7 = getelementptr inbounds i64, ptr %6, i64 %4 + %8 = load i64, ptr %7, align 4 + %9 = add i64 %2, %8 br label %_llgo_1 _llgo_3: ; preds = %_llgo_1 @@ -66,3 +67,5 @@ declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llg declare i32 @printf(ptr, ...) declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") + +declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") diff --git a/cl/_testdata/builtin/out.ll b/cl/_testdata/builtin/out.ll index d284826e..7588a13e 100644 --- a/cl/_testdata/builtin/out.ll +++ b/cl/_testdata/builtin/out.ll @@ -36,7 +36,7 @@ _llgo_0: store i64 3, ptr %3, align 4 %4 = getelementptr inbounds i64, ptr %0, i64 3 store i64 4, ptr %4, align 4 - %5 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(i64 4, i64 4) + %5 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %0, i64 4, i64 4) %6 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %7 = call ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(i64 16) %8 = getelementptr inbounds i64, ptr %7, i64 0 @@ -47,7 +47,7 @@ _llgo_0: store i64 3, ptr %10, align 4 %11 = getelementptr inbounds i64, ptr %7, i64 3 store i64 4, ptr %11, align 4 - %12 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(i64 4, i64 4) + %12 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %7, i64 4, i64 4) %13 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %12) ret void } diff --git a/internal/build/build.go b/internal/build/build.go index e17ee2f1..2601355f 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -140,8 +140,7 @@ func Do(args []string, conf *Config) { } } if nErr > 0 { - fmt.Fprintf(os.Stderr, "%d errors occurred\n", nErr) - os.Exit(1) + os.Exit(nErr) } } } diff --git a/internal/runtime/llgo_autogen.ll b/internal/runtime/llgo_autogen.ll index 0708430f..22268057 100644 --- a/internal/runtime/llgo_autogen.ll +++ b/internal/runtime/llgo_autogen.ll @@ -198,6 +198,15 @@ _llgo_0: ret %"github.com/goplus/llgo/internal/runtime.Slice" %4 } +define ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { +_llgo_0: + %1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + store %"github.com/goplus/llgo/internal/runtime.Slice" %0, ptr %1, align 8 + %2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %1, i32 0, i32 0 + %3 = load ptr, ptr %2, align 8 + ret ptr %3 +} + define i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { _llgo_0: %1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 diff --git a/internal/runtime/z_slice.go b/internal/runtime/z_slice.go index ff4b309e..dc83b0c7 100644 --- a/internal/runtime/z_slice.go +++ b/internal/runtime/z_slice.go @@ -44,4 +44,9 @@ func SliceLen(s Slice) int { return s.len } +// SliceData returns the data pointer of a slice. +func SliceData(s Slice) unsafe.Pointer { + return s.data +} + // ----------------------------------------------------------------------------- diff --git a/ssa/expr.go b/ssa/expr.go index 476a276f..1544f242 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -424,8 +424,17 @@ func (b Builder) IndexAddr(x, idx Expr) Expr { prog := b.Prog telem := prog.Index(x.Type) pt := prog.Pointer(telem) - indices := []llvm.Value{idx.impl} - return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, x.impl, indices), pt} + switch x.t.Underlying().(type) { + case *types.Pointer: + indices := []llvm.Value{idx.impl} + return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, x.impl, indices), pt} + case *types.Slice: + pkg := b.fn.pkg + ptr := b.InlineCall(pkg.rtFunc("SliceData"), x) + indices := []llvm.Value{idx.impl} + return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, ptr.impl, indices), pt} + } + panic("todo") } // The Slice instruction yields a slice of an existing string, slice @@ -458,7 +467,7 @@ func (b Builder) Slice(x, low, high, max Expr) (ret Expr) { ret.Type = prog.Type(types.NewSlice(te.Elem())) if low.IsNil() && high.IsNil() && max.IsNil() { n := prog.Val(int(te.Len())) - ret.impl = b.InlineCall(pkg.rtFunc("NewSlice"), n, n).impl + ret.impl = b.InlineCall(pkg.rtFunc("NewSlice"), x, n, n).impl return ret } }