authorgravatar for gwenzek@users.noreply.github.comGuillaume Wenzek <gwenzek@users.noreply.github.com> 2022-03-01 23:26:43+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-12 14:25:59-05:00
logf000f8a59a8bf1121ecbe9b60ae50cc0218d3ba3
treef4578be5065b377c3c158562206311ed4d28f99d
parent5ff7b04a6ad72eb86b6d467dfdc25bea1a9ecf63

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`

4 files changed, 52 insertions(+), 42 deletions(-)

src/link/NvPtx.zig+16-17
...@@ -25,8 +25,21 @@ base: link.File,...@@ -25,8 +25,21 @@ base: link.File,
25llvm_object: *LlvmObject,25llvm_object: *LlvmObject,
2626
27pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx {27pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx {
28 if (!build_options.have_llvm) return error.TODOArchNotSupported;28 if (!build_options.have_llvm) return error.PtxArchNotSupported;
29 if (!options.use_llvm) return error.PtxArchNotSupported;
2930
31 switch (options.target.cpu.arch) {
32 .nvptx, .nvptx64 => {},
33 else => return error.PtxArchNotSupported,
34 }
35
36 switch (options.target.os.tag) {
37 // TODO: does it also work with nvcl ?
38 .cuda => {},
39 else => return error.PtxArchNotSupported,
40 }
41
42 const llvm_object = try LlvmObject.create(gpa, options);
30 const nvptx = try gpa.create(NvPtx);43 const nvptx = try gpa.create(NvPtx);
31 nvptx.* = .{44 nvptx.* = .{
32 .base = .{45 .base = .{
...@@ -35,32 +48,19 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx {...@@ -35,32 +48,19 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx {
35 .file = null,48 .file = null,
36 .allocator = gpa,49 .allocator = gpa,
37 },50 },
38 .llvm_object = undefined,51 .llvm_object = llvm_object,
39 };52 };
4053
41 switch (options.target.cpu.arch) {
42 .nvptx, .nvptx64 => {},
43 else => return error.TODOArchNotSupported,
44 }
45
46 switch (options.target.os.tag) {
47 // TODO: does it also work with nvcl ?
48 .cuda => {},
49 else => return error.TODOOsNotSupported,
50 }
51
52 return nvptx;54 return nvptx;
53}55}
5456
55pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*NvPtx {57pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*NvPtx {
56 if (!build_options.have_llvm) @panic("nvptx target requires a zig compiler with llvm enabled.");58 if (!build_options.have_llvm) @panic("nvptx target requires a zig compiler with llvm enabled.");
57 if (!options.use_llvm) return error.TODOArchNotSupported;59 if (!options.use_llvm) return error.PtxArchNotSupported;
58 assert(options.object_format == .nvptx);60 assert(options.object_format == .nvptx);
5961
60 const nvptx = try createEmpty(allocator, options);62 const nvptx = try createEmpty(allocator, options);
61 errdefer nvptx.base.destroy();
62 log.info("Opening .ptx target file {s}", .{sub_path});63 log.info("Opening .ptx target file {s}", .{sub_path});
63 nvptx.llvm_object = try LlvmObject.create(allocator, options);
64 return nvptx;64 return nvptx;
65}65}
6666
...@@ -117,6 +117,5 @@ pub fn flushModule(self: *NvPtx, comp: *Compilation) !void {...@@ -117,6 +117,5 @@ pub fn flushModule(self: *NvPtx, comp: *Compilation) !void {
117 };117 };
118 hack_comp.bin_file.options.emit = null;118 hack_comp.bin_file.options.emit = null;
119 }119 }
120
121 return try self.llvm_object.flushModule(hack_comp);120 return try self.llvm_object.flushModule(hack_comp);
122}121}
src/test.zig+6-10
...@@ -175,6 +175,7 @@ pub const TestContext = struct {...@@ -175,6 +175,7 @@ pub const TestContext = struct {
175 is_test: bool = false,175 is_test: bool = false,
176 expect_exact: bool = false,176 expect_exact: bool = false,
177 backend: Backend = .stage2,177 backend: Backend = .stage2,
178 link_libc: bool = false,
178179
179 files: std.ArrayList(File),180 files: std.ArrayList(File),
180181
...@@ -331,6 +332,7 @@ pub const TestContext = struct {...@@ -331,6 +332,7 @@ pub const TestContext = struct {
331 .output_mode = .Exe,332 .output_mode = .Exe,
332 .files = std.ArrayList(File).init(ctx.cases.allocator),333 .files = std.ArrayList(File).init(ctx.cases.allocator),
333 .backend = .llvm,334 .backend = .llvm,
335 .link_libc = true,
334 }) catch @panic("out of memory");336 }) catch @panic("out of memory");
335 return &ctx.cases.items[ctx.cases.items.len - 1];337 return &ctx.cases.items[ctx.cases.items.len - 1];
336 }338 }
...@@ -888,11 +890,6 @@ pub const TestContext = struct {...@@ -888,11 +890,6 @@ pub const TestContext = struct {
888 .llvm => true,890 .llvm => true,
889 else => null,891 else => null,
890 };892 };
891 const use_stage1: ?bool = switch (case.backend) {
892 .stage1 => true,
893 else => null,
894 };
895 const link_libc = case.backend == .llvm;
896 const comp = try Compilation.create(allocator, .{893 const comp = try Compilation.create(allocator, .{
897 .local_cache_directory = zig_cache_directory,894 .local_cache_directory = zig_cache_directory,
898 .global_cache_directory = global_cache_directory,895 .global_cache_directory = global_cache_directory,
...@@ -914,9 +911,9 @@ pub const TestContext = struct {...@@ -914,9 +911,9 @@ pub const TestContext = struct {
914 .is_native_os = case.target.isNativeOs(),911 .is_native_os = case.target.isNativeOs(),
915 .is_native_abi = case.target.isNativeAbi(),912 .is_native_abi = case.target.isNativeAbi(),
916 .dynamic_linker = target_info.dynamic_linker.get(),913 .dynamic_linker = target_info.dynamic_linker.get(),
917 .link_libc = link_libc,914 .link_libc = case.link_libc,
918 .use_llvm = use_llvm,915 .use_llvm = use_llvm,
919 .use_stage1 = use_stage1,916 .use_stage1 = null, // We already handled stage1 tests
920 .self_exe_path = std.testing.zig_exe_path,917 .self_exe_path = std.testing.zig_exe_path,
921 });918 });
922 defer comp.destroy();919 defer comp.destroy();
...@@ -1145,7 +1142,7 @@ pub const TestContext = struct {...@@ -1145,7 +1142,7 @@ pub const TestContext = struct {
1145 "-lc",1142 "-lc",
1146 exe_path,1143 exe_path,
1147 });1144 });
1148 } else switch (host.getExternalExecutor(target_info, .{ .link_libc = link_libc })) {1145 } else switch (host.getExternalExecutor(target_info, .{ .link_libc = case.link_libc })) {
1149 .native => try argv.append(exe_path),1146 .native => try argv.append(exe_path),
1150 .bad_dl, .bad_os_or_cpu => return, // Pass test.1147 .bad_dl, .bad_os_or_cpu => return, // Pass test.
11511148
...@@ -1156,8 +1153,7 @@ pub const TestContext = struct {...@@ -1156,8 +1153,7 @@ pub const TestContext = struct {
1156 },1153 },
11571154
1158 .qemu => |qemu_bin_name| if (enable_qemu) {1155 .qemu => |qemu_bin_name| if (enable_qemu) {
1159 // TODO Ability for test cases to specify whether to link libc.1156 const need_cross_glibc = target.isGnuLibC() and case.link_libc;
1160 const need_cross_glibc = false; // target.isGnuLibC() and self.is_linking_libc;
1161 const glibc_dir_arg = if (need_cross_glibc)1157 const glibc_dir_arg = if (need_cross_glibc)
1162 glibc_runtimes_dir orelse return // glibc dir not available; pass test1158 glibc_runtimes_dir orelse return // glibc dir not available; pass test
1163 else1159 else
test/cases.zig+1-2
...@@ -16,6 +16,5 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -16,6 +16,5 @@ pub fn addCases(ctx: *TestContext) !void {
16 try @import("stage2/riscv64.zig").addCases(ctx);16 try @import("stage2/riscv64.zig").addCases(ctx);
17 try @import("stage2/plan9.zig").addCases(ctx);17 try @import("stage2/plan9.zig").addCases(ctx);
18 try @import("stage2/x86_64.zig").addCases(ctx);18 try @import("stage2/x86_64.zig").addCases(ctx);
19 // TODO https://github.com/ziglang/zig/issues/1096819 try @import("stage2/nvptx.zig").addCases(ctx);
20 //try @import("stage2/nvptx.zig").addCases(ctx);
21}20}
test/stage2/nvptx.zig+29-13
...@@ -1,21 +1,16 @@...@@ -1,21 +1,16 @@
1const std = @import("std");1const std = @import("std");
2const TestContext = @import("../../src/test.zig").TestContext;2const TestContext = @import("../../src/test.zig").TestContext;
33
4const nvptx = std.zig.CrossTarget{
5 .cpu_arch = .nvptx64,
6 .os_tag = .cuda,
7};
8
9pub fn addCases(ctx: *TestContext) !void {4pub fn addCases(ctx: *TestContext) !void {
10 {5 {
11 var case = ctx.exeUsingLlvmBackend("simple addition and subtraction", nvptx);6 var case = addPtx(ctx, "nvptx: simple addition and subtraction");
127
13 case.compiles(8 case.compiles(
14 \\fn add(a: i32, b: i32) i32 {9 \\fn add(a: i32, b: i32) i32 {
15 \\ return a + b;10 \\ return a + b;
16 \\}11 \\}
17 \\12 \\
18 \\pub export fn main(a: i32, out: *i32) callconv(.PtxKernel) void {13 \\pub export fn add_and_substract(a: i32, out: *i32) callconv(.PtxKernel) void {
19 \\ const x = add(a, 7);14 \\ const x = add(a, 7);
20 \\ var y = add(2, 0);15 \\ var y = add(2, 0);
21 \\ y -= x;16 \\ y -= x;
...@@ -25,28 +20,28 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -25,28 +20,28 @@ pub fn addCases(ctx: *TestContext) !void {
25 }20 }
2621
27 {22 {
28 var case = ctx.exeUsingLlvmBackend("read special registers", nvptx);23 var case = addPtx(ctx, "nvptx: read special registers");
2924
30 case.compiles(25 case.compiles(
31 \\fn tid() usize {26 \\fn threadIdX() usize {
32 \\ var tid = asm volatile ("mov.u32 \t$0, %tid.x;"27 \\ var tid = asm volatile ("mov.u32 \t$0, %tid.x;"
33 \\ : [ret] "=r" (-> u32),28 \\ : [ret] "=r" (-> u32),
34 \\ );29 \\ );
35 \\ return @as(usize, tid);30 \\ return @as(usize, tid);
36 \\}31 \\}
37 \\32 \\
38 \\pub export fn main(a: []const i32, out: []i32) callconv(.PtxKernel) void {33 \\pub export fn special_reg(a: []const i32, out: []i32) callconv(.PtxKernel) void {
39 \\ const i = tid();34 \\ const i = threadIdX();
40 \\ out[i] = a[i] + 7;35 \\ out[i] = a[i] + 7;
41 \\}36 \\}
42 );37 );
43 }38 }
4439
45 {40 {
46 var case = ctx.exeUsingLlvmBackend("address spaces", nvptx);41 var case = addPtx(ctx, "nvptx: address spaces");
4742
48 case.compiles(43 case.compiles(
49 \\var x: u32 addrspace(.global) = 0;44 \\var x: i32 addrspace(.global) = 0;
50 \\45 \\
51 \\pub export fn increment(out: *i32) callconv(.PtxKernel) void {46 \\pub export fn increment(out: *i32) callconv(.PtxKernel) void {
52 \\ x += 1;47 \\ x += 1;
...@@ -55,3 +50,24 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -55,3 +50,24 @@ pub fn addCases(ctx: *TestContext) !void {
55 );50 );
56 }51 }
57}52}
53
54const nvptx_target = std.zig.CrossTarget{
55 .cpu_arch = .nvptx64,
56 .os_tag = .cuda,
57};
58
59pub fn addPtx(
60 ctx: *TestContext,
61 name: []const u8,
62) *TestContext.Case {
63 ctx.cases.append(TestContext.Case{
64 .name = name,
65 .target = nvptx_target,
66 .updates = std.ArrayList(TestContext.Update).init(ctx.cases.allocator),
67 .output_mode = .Obj,
68 .files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),
69 .link_libc = false,
70 .backend = .llvm,
71 }) catch @panic("out of memory");
72 return &ctx.cases.items[ctx.cases.items.len - 1];
73}