From 88cfeb27912448557f2b50aa46d51848ca00e73a Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 11 Jul 2024 18:06:41 +0800 Subject: [PATCH 1/3] fix:correct `Sizeof` to align size properly --- ssa/type.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ssa/type.go b/ssa/type.go index 3b6e85f9..67c0ca17 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -114,7 +114,7 @@ func (p *goProgram) Offsetsof(fields []*types.Var) (ret []int64) { func (p *goProgram) Sizeof(T types.Type) int64 { prog := Program(p) ptrSize := int64(prog.PointerSize()) - return prog.sizes.Sizeof(T) + extraSize(T, ptrSize) + return align((prog.sizes.Sizeof(T) + extraSize(T, ptrSize)), prog.sizes.Alignof(T)) } func extraSize(t types.Type, ptrSize int64) (ret int64) { @@ -134,6 +134,10 @@ func extraSize(t types.Type, ptrSize int64) (ret int64) { return 0 } +func align(x, a int64) int64 { + return (x + a - 1) &^ (a - 1) +} + // ----------------------------------------------------------------------------- type rawType struct { From 861551b2ba73955bec4eccced0a2e70feb32b8d1 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 11 Jul 2024 21:16:50 +0800 Subject: [PATCH 2/3] update:extra alignment for structs only --- ssa/type.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ssa/type.go b/ssa/type.go index 67c0ca17..af48f47c 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -114,7 +114,11 @@ func (p *goProgram) Offsetsof(fields []*types.Var) (ret []int64) { func (p *goProgram) Sizeof(T types.Type) int64 { prog := Program(p) ptrSize := int64(prog.PointerSize()) - return align((prog.sizes.Sizeof(T) + extraSize(T, ptrSize)), prog.sizes.Alignof(T)) + baseSize := prog.sizes.Sizeof(T) + extraSize(T, ptrSize) + if _, ok := T.Underlying().(*types.Struct); ok { + return align(baseSize, prog.sizes.Alignof(T)) + } + return baseSize } func extraSize(t types.Type, ptrSize int64) (ret int64) { From 6d4e26012715ab351886ff2f267a597b5958460c Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 11 Jul 2024 21:41:54 +0800 Subject: [PATCH 3/3] test:add struct size test --- cl/_testrt/structsize/in.go | 19 +++++++++++++++++++ cl/_testrt/structsize/out.ll | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 cl/_testrt/structsize/in.go create mode 100644 cl/_testrt/structsize/out.ll diff --git a/cl/_testrt/structsize/in.go b/cl/_testrt/structsize/in.go new file mode 100644 index 00000000..0e83f67c --- /dev/null +++ b/cl/_testrt/structsize/in.go @@ -0,0 +1,19 @@ +package main + +import ( + "unsafe" + + "github.com/goplus/llgo/c" +) + +type Foo struct { + A byte + B uint8 + C uint16 + D byte + E [8]int8 +} + +func main() { + c.Printf(c.Str("%d"), unsafe.Sizeof(Foo{})) +} diff --git a/cl/_testrt/structsize/out.ll b/cl/_testrt/structsize/out.ll new file mode 100644 index 00000000..643a449e --- /dev/null +++ b/cl/_testrt/structsize/out.ll @@ -0,0 +1,34 @@ +; ModuleID = 'main' +source_filename = "main" + +@"main.init$guard" = global i1 false, align 1 +@__llgo_argc = global i32 0, align 4 +@__llgo_argv = global ptr null, align 8 +@0 = private unnamed_addr constant [3 x i8] c"%d\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define i32 @main(i32 %0, ptr %1) { +_llgo_0: + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = call i32 (ptr, ...) @printf(ptr @0, i64 14) + ret i32 0 +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare i32 @printf(ptr, ...)