authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-11 23:02:06+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-14 16:26:50+02:00
log0013042cbd539cf7eb463483633e9f7aa2fa8067
tree4346a3276ec07b35e3d90df88a8c5528c1fd7f96
parent5572c67e73222716372762d30453cc44ca4339c0

llvm: correctly handle C ABI structs with f32/f64 alignment differences

Closes #13830

3 files changed, 37 insertions(+), 4 deletions(-)

src/arch/x86_64/abi.zig+21-2
......@@ -5,7 +5,19 @@ const assert = std.debug.assert;
55const Register = @import("bits.zig").Register;
66const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
77
8pub const Class = enum { integer, sse, sseup, x87, x87up, complex_x87, memory, none, win_i128 };
8pub const Class = enum {
9 integer,
10 sse,
11 sseup,
12 x87,
13 x87up,
14 complex_x87,
15 memory,
16 none,
17 win_i128,
18 float,
19 float_combine,
20};
921
1022pub fn classifyWindows(ty: Type, target: Target) Class {
1123 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
......@@ -121,7 +133,11 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
121133 }
122134 return result;
123135 },
124 32, 64 => {
136 32 => {
137 result[0] = .float;
138 return result;
139 },
140 64 => {
125141 result[0] = .sse;
126142 return result;
127143 },
......@@ -252,6 +268,9 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
252268 combine: {
253269 // "If both classes are equal, this is the resulting class."
254270 if (result[result_i] == field_class[0]) {
271 if (result[result_i] == .float) {
272 result[result_i] = .float_combine;
273 }
255274 break :combine;
256275 }
257276
src/codegen/llvm.zig+16
......@@ -10478,6 +10478,14 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
1047810478 llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
1047910479 llvm_types_index += 1;
1048010480 },
10481 .float => {
10482 llvm_types_buffer[llvm_types_index] = dg.context.floatType();
10483 llvm_types_index += 1;
10484 },
10485 .float_combine => {
10486 llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
10487 llvm_types_index += 1;
10488 },
1048110489 .x87 => {
1048210490 if (llvm_types_index != 0 or classes[2] != .none) {
1048310491 return dg.context.voidType();
......@@ -10694,6 +10702,14 @@ const ParamTypeIterator = struct {
1069410702 llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
1069510703 llvm_types_index += 1;
1069610704 },
10705 .float => {
10706 llvm_types_buffer[llvm_types_index] = dg.context.floatType();
10707 llvm_types_index += 1;
10708 },
10709 .float_combine => {
10710 llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
10711 llvm_types_index += 1;
10712 },
1069710713 .x87 => {
1069810714 it.zig_index += 1;
1069910715 it.llvm_index += 1;
test/c_abi/main.zig-2
......@@ -937,7 +937,6 @@ test "CFF: Zig returns to C" {
937937 try expectOk(c_assert_ret_CFF());
938938}
939939test "CFF: C passes to Zig" {
940 if (builtin.cpu.arch == .x86_64 and builtin.mode != .Debug) return error.SkipZigTest;
941940 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
942941 if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
943942 if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
......@@ -948,7 +947,6 @@ test "CFF: C passes to Zig" {
948947 try expectOk(c_send_CFF());
949948}
950949test "CFF: C returns to Zig" {
951 if (builtin.cpu.arch == .x86_64 and builtin.mode != .Debug) return error.SkipZigTest;
952950 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
953951 if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
954952 if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;