diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index f1a23a95c..528ddca88 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1342,22 +1342,8 @@ namespace lbAbiArm64 { } else if (size <= 8) { cast_type = LLVMIntTypeInContext(c, cast(unsigned)(size*8)); } else { - unsigned count = cast(unsigned)((size+7)/8); - LLVMTypeRef llvm_i64 = LLVMIntTypeInContext(c, 64); - LLVMTypeRef *types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, count); - - i64 size_copy = size; - for (unsigned i = 0; i < count; i++) { - if (size_copy >= 8) { - types[i] = llvm_i64; - } else { - types[i] = LLVMIntTypeInContext(c, 8*cast(unsigned)size_copy); - } - size_copy -= 8; - } - GB_ASSERT(size_copy <= 0); - cast_type = LLVMStructTypeInContext(c, types, count, true); + cast_type = llvm_array_type(llvm_i64, 2); } args[i] = lb_arg_type_direct(type, cast_type, nullptr, nullptr); } else { diff --git a/tests/issues/run.sh b/tests/issues/run.sh index c1e231390..c8fa80183 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -88,6 +88,9 @@ $ODIN test ../test_issue_7010.odin $COMMON clang -c ../test_issue_6809_6816.c -o test_issue_6809_6816_c.o -O3 $ODIN test ../test_issue_6809_6816.odin -o:speed $COMMON +clang -c ../test_issue_5640.c -o test_issue_5640_c.o +$ODIN test ../test_issue_5640.odin -o:none --sanitize:address $COMMON + set +x popd diff --git a/tests/issues/test_issue_5640.c b/tests/issues/test_issue_5640.c new file mode 100644 index 000000000..58cbff688 --- /dev/null +++ b/tests/issues/test_issue_5640.c @@ -0,0 +1,17 @@ +#include +#include + +typedef struct { + uint32_t a; + uint32_t b; + uint32_t c; +} MyStruct; + +bool test_stack_next( + int64_t r0, int64_t r1, int64_t r2, int64_t r3, + int64_t r4, int64_t r5, int64_t r6, int64_t r7, + MyStruct s, + int32_t next_arg +) { + return next_arg == 999; +} diff --git a/tests/issues/test_issue_5640.odin b/tests/issues/test_issue_5640.odin new file mode 100644 index 000000000..d25c68976 --- /dev/null +++ b/tests/issues/test_issue_5640.odin @@ -0,0 +1,39 @@ +package test_issues + +import "core:testing" + +MyStruct :: struct { + a: u32, + b: u32, + c: u32, +} + +Foo :: struct { + x: [15]u8, // errors with 11, 13, 14, 15 +} + + +myfunc :: #force_no_inline proc( f: Foo ) -> bool { + return f.x[0] == 45 && f.x[14] == 67 +} + +foreign import test_lib "build/test_issue_5640_c.o" + +foreign test_lib { + test_stack_next :: proc( + r0, r1, r2, r3, r4, r5, r6, r7: i64, + s: MyStruct, + next_arg: i32, + ) -> bool --- +} + +@test +test_stack_parameter_alignment_arm64_abi :: proc(t: ^testing.T) { + s := MyStruct{ a = 42, b = 1337, c = 342 } + + res := test_stack_next(0, 1, 2, 3, 4, 5, 6, 7, s, 999) + testing.expect(t, res == true) + + res_2 := myfunc({{45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67}}) + testing.expect(t, res_2 == true) +}