authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-25 05:19:18+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-25 05:19:18+02:00
logfb9ba5e4b315e76c3ff1d01ebd56c651e13c314d
treef4c76488973ac4b909764c89211808252496b347
parent5cc281e7232b9f1bc5f4d732e4a37fb5df02f780
parentdf3aba6cc08622b908c47b6ae3aab2c1795e652e

Merge pull request 'llvm: fix `multiple_llvm_types` handling and aarch64 return types' (#32028) from aarch64-c-abi into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/32028 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

7 files changed, 107 insertions(+), 111 deletions(-)

build.zig+10-10
......@@ -416,7 +416,7 @@ pub fn build(b: *std.Build) !void {
416416 chosen_opt_modes_buf[chosen_mode_index] = builtin.OptimizeMode.ReleaseSmall;
417417 chosen_mode_index += 1;
418418 }
419 const optimization_modes = chosen_opt_modes_buf[0..chosen_mode_index];
419 const optimize_modes = chosen_opt_modes_buf[0..chosen_mode_index];
420420
421421 const test_only: ?tests.ModuleTestOptions.TestOnly = if (no_matrix)
422422 .default
......@@ -476,7 +476,7 @@ pub fn build(b: *std.Build) !void {
476476 .root_src = "test/behavior.zig",
477477 .name = "behavior",
478478 .desc = "Run the behavior tests",
479 .optimize_modes = optimization_modes,
479 .optimize_modes = optimize_modes,
480480 .include_paths = &.{},
481481 .sanitize_thread = sanitize_thread,
482482 .skip_single_threaded = skip_single_threaded,
......@@ -502,7 +502,7 @@ pub fn build(b: *std.Build) !void {
502502 .root_src = "lib/compiler_rt.zig",
503503 .name = "compiler-rt",
504504 .desc = "Run the compiler_rt tests",
505 .optimize_modes = optimization_modes,
505 .optimize_modes = optimize_modes,
506506 .include_paths = &.{},
507507 .sanitize_thread = sanitize_thread,
508508 .skip_single_threaded = true,
......@@ -529,7 +529,7 @@ pub fn build(b: *std.Build) !void {
529529 .root_src = "lib/std/std.zig",
530530 .name = "std",
531531 .desc = "Run the standard library tests",
532 .optimize_modes = optimization_modes,
532 .optimize_modes = optimize_modes,
533533 .include_paths = &.{},
534534 .sanitize_thread = sanitize_thread,
535535 .skip_single_threaded = skip_single_threaded,
......@@ -555,7 +555,7 @@ pub fn build(b: *std.Build) !void {
555555 .root_src = "test/c.zig",
556556 .name = "libc",
557557 .desc = "Run the libc API tests",
558 .optimize_modes = optimization_modes,
558 .optimize_modes = optimize_modes,
559559 .include_paths = &.{},
560560 .sanitize_thread = sanitize_thread,
561561 .skip_single_threaded = true,
......@@ -599,13 +599,14 @@ pub fn build(b: *std.Build) !void {
599599
600600 test_step.dependOn(tests.addStandaloneTests(
601601 b,
602 optimization_modes,
602 optimize_modes,
603603 enable_macos_sdk,
604604 enable_ios_sdk,
605605 enable_symlinks_windows,
606606 ));
607607 test_step.dependOn(tests.addCAbiTests(b, .{
608608 .test_target_filters = test_target_filters,
609 .optimize_modes = optimize_modes,
609610 .skip_non_native = skip_non_native,
610611 .skip_wasm = skip_wasm,
611612 .skip_freebsd = skip_freebsd,
......@@ -615,19 +616,18 @@ pub fn build(b: *std.Build) !void {
615616 .skip_darwin = skip_darwin,
616617 .skip_linux = skip_linux,
617618 .skip_llvm = skip_llvm,
618 .skip_release = skip_release,
619619 .max_rss = 3_300_000_000,
620620 }));
621621 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
622622 test_step.dependOn(tests.addStackTraceTests(b, test_filters, skip_non_native));
623 test_step.dependOn(tests.addErrorTraceTests(b, test_filters, optimization_modes, skip_non_native));
623 test_step.dependOn(tests.addErrorTraceTests(b, test_filters, optimize_modes, skip_non_native));
624624 test_step.dependOn(tests.addCliTests(b));
625625 if (tests.addDebuggerTests(b, .{
626626 .test_filters = test_filters,
627627 .test_target_filters = test_target_filters,
628628 .gdb = b.option([]const u8, "gdb", "path to gdb binary"),
629629 .lldb = b.option([]const u8, "lldb", "path to lldb binary"),
630 .optimize_modes = optimization_modes,
630 .optimize_modes = optimize_modes,
631631 .skip_single_threaded = skip_single_threaded,
632632 .skip_libc = skip_libc,
633633 })) |test_debugger_step| test_step.dependOn(test_debugger_step);
......@@ -663,7 +663,7 @@ pub fn build(b: *std.Build) !void {
663663 if (!skip_test_incremental) test_step.dependOn(test_incremental_step);
664664
665665 if (tests.addLibcTestNszTests(b, .{
666 .optimize_modes = optimization_modes,
666 .optimize_modes = optimize_modes,
667667 .test_filters = test_filters,
668668 .test_target_filters = test_target_filters,
669669 .skip_wasm = skip_wasm,
src/InternPool.zig+6
......@@ -5888,6 +5888,12 @@ pub const Alignment = enum(u6) {
58885888 return @enumFromInt(@min(@intFromEnum(lhs), @intFromEnum(rhs)));
58895889 }
58905890
5891 /// Given a base address known to be aligned to `a`,
5892 /// computes the known alignment of base address plus `off`.
5893 pub fn offset(a: Alignment, off: u64) Alignment {
5894 return .fromLog2Units(@min(a.toLog2Units(), @ctz(off)));
5895 }
5896
58915897 /// Align an address forwards to this alignment.
58925898 pub fn forward(a: Alignment, addr: u64) u64 {
58935899 assert(a != .none);
src/codegen/llvm.zig+15-10
......@@ -1358,24 +1358,22 @@ pub const Object = struct {
13581358 },
13591359 .multiple_llvm_types => {
13601360 assert(!it.byval_attr);
1361 const field_types = it.types_buffer[0..it.types_len];
13621361 const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
13631362 const param_llvm_ty = try o.lowerType(param_ty);
1364 const param_alignment = param_ty.abiAlignment(zcu).toLlvm();
1365 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, param_alignment, target);
1366 const llvm_ty = try o.builder.structType(.normal, field_types);
1367 const llvm_args_start = it.llvm_index - field_types.len;
1368 for (0..field_types.len, llvm_args_start..) |field_i, llvm_arg_index| {
1363 const param_alignment = param_ty.abiAlignment(zcu);
1364 const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8);
1365 const arg_ptr = try buildAllocaInner(&wip, llvm_ty, param_alignment.toLlvm(), target);
1366 const llvm_args_start = it.llvm_index - it.types_len;
1367 for (llvm_args_start.., it.offsets_buffer[0..it.types_len]) |llvm_arg_index, offset| {
13691368 const param = wip.arg(@intCast(llvm_arg_index));
1370 const field_ptr = try wip.gepStruct(llvm_ty, arg_ptr, field_i, "");
1371 const alignment = Type.ptrAbiAlignment(target).toLlvm();
1372 _ = try wip.store(.normal, param, field_ptr, alignment);
1369 const part_ptr = try o.ptraddConst(&wip, arg_ptr, offset);
1370 _ = try wip.store(.normal, param, part_ptr, param_alignment.offset(offset).toLlvm());
13731371 }
13741372
13751373 if (isByRef(param_ty, zcu)) {
13761374 args.appendAssumeCapacity(arg_ptr);
13771375 } else {
1378 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, arg_ptr, param_alignment, ""));
1376 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, arg_ptr, param_alignment.toLlvm(), ""));
13791377 }
13801378 },
13811379 .float_array => {
......@@ -4362,6 +4360,13 @@ pub const Object = struct {
43624360 toLlvmAddressSpace(.generic, o.zcu.getTarget()),
43634361 );
43644362 }
4363
4364 pub fn ptraddConst(o: *Object, wip: *Builder.WipFunction, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value {
4365 if (offset == 0) return ptr;
4366 const llvm_usize_ty = try o.lowerType(.usize);
4367 const offset_val = try o.builder.intValue(llvm_usize_ty, offset);
4368 return wip.gep(.inbounds, .i8, ptr, &.{offset_val}, "");
4369 }
43654370};
43664371
43674372const CallingConventionInfo = struct {
src/codegen/llvm/FuncGen.zig+52-49
......@@ -709,22 +709,25 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
709709 .multiple_llvm_types => {
710710 const arg = args[it.zig_index - 1];
711711 const param_ty = self.typeOf(arg);
712 const llvm_types = it.types_buffer[0..it.types_len];
713712 const llvm_arg = try self.resolveInst(arg);
714713 const is_by_ref = isByRef(param_ty, zcu);
715 const arg_ptr = if (is_by_ref) llvm_arg else ptr: {
716 const alignment = param_ty.abiAlignment(zcu).toLlvm();
717 const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment);
718 _ = try self.wip.store(.normal, llvm_arg, ptr, alignment);
719 break :ptr ptr;
720 };
714 const param_alignment = param_ty.abiAlignment(zcu);
715 const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8);
716 const arg_ptr = try self.buildAlloca(llvm_ty, param_alignment.toLlvm());
717 if (is_by_ref) _ = try self.wip.callMemCpy(
718 arg_ptr,
719 param_alignment.toLlvm(),
720 llvm_arg,
721 param_alignment.toLlvm(),
722 try o.builder.intValue(try o.lowerType(.usize), param_ty.abiSize(zcu)),
723 .normal,
724 self.disable_intrinsics,
725 ) else _ = try self.wip.store(.normal, llvm_arg, arg_ptr, param_alignment.toLlvm());
721726
722 const llvm_ty = try o.builder.structType(.normal, llvm_types);
723727 try llvm_args.ensureUnusedCapacity(it.types_len);
724 for (llvm_types, 0..) |field_ty, i| {
725 const alignment: Builder.Alignment = .fromByteUnits(@divExact(target.ptrBitWidth(), 8));
726 const field_ptr = try self.wip.gepStruct(llvm_ty, arg_ptr, i, "");
727 const loaded = try self.wip.load(.normal, field_ty, field_ptr, alignment, "");
728 for (it.types_buffer[0..it.types_len], it.offsets_buffer[0..it.types_len]) |field_ty, offset| {
729 const field_ptr = try self.ptraddConst(arg_ptr, offset);
730 const loaded = try self.wip.load(.normal, field_ty, field_ptr, param_alignment.offset(offset).toLlvm(), "");
728731 llvm_args.appendAssumeCapacity(loaded);
729732 }
730733 },
......@@ -2269,10 +2272,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build
22692272
22702273 const struct_ptr_align = struct_ty.abiAlignment(zcu);
22712274 const field_ptr = try self.ptraddConst(struct_llvm_val, offset);
2272 const field_ptr_align: InternPool.Alignment = switch (offset) {
2273 0 => struct_ptr_align,
2274 else => struct_ptr_align.minStrict(.fromLog2Units(@ctz(offset))),
2275 };
2275 const field_ptr_align = struct_ptr_align.offset(offset);
22762276
22772277 if (isByRef(field_ty, zcu)) {
22782278 return self.loadByRef(field_ptr, field_ty, field_ptr_align.toLlvm(), .normal);
......@@ -3120,11 +3120,7 @@ fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) Allocator.Er
31203120
31213121 const field_ty = struct_ty.fieldType(field_index, zcu);
31223122 const field_offset = struct_ty.structFieldOffset(field_index, zcu);
3123 const field_align = switch (field_offset) {
3124 0 => struct_ty.abiAlignment(zcu),
3125 else => struct_ty.abiAlignment(zcu).minStrict(.fromLog2Units(@ctz(field_offset))),
3126 };
3127
3123 const field_align = struct_ty.abiAlignment(zcu).offset(field_offset);
31283124 const field_ptr = try self.ptraddConst(self.err_ret_trace, field_offset);
31293125 return self.load(field_ptr, field_ty, field_align.toLlvm(), .normal);
31303126}
......@@ -5279,10 +5275,7 @@ fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.
52795275 return .none;
52805276 }
52815277 const tag_field_ptr = try self.ptraddConst(union_ptr, layout.tagOffset());
5282 const tag_ptr_align: InternPool.Alignment = switch (layout.tagOffset()) {
5283 0 => union_ptr_align,
5284 else => |off| .minStrict(union_ptr_align, .fromLog2Units(@ctz(off))),
5285 };
5278 const tag_ptr_align = union_ptr_align.offset(layout.tagOffset());
52865279 _ = try self.wip.store(access_kind, new_tag, tag_field_ptr, tag_ptr_align.toLlvm());
52875280 return .none;
52885281}
......@@ -5922,10 +5915,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde
59225915 if (!field_ty.hasRuntimeBits(zcu)) continue;
59235916 const offset = result_ty.structFieldOffset(field_index, zcu);
59245917 const field_ptr = try self.ptraddConst(alloca_inst, offset);
5925 const field_ptr_align: InternPool.Alignment = switch (offset) {
5926 0 => struct_align,
5927 else => struct_align.minStrict(.fromLog2Units(@ctz(offset))),
5928 };
5918 const field_ptr_align = struct_align.offset(offset);
59295919
59305920 const llvm_field_val = try self.resolveInst(elem);
59315921
......@@ -6581,6 +6571,7 @@ const ParamTypeIterator = struct {
65816571 llvm_index: u32,
65826572 types_len: u32,
65836573 types_buffer: [8]Builder.Type,
6574 offsets_buffer: [9]u64,
65846575 byval_attr: bool,
65856576
65866577 const Lowering = union(enum) {
......@@ -6672,7 +6663,12 @@ const ParamTypeIterator = struct {
66726663 .memory => return .byref_mut,
66736664 .float_array => |len| return Lowering{ .float_array = len },
66746665 .byval => return .byval,
6675 .integer => return .abi_sized_int,
6666 .integer => {
6667 it.types_len = 1;
6668 it.types_buffer[0..1].* = .{.i64};
6669 it.offsets_buffer[0..2].* = .{ 0, 8 };
6670 return .multiple_llvm_types;
6671 },
66766672 .double_integer => return Lowering{ .i64_array = 2 },
66776673 }
66786674 },
......@@ -6711,12 +6707,17 @@ const ParamTypeIterator = struct {
67116707 .double_integer => return Lowering{ .i64_array = 2 },
67126708 .fields => {
67136709 it.types_len = 0;
6710 var offset: u64 = 0;
67146711 for (0..ty.structFieldCount(zcu)) |field_index| {
67156712 const field_ty = ty.fieldType(field_index, zcu);
67166713 if (!field_ty.hasRuntimeBits(zcu)) continue;
6714 offset = field_ty.abiAlignment(zcu).forward(offset);
67176715 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);
6716 it.offsets_buffer[it.types_len] = offset;
67186717 it.types_len += 1;
6718 offset += field_ty.abiSize(zcu);
67196719 }
6720 it.offsets_buffer[it.types_len] = offset;
67206721 it.llvm_index += it.types_len - 1;
67216722 return .multiple_llvm_types;
67226723 },
......@@ -6729,9 +6730,8 @@ const ParamTypeIterator = struct {
67296730 it.llvm_index += 1;
67306731 return .byval;
67316732 } else {
6732 var types_buffer: [8]Builder.Type = undefined;
6733 types_buffer[0] = try it.object.lowerType(scalar_ty);
6734 it.types_buffer = types_buffer;
6733 it.types_buffer[0..1].* = .{try it.object.lowerType(scalar_ty)};
6734 it.offsets_buffer[0..2].* = .{ 0, scalar_ty.abiSize(zcu) };
67356735 it.types_len = 1;
67366736 it.llvm_index += 1;
67376737 it.zig_index += 1;
......@@ -6804,31 +6804,36 @@ const ParamTypeIterator = struct {
68046804 return .byval;
68056805 }
68066806 var types_index: u32 = 0;
6807 var types_buffer: [8]Builder.Type = undefined;
6807 var offset: u64 = 0;
68086808 for (classes) |class| {
68096809 switch (class) {
68106810 .integer => {
6811 types_buffer[types_index] = .i64;
6811 it.types_buffer[types_index] = .i64;
6812 it.offsets_buffer[types_index] = offset;
68126813 types_index += 1;
68136814 },
68146815 .sse => {
6815 types_buffer[types_index] = .double;
6816 it.types_buffer[types_index] = .double;
6817 it.offsets_buffer[types_index] = offset;
68166818 types_index += 1;
68176819 },
68186820 .sseup => {
6819 if (types_buffer[types_index - 1] == .double) {
6820 types_buffer[types_index - 1] = .fp128;
6821 if (it.types_buffer[types_index - 1] == .double) {
6822 it.types_buffer[types_index - 1] = .fp128;
68216823 } else {
6822 types_buffer[types_index] = .double;
6824 it.types_buffer[types_index] = .double;
6825 it.offsets_buffer[types_index] = offset;
68236826 types_index += 1;
68246827 }
68256828 },
68266829 .float => {
6827 types_buffer[types_index] = .float;
6830 it.types_buffer[types_index] = .float;
6831 it.offsets_buffer[types_index] = offset;
68286832 types_index += 1;
68296833 },
68306834 .float_combine => {
6831 types_buffer[types_index] = try it.object.builder.vectorType(.normal, 2, .float);
6835 it.types_buffer[types_index] = try it.object.builder.vectorType(.normal, 2, .float);
6836 it.offsets_buffer[types_index] = offset;
68326837 types_index += 1;
68336838 },
68346839 .x87 => {
......@@ -6845,6 +6850,7 @@ const ParamTypeIterator = struct {
68456850 @panic("TODO");
68466851 },
68476852 }
6853 offset += 8;
68486854 }
68496855 const first_non_integer = std.mem.indexOfNone(x86_64_abi.Class, &classes, &.{.integer});
68506856 if (first_non_integer == null or classes[first_non_integer.?] == .none) {
......@@ -6865,15 +6871,15 @@ const ParamTypeIterator = struct {
68656871 const size = ty.abiSize(zcu);
68666872 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
68676873 if (size % 8 > 0) {
6868 types_buffer[types_index - 1] =
6874 it.types_buffer[types_index - 1] =
68696875 try it.object.builder.intType(@intCast(size % 8 * 8));
68706876 }
68716877 },
68726878 else => {},
68736879 }
68746880 }
6881 it.offsets_buffer[types_index] = offset;
68756882 it.types_len = types_index;
6876 it.types_buffer = types_buffer;
68776883 it.llvm_index += types_index;
68786884 it.zig_index += 1;
68796885 return .multiple_llvm_types;
......@@ -6887,6 +6893,7 @@ pub fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) Para
68876893 .llvm_index = 0,
68886894 .types_len = 0,
68896895 .types_buffer = undefined,
6896 .offsets_buffer = undefined,
68906897 .byval_attr = false,
68916898 };
68926899}
......@@ -6965,7 +6972,7 @@ pub fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Erro
69656972 .memory => return .void,
69666973 .float_array => return o.lowerType(return_type),
69676974 .byval => return o.lowerType(return_type),
6968 .integer => return o.builder.intType(@intCast(return_type.bitSize(zcu))),
6975 .integer => return .i64,
69696976 .double_integer => return o.builder.arrayType(2, .i64),
69706977 },
69716978 .arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) {
......@@ -7285,11 +7292,7 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E
72857292}
72867293
72877294fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value {
7288 if (offset == 0) return ptr;
7289 const o = fg.object;
7290 const llvm_usize_ty = try o.lowerType(.usize);
7291 const offset_val = try o.builder.intValue(llvm_usize_ty, offset);
7292 return fg.wip.gep(.inbounds, .i8, ptr, &.{offset_val}, "");
7295 return fg.object.ptraddConst(&fg.wip, ptr, offset);
72937296}
72947297fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u64) Allocator.Error!Builder.Value {
72957298 if (scale == 0) return ptr;
test/c_abi/cfuncs.c+4-12
......@@ -2802,7 +2802,6 @@ void run_c_tests(void) {
28022802 }
28032803#endif
28042804
2805#if !defined(__AARCH_BIG_ENDIAN)
28062805#if !defined(__mips64)
28072806#if !defined(ZIG_PPC32)
28082807#if !defined(__s390x__)
......@@ -2814,9 +2813,7 @@ void run_c_tests(void) {
28142813#endif
28152814#endif
28162815#endif
2817#endif
28182816
2819#if !defined(__AARCH_BIG_ENDIAN)
28202817#if !defined(__mips64)
28212818#if !defined(ZIG_PPC32)
28222819#if !defined(__s390x__)
......@@ -2828,9 +2825,7 @@ void run_c_tests(void) {
28282825#endif
28292826#endif
28302827#endif
2831#endif
28322828
2833#if !defined(__AARCH_BIG_ENDIAN)
28342829#if !defined(__mips64)
28352830#if !defined(ZIG_PPC32)
28362831#if !defined(__s390x__)
......@@ -2842,7 +2837,6 @@ void run_c_tests(void) {
28422837#endif
28432838#endif
28442839#endif
2845#endif
28462840
28472841#if !defined(ZIG_PPC32)
28482842#if !defined(ZIG_RISCV32)
......@@ -2872,7 +2866,6 @@ void run_c_tests(void) {
28722866 zig_struct_u64_u64_8(0, 1, 2, 3, 4, 5, 6, 7, (struct Struct_u64_u64){ .a = 19, .b = 20 }, 9);
28732867 }
28742868
2875#if !defined(ZIG_RISCV64)
28762869#if !defined(__mips64__)
28772870 {
28782871 struct Struct_f32 s = zig_ret_struct_f32();
......@@ -2908,7 +2901,6 @@ void run_c_tests(void) {
29082901 }
29092902#endif
29102903#endif
2911#endif
29122904
29132905#if !defined(__powerpc__) && !defined(__loongarch__) && !defined(__mips64__)
29142906 {
......@@ -2933,8 +2925,8 @@ void run_c_tests(void) {
29332925#endif
29342926#endif
29352927
2936#if !defined __i386__ && !defined __arm__ && !defined(__AARCH_BIG_ENDIAN) && \
2937 !defined __powerpc__ && !defined ZIG_RISCV64 && !defined(__loongarch__) && \
2928#if !defined __i386__ && !defined __arm__ && \
2929 !defined __powerpc__ && !defined(__loongarch__) && \
29382930 !defined(__mips64__) && !defined(__hexagon__) && !defined(__s390x__)
29392931 {
29402932 struct SmallStructInts s = {1, 2, 3, 4};
......@@ -2942,8 +2934,8 @@ void run_c_tests(void) {
29422934 }
29432935#endif
29442936
2945#if !defined __arm__ && !defined(__AARCH_BIG_ENDIAN) && \
2946 !defined __powerpc__ && !defined ZIG_RISCV64 && !defined(__loongarch__) && \
2937#if !defined __arm__ && \
2938 !defined __powerpc__ && !defined(__loongarch__) && \
29472939 !defined(__mips64__) && !defined(__hexagon__) && !defined(__s390x__)
29482940 {
29492941 struct MedStructInts s = {1, 2, 3};
test/c_abi/main.zig-6
......@@ -287,7 +287,6 @@ extern fn c_ret_struct_u8() Struct_u8;
287287extern fn c_struct_u8(Struct_u8, usize) void;
288288
289289test "C ABI struct u8" {
290 if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
291290 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
292291 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
293292 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
......@@ -315,7 +314,6 @@ extern fn c_ret_struct_u16() Struct_u16;
315314extern fn c_struct_u16(Struct_u16, usize) void;
316315
317316test "C ABI struct u16" {
318 if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
319317 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
320318 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
321319 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
......@@ -343,7 +341,6 @@ extern fn c_ret_struct_u32() Struct_u32;
343341extern fn c_struct_u32(Struct_u32, usize) void;
344342
345343test "C ABI struct u32" {
346 if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
347344 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
348345 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
349346 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
......@@ -770,7 +767,6 @@ test "C ABI small struct of ints" {
770767 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
771768 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
772769 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
773 if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
774770 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
775771 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
776772 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
......@@ -5613,7 +5609,6 @@ extern fn c_ret_ptr_size_float_struct() Vector2;
56135609
56145610test "C ABI pointer sized float struct" {
56155611 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
5616 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
56175612 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
56185613 if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest;
56195614 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
......@@ -5978,7 +5973,6 @@ extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coor
59785973test "Stdcall ABI structs" {
59795974 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
59805975 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
5981 if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
59825976 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
59835977 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
59845978 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
test/tests.zig+20-24
......@@ -2749,6 +2749,7 @@ pub fn wouldUseLlvm(use_llvm: ?bool, query: std.Target.Query, optimize_mode: Opt
27492749
27502750const CAbiTestOptions = struct {
27512751 test_target_filters: []const []const u8,
2752 optimize_modes: []const OptimizeMode,
27522753 skip_non_native: bool,
27532754 skip_wasm: bool,
27542755 skip_freebsd: bool,
......@@ -2758,43 +2759,38 @@ const CAbiTestOptions = struct {
27582759 skip_darwin: bool,
27592760 skip_linux: bool,
27602761 skip_llvm: bool,
2761 skip_release: bool,
27622762 max_rss: usize = 0,
27632763};
27642764
27652765pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step {
27662766 const step = b.step("test-c-abi", "Run the C ABI tests");
27672767
2768 const optimize_modes: [3]OptimizeMode = .{ .Debug, .ReleaseSafe, .ReleaseFast };
2768 for (c_abi_targets) |c_abi_target| {
2769 if (options.skip_non_native and !c_abi_target.target.isNative()) continue;
27692770
2770 for (optimize_modes) |optimize_mode| {
2771 if (optimize_mode != .Debug and options.skip_release) continue;
2771 if (options.skip_wasm and c_abi_target.target.cpu_arch != null and c_abi_target.target.cpu_arch.?.isWasm()) continue;
27722772
2773 for (c_abi_targets) |c_abi_target| {
2774 if (options.skip_non_native and !c_abi_target.target.isNative()) continue;
2773 if (options.skip_freebsd and c_abi_target.target.os_tag == .freebsd) continue;
2774 if (options.skip_netbsd and c_abi_target.target.os_tag == .netbsd) continue;
2775 if (options.skip_openbsd and c_abi_target.target.os_tag == .openbsd) continue;
2776 if (options.skip_windows and c_abi_target.target.os_tag == .windows) continue;
2777 if (options.skip_darwin and c_abi_target.target.os_tag != null and c_abi_target.target.os_tag.?.isDarwin()) continue;
2778 if (options.skip_linux and c_abi_target.target.os_tag == .linux) continue;
27752779
2776 if (options.skip_wasm and c_abi_target.target.cpu_arch != null and c_abi_target.target.cpu_arch.?.isWasm()) continue;
2780 const resolved_target = b.resolveTargetQuery(c_abi_target.target);
2781 const triple_txt = resolved_target.query.zigTriple(b.allocator) catch @panic("OOM");
2782 const target = &resolved_target.result;
27772783
2778 if (options.skip_freebsd and c_abi_target.target.os_tag == .freebsd) continue;
2779 if (options.skip_netbsd and c_abi_target.target.os_tag == .netbsd) continue;
2780 if (options.skip_openbsd and c_abi_target.target.os_tag == .openbsd) continue;
2781 if (options.skip_windows and c_abi_target.target.os_tag == .windows) continue;
2782 if (options.skip_darwin and c_abi_target.target.os_tag != null and c_abi_target.target.os_tag.?.isDarwin()) continue;
2783 if (options.skip_linux and c_abi_target.target.os_tag == .linux) continue;
2784 if (options.test_target_filters.len > 0) {
2785 for (options.test_target_filters) |filter| {
2786 if (std.mem.indexOf(u8, triple_txt, filter) != null) break;
2787 } else continue;
2788 }
27842789
2785 const would_use_llvm = wouldUseLlvm(c_abi_target.use_llvm, c_abi_target.target, .Debug);
2790 for (options.optimize_modes) |optimize_mode| {
2791 const would_use_llvm = wouldUseLlvm(c_abi_target.use_llvm, c_abi_target.target, optimize_mode);
27862792 if (options.skip_llvm and would_use_llvm) continue;
27872793
2788 const resolved_target = b.resolveTargetQuery(c_abi_target.target);
2789 const triple_txt = resolved_target.query.zigTriple(b.allocator) catch @panic("OOM");
2790 const target = &resolved_target.result;
2791
2792 if (options.test_target_filters.len > 0) {
2793 for (options.test_target_filters) |filter| {
2794 if (std.mem.indexOf(u8, triple_txt, filter) != null) break;
2795 } else continue;
2796 }
2797
27982794 const test_mod = b.createModule(.{
27992795 .root_source_file = b.path("test/c_abi/main.zig"),
28002796 .target = resolved_target,