Skip to content

Commit

Permalink
llvm: fix and test datalayout generation for more targets
Browse files Browse the repository at this point in the history
Closes #16482
  • Loading branch information
jacobly0 committed Jul 23, 2023
1 parent 15386f5 commit 0f7de4c
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 33 deletions.
4 changes: 3 additions & 1 deletion lib/std/Build/Step.zig
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ pub fn evalZigProcess(
s: *Step,
argv: []const []const u8,
prog_node: *std.Progress.Node,
) ![]const u8 {
) !?[]const u8 {
assert(argv.len != 0);
const b = s.owner;
const arena = b.allocator;
Expand Down Expand Up @@ -423,6 +423,8 @@ pub fn evalZigProcess(
});
}

if (s.cast(Compile)) |compile| if (compile.emit_bin == .no_emit) return result;

return result orelse return s.fail(
"the following command failed to communicate the compilation result:\n{s}",
.{try allocPrintCmd(arena, null, argv)},
Expand Down
7 changes: 4 additions & 3 deletions lib/std/Build/Step/Compile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1997,18 +1997,19 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try zig_args.append(resolved_args_file);
}

const output_bin_path = step.evalZigProcess(zig_args.items, prog_node) catch |err| switch (err) {
const maybe_output_bin_path = step.evalZigProcess(zig_args.items, prog_node) catch |err| switch (err) {
error.NeedCompileErrorCheck => {
assert(self.expect_errors.len != 0);
try checkCompileErrors(self);
return;
},
else => |e| return e,
};
const output_dir = fs.path.dirname(output_bin_path).?;

// Update generated files
{
if (maybe_output_bin_path) |output_bin_path| {
const output_dir = fs.path.dirname(output_bin_path).?;

self.output_dirname_source.path = output_dir;

self.output_path_source.path = b.pathJoin(
Expand Down
4 changes: 2 additions & 2 deletions lib/std/Build/Step/TranslateC.zig
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {

const output_path = try step.evalZigProcess(argv_list.items, prog_node);

self.out_basename = fs.path.basename(output_path);
const output_dir = fs.path.dirname(output_path).?;
self.out_basename = fs.path.basename(output_path.?);
const output_dir = fs.path.dirname(output_path.?).?;

self.output_file.path = try fs.path.join(
b.allocator,
Expand Down
10 changes: 7 additions & 3 deletions lib/std/target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1912,7 +1912,7 @@ pub const Target = struct {
return switch (target.cpu.arch) {
.amdgcn => 4,
.x86 => switch (target.os.tag) {
.windows => 4,
.windows, .uefi => 4,
else => 16,
},
.arm,
Expand All @@ -1931,8 +1931,6 @@ pub const Target = struct {
.bpfel,
.mips64,
.mips64el,
.powerpc64,
.powerpc64le,
.riscv32,
.riscv64,
.sparc64,
Expand All @@ -1941,6 +1939,12 @@ pub const Target = struct {
.wasm32,
.wasm64,
=> 16,
.powerpc64,
.powerpc64le,
=> switch (target.os.tag) {
else => 8,
.linux => 16,
},
else => @divExact(target.ptrBitWidth(), 8),
};
}
Expand Down
1 change: 1 addition & 0 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
buf.appendSliceAssumeCapacity(",");
}
}
if (buf.items.len == 0) break :blk "";
assert(mem.endsWith(u8, buf.items, ","));
buf.items[buf.items.len - 1] = 0;
buf.shrinkAndFree(buf.items.len);
Expand Down
61 changes: 37 additions & 24 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,6 @@ const DataLayoutBuilder = struct {
_: std.fmt.FormatOptions,
writer: anytype,
) @TypeOf(writer).Error!void {
const is_aarch64_windows = self.target.cpu.arch == .aarch64 and self.target.os.tag == .windows;
try writer.writeByte(switch (self.target.cpu.arch.endian()) {
.Little => 'e',
.Big => 'E',
Expand Down Expand Up @@ -407,7 +406,8 @@ const DataLayoutBuilder = struct {
};
if (self.target.cpu.arch == .aarch64_32) continue;
if (!info.force_in_data_layout and matches_default and
self.target.cpu.arch != .riscv64 and !is_aarch64_windows and
self.target.cpu.arch != .riscv64 and !(self.target.cpu.arch == .aarch64 and
(self.target.os.tag == .uefi or self.target.os.tag == .windows)) and
self.target.cpu.arch != .bpfeb and self.target.cpu.arch != .bpfel) continue;
try writer.writeAll("-p");
if (info.llvm != .default) try writer.print("{d}", .{@intFromEnum(info.llvm)});
Expand All @@ -423,7 +423,7 @@ const DataLayoutBuilder = struct {
if (self.target.cpu.arch == .s390x) try self.typeAlignment(.integer, 1, 8, 8, false, writer);
try self.typeAlignment(.integer, 8, 8, 8, false, writer);
try self.typeAlignment(.integer, 16, 16, 16, false, writer);
try self.typeAlignment(.integer, 32, if (is_aarch64_windows) 0 else 32, 32, false, writer);
try self.typeAlignment(.integer, 32, 32, 32, false, writer);
try self.typeAlignment(.integer, 64, 32, 64, false, writer);
try self.typeAlignment(.integer, 128, 32, 64, false, writer);
if (backendSupportsF16(self.target)) try self.typeAlignment(.float, 16, 16, 16, false, writer);
Expand Down Expand Up @@ -453,8 +453,15 @@ const DataLayoutBuilder = struct {
try self.typeAlignment(.vector, 128, 128, 128, true, writer);
},
}
if (self.target.os.tag != .windows and self.target.cpu.arch != .avr)
try self.typeAlignment(.aggregate, 0, 0, 64, false, writer);
const swap_agg_nat = switch (self.target.cpu.arch) {
.x86, .x86_64 => switch (self.target.os.tag) {
.uefi, .windows => true,
else => false,
},
.avr => true,
else => false,
};
if (!swap_agg_nat) try self.typeAlignment(.aggregate, 0, 0, 64, false, writer);
for (@as([]const u24, switch (self.target.cpu.arch) {
.avr => &.{8},
.msp430 => &.{ 8, 16 },
Expand Down Expand Up @@ -498,6 +505,7 @@ const DataLayoutBuilder = struct {
0 => try writer.print("-n{d}", .{natural}),
else => try writer.print(":{d}", .{natural}),
};
if (swap_agg_nat) try self.typeAlignment(.aggregate, 0, 0, 64, false, writer);
if (self.target.cpu.arch == .hexagon) {
try self.typeAlignment(.integer, 64, 64, 64, true, writer);
try self.typeAlignment(.integer, 32, 32, 32, true, writer);
Expand All @@ -506,11 +514,9 @@ const DataLayoutBuilder = struct {
try self.typeAlignment(.float, 32, 32, 32, true, writer);
try self.typeAlignment(.float, 64, 64, 64, true, writer);
}
if (self.target.os.tag == .windows or self.target.cpu.arch == .avr)
try self.typeAlignment(.aggregate, 0, 0, 64, false, writer);
const stack_abi = self.target.stackAlignment() * 8;
if (self.target.os.tag == .windows or self.target.cpu.arch == .msp430 or
stack_abi != ptr_bit_width)
if (self.target.os.tag == .uefi or self.target.os.tag == .windows or
self.target.cpu.arch == .msp430 or stack_abi != ptr_bit_width)
try writer.print("-S{d}", .{stack_abi});
switch (self.target.cpu.arch) {
.hexagon, .ve => {
Expand Down Expand Up @@ -571,22 +577,21 @@ const DataLayoutBuilder = struct {
.integer => {
if (self.target.ptrBitWidth() <= 16 and size >= 128) return;
abi = @min(abi, self.target.maxIntAlignment() * 8);
switch (self.target.os.tag) {
.linux => switch (self.target.cpu.arch) {
.aarch64,
.aarch64_be,
.aarch64_32,
.mips,
.mipsel,
=> pref = @max(pref, 32),
else => {},
},
else => {},
}
switch (self.target.cpu.arch) {
.aarch64,
.aarch64_be,
.aarch64_32,
=> if (size == 128) {
abi = size;
pref = size;
} else switch (self.target.os.tag) {
.macos => {},
.uefi, .windows => {
pref = size;
force_abi = size >= 32;
},
else => pref = @max(pref, 32),
},
.bpfeb,
.bpfel,
.nvptx,
Expand All @@ -597,6 +602,9 @@ const DataLayoutBuilder = struct {
pref = size;
},
.hexagon => force_abi = true,
.mips,
.mipsel,
=> pref = @max(pref, 32),
.mips64,
.mips64el,
=> if (size <= 32) {
Expand All @@ -617,7 +625,8 @@ const DataLayoutBuilder = struct {
128 => abi = 64,
else => {},
}
} else if ((self.target.cpu.arch.isPPC64() and (size == 256 or size == 512)) or
} else if ((self.target.cpu.arch.isPPC64() and self.target.os.tag == .linux and
(size == 256 or size == 512)) or
(self.target.cpu.arch.isNvptx() and (size == 16 or size == 32)))
{
force_abi = true;
Expand Down Expand Up @@ -646,17 +655,21 @@ const DataLayoutBuilder = struct {
.hexagon => if (size == 32 or size == 64) {
force_abi = true;
},
.aarch64_32 => if (size == 128) {
.aarch64_32, .amdgcn => if (size == 128) {
abi = size;
pref = size;
},
.wasm32, .wasm64 => if (self.target.os.tag == .emscripten and size == 128) {
abi = 64;
pref = 64;
},
.ve => if (size == 64) {
abi = size;
pref = size;
},
else => {},
},
.aggregate => if (self.target.os.tag == .windows or
.aggregate => if (self.target.os.tag == .uefi or self.target.os.tag == .windows or
self.target.cpu.arch.isARM() or self.target.cpu.arch.isThumb())
{
pref = @min(pref, self.target.ptrBitWidth());
Expand Down
1 change: 1 addition & 0 deletions test/cases.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ const Cases = @import("src/Cases.zig");
pub fn addCases(cases: *Cases) !void {
try @import("compile_errors.zig").addCases(cases);
try @import("cbe.zig").addCases(cases);
try @import("llvm_targets.zig").addCases(cases);
try @import("nvptx.zig").addCases(cases);
}
117 changes: 117 additions & 0 deletions test/llvm_targets.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const std = @import("std");
const Cases = @import("src/Cases.zig");

const targets = [_]std.zig.CrossTarget{
.{ .cpu_arch = .aarch64, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .aarch64, .os_tag = .macos, .abi = .none },
.{ .cpu_arch = .aarch64, .os_tag = .uefi, .abi = .none },
.{ .cpu_arch = .aarch64, .os_tag = .windows, .abi = .gnu },
.{ .cpu_arch = .aarch64, .os_tag = .windows, .abi = .msvc },
.{ .cpu_arch = .aarch64_be, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .aarch64_be, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .aarch64_32, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .aarch64_32, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .amdgcn, .os_tag = .amdhsa, .abi = .none },
.{ .cpu_arch = .amdgcn, .os_tag = .amdpal, .abi = .none },
.{ .cpu_arch = .amdgcn, .os_tag = .linux, .abi = .none },
//.{ .cpu_arch = .amdgcn, .os_tag = .mesa3d, .abi = .none },
.{ .cpu_arch = .arm, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .arm, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .arm, .os_tag = .uefi, .abi = .none },
.{ .cpu_arch = .armeb, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .armeb, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .avr, .os_tag = .freebsd, .abi = .none },
.{ .cpu_arch = .avr, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .avr, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .bpfel, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .bpfel, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .bpfeb, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .bpfeb, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .hexagon, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .mips, .os_tag = .linux, .abi = .gnueabihf },
.{ .cpu_arch = .mips, .os_tag = .linux, .abi = .musl },
.{ .cpu_arch = .mips, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .mipsel, .os_tag = .linux, .abi = .gnueabihf },
.{ .cpu_arch = .mipsel, .os_tag = .linux, .abi = .musl },
.{ .cpu_arch = .mipsel, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .mips64, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .mips64el, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .msp430, .os_tag = .freebsd, .abi = .none },
.{ .cpu_arch = .msp430, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .msp430, .os_tag = .linux, .abi = .none },
//.{ .cpu_arch = .nvptx, .os_tag = .cuda, .abi = .none },
//.{ .cpu_arch = .nvptx64, .os_tag = .cuda, .abi = .none },
.{ .cpu_arch = .powerpc, .os_tag = .freebsd, .abi = .none },
.{ .cpu_arch = .powerpc, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .powerpc, .os_tag = .linux, .abi = .gnueabihf },
.{ .cpu_arch = .powerpc, .os_tag = .linux, .abi = .musl },
.{ .cpu_arch = .powerpc, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .powerpcle, .os_tag = .freebsd, .abi = .none },
.{ .cpu_arch = .powerpcle, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .powerpcle, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .powerpcle, .os_tag = .linux, .abi = .musl },
.{ .cpu_arch = .powerpcle, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .powerpc64, .os_tag = .freebsd, .abi = .none },
.{ .cpu_arch = .powerpc64, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .powerpc64, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .powerpc64, .os_tag = .linux, .abi = .musl },
.{ .cpu_arch = .powerpc64, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .powerpc64le, .os_tag = .freebsd, .abi = .none },
.{ .cpu_arch = .powerpc64le, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .powerpc64le, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .powerpc64le, .os_tag = .linux, .abi = .musl },
.{ .cpu_arch = .powerpc64le, .os_tag = .linux, .abi = .none },
//.{ .cpu_arch = .r600, .os_tag = .mesa3d, .abi = .none },
.{ .cpu_arch = .riscv32, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .riscv32, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .riscv64, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .riscv64, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .riscv64, .os_tag = .linux, .abi = .musl },
.{ .cpu_arch = .riscv64, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .s390x, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .sparc, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .sparcel, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .sparcel, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .sparc64, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .sparc64, .os_tag = .linux, .abi = .gnu },
//.{ .cpu_arch = .spirv32, .os_tag = .opencl, .abi = .none },
//.{ .cpu_arch = .spirv32, .os_tag = .glsl450, .abi = .none },
//.{ .cpu_arch = .spirv32, .os_tag = .vulkan, .abi = .none },
//.{ .cpu_arch = .spirv64, .os_tag = .opencl, .abi = .none },
//.{ .cpu_arch = .spirv64, .os_tag = .glsl450, .abi = .none },
//.{ .cpu_arch = .spirv64, .os_tag = .vulkan, .abi = .none },
.{ .cpu_arch = .thumb, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .thumbeb, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .ve, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .wasm32, .os_tag = .emscripten, .abi = .none },
.{ .cpu_arch = .wasm32, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .wasm32, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .wasm32, .os_tag = .wasi, .abi = .none },
.{ .cpu_arch = .wasm64, .os_tag = .emscripten, .abi = .none },
.{ .cpu_arch = .wasm64, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .wasm64, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .wasm64, .os_tag = .wasi, .abi = .none },
.{ .cpu_arch = .x86, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .x86, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .x86, .os_tag = .uefi, .abi = .none },
.{ .cpu_arch = .x86, .os_tag = .windows, .abi = .gnu },
.{ .cpu_arch = .x86, .os_tag = .windows, .abi = .msvc },
.{ .cpu_arch = .x86_64, .os_tag = .freebsd, .abi = .none },
.{ .cpu_arch = .x86_64, .os_tag = .freestanding, .abi = .none },
.{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .none },
.{ .cpu_arch = .x86_64, .os_tag = .macos, .abi = .none },
.{ .cpu_arch = .x86_64, .os_tag = .uefi, .abi = .none },
.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu },
.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .msvc },
};

pub fn addCases(ctx: *Cases) !void {
for (targets) |target| {
var case = ctx.noEmitUsingLlvmBackend("llvm_targets", target);
case.addCompile("");
}
}
16 changes: 16 additions & 0 deletions test/src/Cases.zig
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub const Case = struct {
output_mode: std.builtin.OutputMode,
optimize_mode: std.builtin.Mode = .Debug,
updates: std.ArrayList(Update),
emit_bin: bool = true,
emit_h: bool = false,
is_test: bool = false,
expect_exact: bool = false,
Expand Down Expand Up @@ -176,6 +177,19 @@ pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Cas
return &ctx.cases.items[ctx.cases.items.len - 1];
}

pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
ctx.cases.append(Case{
.name = name,
.target = target,
.updates = std.ArrayList(Update).init(ctx.cases.allocator),
.output_mode = .Obj,
.emit_bin = false,
.deps = std.ArrayList(DepModule).init(ctx.arena),
.backend = .llvm,
}) catch @panic("out of memory");
return &ctx.cases.items[ctx.cases.items.len - 1];
}

/// Adds a test case that uses the LLVM backend to emit an executable.
/// Currently this implies linking libc, because only then we can generate a testable executable.
pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
Expand Down Expand Up @@ -537,6 +551,8 @@ pub fn lowerToBuildSteps(
}),
};

artifact.emit_bin = if (case.emit_bin) .default else .no_emit;

if (case.link_libc) artifact.linkLibC();

switch (case.backend) {
Expand Down

0 comments on commit 0f7de4c

Please sign in to comment.