From f000f8a59a8bf1121ecbe9b60ae50cc0218d3ba3 Mon Sep 17 00:00:00 2001 From: Guillaume Wenzek Date: Tue, 1 Mar 2022 23:26:43 +0100 Subject: [PATCH] fix nvptx test failure #10968 allow test cases to chose wether to link libc or not. default behavior is to not link libc, except for `exeUsingLLVMBackend` --- src/link/NvPtx.zig | 33 ++++++++++++++++----------------- src/test.zig | 16 ++++++---------- test/cases.zig | 3 +-- test/stage2/nvptx.zig | 42 +++++++++++++++++++++++++++++------------- 4 files changed, 52 insertions(+), 42 deletions(-) diff --git a/src/link/NvPtx.zig b/src/link/NvPtx.zig index 77613cdc1d..5d0f578d1d 100644 --- a/src/link/NvPtx.zig +++ b/src/link/NvPtx.zig @@ -25,8 +25,21 @@ base: link.File, llvm_object: *LlvmObject, pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx { - if (!build_options.have_llvm) return error.TODOArchNotSupported; + if (!build_options.have_llvm) return error.PtxArchNotSupported; + if (!options.use_llvm) return error.PtxArchNotSupported; + switch (options.target.cpu.arch) { + .nvptx, .nvptx64 => {}, + else => return error.PtxArchNotSupported, + } + + switch (options.target.os.tag) { + // TODO: does it also work with nvcl ? + .cuda => {}, + else => return error.PtxArchNotSupported, + } + + const llvm_object = try LlvmObject.create(gpa, options); const nvptx = try gpa.create(NvPtx); nvptx.* = .{ .base = .{ @@ -35,32 +48,19 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx { .file = null, .allocator = gpa, }, - .llvm_object = undefined, + .llvm_object = llvm_object, }; - switch (options.target.cpu.arch) { - .nvptx, .nvptx64 => {}, - else => return error.TODOArchNotSupported, - } - - switch (options.target.os.tag) { - // TODO: does it also work with nvcl ? - .cuda => {}, - else => return error.TODOOsNotSupported, - } - return nvptx; } pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*NvPtx { if (!build_options.have_llvm) @panic("nvptx target requires a zig compiler with llvm enabled."); - if (!options.use_llvm) return error.TODOArchNotSupported; + if (!options.use_llvm) return error.PtxArchNotSupported; assert(options.object_format == .nvptx); const nvptx = try createEmpty(allocator, options); - errdefer nvptx.base.destroy(); log.info("Opening .ptx target file {s}", .{sub_path}); - nvptx.llvm_object = try LlvmObject.create(allocator, options); return nvptx; } @@ -117,6 +117,5 @@ pub fn flushModule(self: *NvPtx, comp: *Compilation) !void { }; hack_comp.bin_file.options.emit = null; } - return try self.llvm_object.flushModule(hack_comp); } diff --git a/src/test.zig b/src/test.zig index a540d566eb..972bd7bcbd 100644 --- a/src/test.zig +++ b/src/test.zig @@ -175,6 +175,7 @@ pub const TestContext = struct { is_test: bool = false, expect_exact: bool = false, backend: Backend = .stage2, + link_libc: bool = false, files: std.ArrayList(File), @@ -331,6 +332,7 @@ pub const TestContext = struct { .output_mode = .Exe, .files = std.ArrayList(File).init(ctx.cases.allocator), .backend = .llvm, + .link_libc = true, }) catch @panic("out of memory"); return &ctx.cases.items[ctx.cases.items.len - 1]; } @@ -888,11 +890,6 @@ pub const TestContext = struct { .llvm => true, else => null, }; - const use_stage1: ?bool = switch (case.backend) { - .stage1 => true, - else => null, - }; - const link_libc = case.backend == .llvm; const comp = try Compilation.create(allocator, .{ .local_cache_directory = zig_cache_directory, .global_cache_directory = global_cache_directory, @@ -914,9 +911,9 @@ pub const TestContext = struct { .is_native_os = case.target.isNativeOs(), .is_native_abi = case.target.isNativeAbi(), .dynamic_linker = target_info.dynamic_linker.get(), - .link_libc = link_libc, + .link_libc = case.link_libc, .use_llvm = use_llvm, - .use_stage1 = use_stage1, + .use_stage1 = null, // We already handled stage1 tests .self_exe_path = std.testing.zig_exe_path, }); defer comp.destroy(); @@ -1145,7 +1142,7 @@ pub const TestContext = struct { "-lc", exe_path, }); - } else switch (host.getExternalExecutor(target_info, .{ .link_libc = link_libc })) { + } else switch (host.getExternalExecutor(target_info, .{ .link_libc = case.link_libc })) { .native => try argv.append(exe_path), .bad_dl, .bad_os_or_cpu => return, // Pass test. @@ -1156,8 +1153,7 @@ pub const TestContext = struct { }, .qemu => |qemu_bin_name| if (enable_qemu) { - // TODO Ability for test cases to specify whether to link libc. - const need_cross_glibc = false; // target.isGnuLibC() and self.is_linking_libc; + const need_cross_glibc = target.isGnuLibC() and case.link_libc; const glibc_dir_arg = if (need_cross_glibc) glibc_runtimes_dir orelse return // glibc dir not available; pass test else diff --git a/test/cases.zig b/test/cases.zig index 994781132e..a65baeeef6 100644 --- a/test/cases.zig +++ b/test/cases.zig @@ -16,6 +16,5 @@ pub fn addCases(ctx: *TestContext) !void { try @import("stage2/riscv64.zig").addCases(ctx); try @import("stage2/plan9.zig").addCases(ctx); try @import("stage2/x86_64.zig").addCases(ctx); - // TODO https://github.com/ziglang/zig/issues/10968 - //try @import("stage2/nvptx.zig").addCases(ctx); + try @import("stage2/nvptx.zig").addCases(ctx); } diff --git a/test/stage2/nvptx.zig b/test/stage2/nvptx.zig index 95ca79d448..7182092be7 100644 --- a/test/stage2/nvptx.zig +++ b/test/stage2/nvptx.zig @@ -1,21 +1,16 @@ const std = @import("std"); const TestContext = @import("../../src/test.zig").TestContext; -const nvptx = std.zig.CrossTarget{ - .cpu_arch = .nvptx64, - .os_tag = .cuda, -}; - pub fn addCases(ctx: *TestContext) !void { { - var case = ctx.exeUsingLlvmBackend("simple addition and subtraction", nvptx); + var case = addPtx(ctx, "nvptx: simple addition and subtraction"); case.compiles( \\fn add(a: i32, b: i32) i32 { \\ return a + b; \\} \\ - \\pub export fn main(a: i32, out: *i32) callconv(.PtxKernel) void { + \\pub export fn add_and_substract(a: i32, out: *i32) callconv(.PtxKernel) void { \\ const x = add(a, 7); \\ var y = add(2, 0); \\ y -= x; @@ -25,28 +20,28 @@ pub fn addCases(ctx: *TestContext) !void { } { - var case = ctx.exeUsingLlvmBackend("read special registers", nvptx); + var case = addPtx(ctx, "nvptx: read special registers"); case.compiles( - \\fn tid() usize { + \\fn threadIdX() usize { \\ var tid = asm volatile ("mov.u32 \t$0, %tid.x;" \\ : [ret] "=r" (-> u32), \\ ); \\ return @as(usize, tid); \\} \\ - \\pub export fn main(a: []const i32, out: []i32) callconv(.PtxKernel) void { - \\ const i = tid(); + \\pub export fn special_reg(a: []const i32, out: []i32) callconv(.PtxKernel) void { + \\ const i = threadIdX(); \\ out[i] = a[i] + 7; \\} ); } { - var case = ctx.exeUsingLlvmBackend("address spaces", nvptx); + var case = addPtx(ctx, "nvptx: address spaces"); case.compiles( - \\var x: u32 addrspace(.global) = 0; + \\var x: i32 addrspace(.global) = 0; \\ \\pub export fn increment(out: *i32) callconv(.PtxKernel) void { \\ x += 1; @@ -55,3 +50,24 @@ pub fn addCases(ctx: *TestContext) !void { ); } } + +const nvptx_target = std.zig.CrossTarget{ + .cpu_arch = .nvptx64, + .os_tag = .cuda, +}; + +pub fn addPtx( + ctx: *TestContext, + name: []const u8, +) *TestContext.Case { + ctx.cases.append(TestContext.Case{ + .name = name, + .target = nvptx_target, + .updates = std.ArrayList(TestContext.Update).init(ctx.cases.allocator), + .output_mode = .Obj, + .files = std.ArrayList(TestContext.File).init(ctx.cases.allocator), + .link_libc = false, + .backend = .llvm, + }) catch @panic("out of memory"); + return &ctx.cases.items[ctx.cases.items.len - 1]; +}