llvm: fix SysV C abi for structs smaller than two eightbytes

Closes #16038
Closes #16288
This commit is contained in:
Jacob Young
2023-07-28 12:48:01 -04:00
parent c80609dfec
commit 125b453c58
7 changed files with 126 additions and 15 deletions

View File

@@ -16,8 +16,12 @@ static void assert_or_panic(bool ok) {
# define ZIG_PPC32
#endif
#if defined __riscv && defined _ILP32
# define ZIG_RISCV32
#ifdef __riscv
# ifdef _ILP32
# define ZIG_RISCV32
# else
# define ZIG_RISCV64
# endif
#endif
#if defined(__aarch64__) && defined(__linux__)
@@ -191,6 +195,15 @@ struct SmallStructInts {
void zig_small_struct_ints(struct SmallStructInts);
struct SmallStructInts zig_ret_small_struct_ints();
struct MedStructInts {
int32_t x;
int32_t y;
int32_t z;
};
void zig_med_struct_ints(struct MedStructInts);
struct MedStructInts zig_ret_med_struct_ints();
struct MedStructMixed {
uint32_t a;
float b;
@@ -339,14 +352,22 @@ void run_c_tests(void) {
}
#endif
#if !defined __i386__ && !defined __arm__ && !defined __mips__ && \
!defined ZIG_PPC32 && !defined _ARCH_PPC64
#if !defined __i386__ && !defined __arm__ && !defined __aarch64__ && \
!defined __mips__ && !defined __powerpc__ && !defined ZIG_RISCV64
{
struct SmallStructInts s = {1, 2, 3, 4};
zig_small_struct_ints(s);
}
#endif
#if !defined __i386__ && !defined __arm__ && !defined __aarch64__ && \
!defined __mips__ && !defined __powerpc__ && !defined ZIG_RISCV64
{
struct MedStructInts s = {1, 2, 3};
zig_med_struct_ints(s);
}
#endif
#ifndef ZIG_NO_I128
{
__int128 s = 0;
@@ -586,6 +607,27 @@ struct SmallStructInts c_ret_small_struct_ints() {
return s;
}
void c_med_struct_ints(struct MedStructInts s) {
assert_or_panic(s.x == 1);
assert_or_panic(s.y == 2);
assert_or_panic(s.z == 3);
struct MedStructInts s2 = zig_ret_med_struct_ints();
assert_or_panic(s2.x == 1);
assert_or_panic(s2.y == 2);
assert_or_panic(s2.z == 3);
}
struct MedStructInts c_ret_med_struct_ints() {
struct MedStructInts s = {
.x = 1,
.y = 2,
.z = 3,
};
return s;
}
void c_med_struct_mixed(struct MedStructMixed x) {
assert_or_panic(x.a == 1234);
assert_or_panic(x.b == 100.0f);

View File

@@ -393,6 +393,38 @@ export fn zig_small_struct_ints(x: SmallStructInts) void {
expect(x.d == 4) catch @panic("test failure");
}
const MedStructInts = extern struct {
x: i32,
y: i32,
z: i32,
};
extern fn c_med_struct_ints(MedStructInts) void;
extern fn c_ret_med_struct_ints() MedStructInts;
test "C ABI medium struct of ints" {
if (builtin.cpu.arch == .x86) return error.SkipZigTest;
if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
var s = MedStructInts{
.x = 1,
.y = 2,
.z = 3,
};
c_med_struct_ints(s);
var s2 = c_ret_med_struct_ints();
try expect(s2.x == 1);
try expect(s2.y == 2);
try expect(s2.z == 3);
}
export fn zig_med_struct_ints(s: MedStructInts) void {
expect(s.x == 1) catch @panic("test failure");
expect(s.y == 2) catch @panic("test failure");
expect(s.z == 3) catch @panic("test failure");
}
const SmallPackedStruct = packed struct {
a: u2,
b: u2,
@@ -691,6 +723,14 @@ export fn zig_ret_small_struct_ints() SmallStructInts {
};
}
export fn zig_ret_med_struct_ints() MedStructInts {
return .{
.x = 1,
.y = 2,
.z = 3,
};
}
export fn zig_ret_med_struct_mixed() MedStructMixed {
return .{
.a = 1234,