aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2023-01-11 23:02:06 +0200
committerVeikka Tuominen <git@vexu.eu>2023-01-14 16:26:50 +0200
commit0013042cbd539cf7eb463483633e9f7aa2fa8067 (patch)
tree4346a3276ec07b35e3d90df88a8c5528c1fd7f96
parent5572c67e73222716372762d30453cc44ca4339c0 (diff)
downloadzig-0013042cbd539cf7eb463483633e9f7aa2fa8067.tar.gz
zig-0013042cbd539cf7eb463483633e9f7aa2fa8067.zip
llvm: correctly handle C ABI structs with f32/f64 alignment differences
Closes #13830
-rw-r--r--src/arch/x86_64/abi.zig23
-rw-r--r--src/codegen/llvm.zig16
-rw-r--r--test/c_abi/main.zig2
3 files changed, 37 insertions, 4 deletions
diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig
index 9fb0f795e3..35ac3dcb55 100644
--- a/src/arch/x86_64/abi.zig
+++ b/src/arch/x86_64/abi.zig
@@ -5,7 +5,19 @@ const assert = std.debug.assert;
const Register = @import("bits.zig").Register;
const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
-pub const Class = enum { integer, sse, sseup, x87, x87up, complex_x87, memory, none, win_i128 };
+pub const Class = enum {
+ integer,
+ sse,
+ sseup,
+ x87,
+ x87up,
+ complex_x87,
+ memory,
+ none,
+ win_i128,
+ float,
+ float_combine,
+};
pub fn classifyWindows(ty: Type, target: Target) Class {
// 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 {
}
return result;
},
- 32, 64 => {
+ 32 => {
+ result[0] = .float;
+ return result;
+ },
+ 64 => {
result[0] = .sse;
return result;
},
@@ -252,6 +268,9 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
combine: {
// "If both classes are equal, this is the resulting class."
if (result[result_i] == field_class[0]) {
+ if (result[result_i] == .float) {
+ result[result_i] = .float_combine;
+ }
break :combine;
}
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 15ffe25ecd..8604c7d7f6 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -10478,6 +10478,14 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
llvm_types_index += 1;
},
+ .float => {
+ llvm_types_buffer[llvm_types_index] = dg.context.floatType();
+ llvm_types_index += 1;
+ },
+ .float_combine => {
+ llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
+ llvm_types_index += 1;
+ },
.x87 => {
if (llvm_types_index != 0 or classes[2] != .none) {
return dg.context.voidType();
@@ -10694,6 +10702,14 @@ const ParamTypeIterator = struct {
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
llvm_types_index += 1;
},
+ .float => {
+ llvm_types_buffer[llvm_types_index] = dg.context.floatType();
+ llvm_types_index += 1;
+ },
+ .float_combine => {
+ llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
+ llvm_types_index += 1;
+ },
.x87 => {
it.zig_index += 1;
it.llvm_index += 1;
diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig
index 3bdb8c78a4..426651aa9e 100644
--- a/test/c_abi/main.zig
+++ b/test/c_abi/main.zig
@@ -937,7 +937,6 @@ test "CFF: Zig returns to C" {
try expectOk(c_assert_ret_CFF());
}
test "CFF: C passes to Zig" {
- if (builtin.cpu.arch == .x86_64 and builtin.mode != .Debug) return error.SkipZigTest;
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
@@ -948,7 +947,6 @@ test "CFF: C passes to Zig" {
try expectOk(c_send_CFF());
}
test "CFF: C returns to Zig" {
- if (builtin.cpu.arch == .x86_64 and builtin.mode != .Debug) return error.SkipZigTest;
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;