Merge pull request #24302 from alexrp/riscv

Native RISC-V bootstrap and test fixes
This commit is contained in:
Alex Rønne Petersen
2025-07-02 04:15:10 +02:00
committed by GitHub
17 changed files with 142 additions and 20 deletions

View File

@@ -1,3 +1,4 @@
const builtin = @import("builtin");
const std = @import("std");
pub fn main() void {
@@ -5,6 +6,8 @@ pub fn main() void {
_ = &x;
const y = @shrExact(x, 2);
std.debug.print("value: {}\n", .{y});
if (builtin.cpu.arch.isRISCV() and builtin.zig_backend == .stage2_llvm) @panic("https://github.com/ziglang/zig/issues/24304");
}
// exe=fail

View File

@@ -150,7 +150,7 @@ bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
#endif
template <typename A>
typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
typename DwarfFDECache<A>::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
pint_t result = 0;
_LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
for (entry *p = _buffer; p < _bufferUsed; ++p) {

View File

@@ -2270,7 +2270,7 @@ const ElfDumper = struct {
try writer.print(" {s}", .{sym_bind});
}
const sym_vis = @as(elf.STV, @enumFromInt(sym.st_other));
const sym_vis = @as(elf.STV, @enumFromInt(@as(u2, @truncate(sym.st_other))));
try writer.print(" {s}", .{@tagName(sym_vis)});
const sym_name = switch (sym.st_type()) {

View File

@@ -1699,6 +1699,7 @@ fn testStaticBitSet(comptime Set: type) !void {
test IntegerBitSet {
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
if (comptime builtin.cpu.has(.riscv, .v) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/24300
try testStaticBitSet(IntegerBitSet(0));
try testStaticBitSet(IntegerBitSet(1));

View File

@@ -557,6 +557,8 @@ pub const SealedBox = struct {
const htest = @import("test.zig");
test "(x)salsa20" {
if (builtin.cpu.has(.riscv, .v) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/24299
const key = [_]u8{0x69} ** 32;
const nonce = [_]u8{0x42} ** 8;
const msg = [_]u8{0} ** 20;
@@ -600,6 +602,8 @@ test "xsalsa20poly1305 secretbox" {
}
test "xsalsa20poly1305 box" {
if (builtin.cpu.has(.riscv, .v) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/24299
var msg: [100]u8 = undefined;
var msg2: [msg.len]u8 = undefined;
var nonce: [Box.nonce_length]u8 = undefined;
@@ -614,6 +618,8 @@ test "xsalsa20poly1305 box" {
}
test "xsalsa20poly1305 sealedbox" {
if (builtin.cpu.has(.riscv, .v) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/24299
var msg: [100]u8 = undefined;
var msg2: [msg.len]u8 = undefined;
var boxed: [msg.len + SealedBox.seal_length]u8 = undefined;

View File

@@ -7,6 +7,8 @@ const SYS = linux.SYS;
const uid_t = std.os.linux.uid_t;
const gid_t = std.os.linux.gid_t;
const pid_t = std.os.linux.pid_t;
const stack_t = linux.stack_t;
const sigset_t = linux.sigset_t;
const sockaddr = linux.sockaddr;
const socklen_t = linux.socklen_t;
const timespec = std.os.linux.timespec;
@@ -261,8 +263,40 @@ pub const VDSO = struct {
pub const CGT_VER = "LINUX_4.15";
};
/// TODO
pub const ucontext_t = void;
pub const f_ext_state = extern struct {
f: [32]f32,
fcsr: u32,
};
pub const d_ext_state = extern struct {
f: [32]f64,
fcsr: u32,
};
pub const q_ext_state = extern struct {
f: [32]f128,
fcsr: u32,
_reserved: [3]u32,
};
pub const fpstate = extern union {
f: f_ext_state,
d: d_ext_state,
q: q_ext_state,
};
pub const mcontext_t = extern struct {
gregs: [32]u32,
fpregs: fpstate,
};
pub const ucontext_t = extern struct {
flags: c_ulong,
link: ?*ucontext_t,
stack: stack_t,
sigmask: [1024 / @bitSizeOf(c_ulong)]c_ulong, // Currently a libc-compatible (1024-bit) sigmask
mcontext: mcontext_t,
};
/// TODO
pub const getcontext = {};

View File

@@ -7,6 +7,8 @@ const SYS = linux.SYS;
const uid_t = std.os.linux.uid_t;
const gid_t = std.os.linux.gid_t;
const pid_t = std.os.linux.pid_t;
const stack_t = linux.stack_t;
const sigset_t = linux.sigset_t;
const sockaddr = linux.sockaddr;
const socklen_t = linux.socklen_t;
const timespec = std.os.linux.timespec;
@@ -261,8 +263,40 @@ pub const VDSO = struct {
pub const CGT_VER = "LINUX_4.15";
};
/// TODO
pub const ucontext_t = void;
pub const f_ext_state = extern struct {
f: [32]f32,
fcsr: u32,
};
pub const d_ext_state = extern struct {
f: [32]f64,
fcsr: u32,
};
pub const q_ext_state = extern struct {
f: [32]f128,
fcsr: u32,
_reserved: [3]u32,
};
pub const fpstate = extern union {
f: f_ext_state,
d: d_ext_state,
q: q_ext_state,
};
pub const mcontext_t = extern struct {
gregs: [32]u64,
fpregs: fpstate,
};
pub const ucontext_t = extern struct {
flags: c_ulong,
link: ?*ucontext_t,
stack: stack_t,
sigmask: [1024 / @bitSizeOf(c_ulong)]c_ulong, // Currently a libc-compatible (1024-bit) sigmask
mcontext: mcontext_t,
};
/// TODO
pub const getcontext = {};

View File

@@ -9,6 +9,8 @@ const std = @import("std");
const builtin = @import("builtin");
pub fn suggestVectorLengthForCpu(comptime T: type, comptime cpu: std.Target.Cpu) ?comptime_int {
@setEvalBranchQuota(2_000);
// This is guesswork, if you have better suggestions can add it or edit the current here
const element_bit_size = @max(8, std.math.ceilPowerOfTwo(u16, @bitSizeOf(T)) catch unreachable);
const vector_bit_size: u16 = blk: {

View File

@@ -76,9 +76,11 @@ const RiscvCpuinfoImpl = struct {
const cpu_names = .{
.{ "sifive,u54", &Target.riscv.cpu.sifive_u54 },
.{ "sifive,u54-mc", &Target.riscv.cpu.sifive_u54 },
.{ "sifive,u7", &Target.riscv.cpu.sifive_7_series },
.{ "sifive,u74", &Target.riscv.cpu.sifive_u74 },
.{ "sifive,u74-mc", &Target.riscv.cpu.sifive_u74 },
.{ "spacemit,x60", &Target.riscv.cpu.spacemit_x60 },
};
fn line_hook(self: *RiscvCpuinfoImpl, key: []const u8, value: []const u8) !bool {

View File

@@ -1068,6 +1068,9 @@ pub const Object = struct {
.full => .FullPreLink,
},
.allow_fast_isel = true,
// LLVM's RISC-V backend for some reason enables the machine outliner by default even
// though it's clearly not ready and produces multiple miscompilations in our std tests.
.allow_machine_outliner = !comp.root_mod.resolved_target.result.cpu.arch.isRISCV(),
.asm_filename = null,
.bin_filename = options.bin_path,
.llvm_ir_filename = options.post_ir_path,
@@ -6831,8 +6834,8 @@ pub const FuncGen = struct {
self.maybeMarkAllowZeroAccess(slice_ty.ptrInfo(zcu));
const elem_alignment = elem_ty.abiAlignment(zcu).toLlvm();
return self.loadByRef(ptr, elem_ty, elem_alignment, if (slice_ty.isVolatilePtr(zcu)) .@"volatile" else .normal);
const slice_align = (slice_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm();
return self.loadByRef(ptr, elem_ty, slice_align, if (slice_ty.isVolatilePtr(zcu)) .@"volatile" else .normal);
}
self.maybeMarkAllowZeroAccess(slice_ty.ptrInfo(zcu));
@@ -6909,8 +6912,8 @@ pub const FuncGen = struct {
self.maybeMarkAllowZeroAccess(ptr_ty.ptrInfo(zcu));
const elem_alignment = elem_ty.abiAlignment(zcu).toLlvm();
return self.loadByRef(ptr, elem_ty, elem_alignment, if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal);
const ptr_align = (ptr_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm();
return self.loadByRef(ptr, elem_ty, ptr_align, if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal);
}
self.maybeMarkAllowZeroAccess(ptr_ty.ptrInfo(zcu));

View File

@@ -92,6 +92,7 @@ pub const TargetMachine = opaque {
sancov: bool,
lto: LtoPhase,
allow_fast_isel: bool,
allow_machine_outliner: bool,
asm_filename: ?[*:0]const u8,
bin_filename: ?[*:0]const u8,
llvm_ir_filename: ?[*:0]const u8,

View File

@@ -260,6 +260,16 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
TargetMachine &target_machine = *reinterpret_cast<TargetMachine*>(targ_machine_ref);
if (options->allow_fast_isel) {
target_machine.setO0WantsFastISel(true);
} else {
target_machine.setFastISel(false);
}
if (!options->allow_machine_outliner) {
target_machine.setMachineOutliner(false);
}
Module &llvm_module = *unwrap(module_ref);
// Pipeline configurations
@@ -385,12 +395,6 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
}
}
if (options->allow_fast_isel) {
target_machine.setO0WantsFastISel(true);
} else {
target_machine.setFastISel(false);
}
// Optimization phase
module_pm.run(llvm_module, module_am);

View File

@@ -71,6 +71,7 @@ struct ZigLLVMEmitOptions {
bool sancov;
ZigLLVMThinOrFullLTOPhase lto;
bool allow_fast_isel;
bool allow_machine_outliner;
const char *asm_filename;
const char *bin_filename;
const char *llvm_ir_filename;

View File

@@ -560,6 +560,7 @@ test "vector division operators" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (comptime builtin.cpu.has(.riscv, .v) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/24301
const S = struct {
fn doTheTestDiv(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {

View File

@@ -33,7 +33,7 @@ pub fn build(b: *std.Build) void {
}
// Build & run a C test case against a sampling of supported glibc versions
for ([_][]const u8{
versions: for ([_][]const u8{
// "native-linux-gnu.2.0", // fails with a pile of missing symbols.
"native-linux-gnu.2.2.5",
"native-linux-gnu.2.4",
@@ -52,9 +52,14 @@ pub fn build(b: *std.Build) void {
const glibc_ver = target.result.os.version_range.linux.glibc;
// only build test if glibc version supports the architecture
if (target.result.cpu.arch.isAARCH64()) {
if (glibc_ver.order(.{ .major = 2, .minor = 17, .patch = 0 }) == .lt) {
for (std.zig.target.available_libcs) |libc| {
if (libc.arch != target.result.cpu.arch or
libc.os != target.result.os.tag or
libc.abi != target.result.abi)
continue;
if (libc.glibc_min) |min| {
if (glibc_ver.order(min) == .lt) continue :versions;
}
}
@@ -147,7 +152,7 @@ pub fn build(b: *std.Build) void {
}
// Build & run a Zig test case against a sampling of supported glibc versions
for ([_][]const u8{
versions: for ([_][]const u8{
"native-linux-gnu.2.17", // Currently oldest supported, see #17769
"native-linux-gnu.2.23",
"native-linux-gnu.2.28",
@@ -161,6 +166,18 @@ pub fn build(b: *std.Build) void {
const glibc_ver = target.result.os.version_range.linux.glibc;
// only build test if glibc version supports the architecture
for (std.zig.target.available_libcs) |libc| {
if (libc.arch != target.result.cpu.arch or
libc.os != target.result.os.tag or
libc.abi != target.result.abi)
continue;
if (libc.glibc_min) |min| {
if (glibc_ver.order(min) == .lt) continue :versions;
}
}
const exe = b.addExecutable(.{
.name = t,
.root_module = b.createModule(.{

View File

@@ -3,6 +3,14 @@ const builtin = @import("builtin");
/// This tests the path where DWARF information is embedded in a COFF binary
pub fn build(b: *std.Build) void {
switch (builtin.cpu.arch) {
.aarch64,
.x86,
.x86_64,
=> {},
else => return,
}
const test_step = b.step("test", "Test it");
b.default_step = test_step;

View File

@@ -8,6 +8,11 @@ pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
if (target.result.cpu.arch.isRISCV() and target.result.os.tag == .linux) {
// https://github.com/ziglang/zig/issues/24310
return;
}
// Unwinding with a frame pointer
//
// getcontext version: zig std