From 7d9edff11d4c0dd6793bfd4bb2d7e3c2d32c88cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 28 Aug 2024 03:02:04 +0200 Subject: [PATCH 1/3] llvm: Set PIC level 1 for MIPS. For hysterical raisins, MIPS always uses 1, regardless of `-fpic` vs `-fPIC`. --- src/codegen/llvm.zig | 7 +++++-- src/codegen/llvm/bindings.zig | 4 ++-- src/target.zig | 6 ++++++ src/zig_llvm.cpp | 10 +++++----- src/zig_llvm.h | 6 +++--- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index eec46b83798a..57ee1c8a6726 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1259,8 +1259,11 @@ pub const Object = struct { ); errdefer target_machine.dispose(); - if (pic) module.setModulePICLevel(); - if (comp.config.pie) module.setModulePIELevel(); + const large_pic = target_util.usesLargePIC(comp.root_mod.resolved_target.result); + + if (pic) module.setModulePICLevel(large_pic); + if (comp.config.pie) module.setModulePIELevel(large_pic); + if (code_model != .Default) module.setModuleCodeModel(code_model); if (comp.llvm_opt_bisect_limit >= 0) { diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index ebab18f68aaf..a5017568e541 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -53,10 +53,10 @@ pub const Module = opaque { extern fn LLVMDisposeModule(*Module) void; pub const setModulePICLevel = ZigLLVMSetModulePICLevel; - extern fn ZigLLVMSetModulePICLevel(module: *Module) void; + extern fn ZigLLVMSetModulePICLevel(module: *Module, big: bool) void; pub const setModulePIELevel = ZigLLVMSetModulePIELevel; - extern fn ZigLLVMSetModulePIELevel(module: *Module) void; + extern fn ZigLLVMSetModulePIELevel(module: *Module, large: bool) void; pub const setModuleCodeModel = ZigLLVMSetModuleCodeModel; extern fn ZigLLVMSetModuleCodeModel(module: *Module, code_model: CodeModel) void; diff --git a/src/target.zig b/src/target.zig index ba586dd7a09a..9147347f9357 100644 --- a/src/target.zig +++ b/src/target.zig @@ -49,6 +49,12 @@ pub fn requiresPIC(target: std.Target, linking_libc: bool) bool { (target.abi == .ohos and target.cpu.arch == .aarch64); } +pub fn usesLargePIC(target: std.Target) bool { + // MIPS always uses PIC level 1; other platforms vary in their default PIC levels, but they + // support both level 1 and 2, in which case we prefer 2. + return !target.cpu.arch.isMIPS(); +} + /// This is not whether the target supports Position Independent Code, but whether the -fPIC /// C compiler argument is valid to Clang. pub fn supports_fpic(target: std.Target) bool { diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 6fa6f028dcdf..b6b6d05f5760 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -81,7 +81,7 @@ static const bool assertions_on = false; LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, - LLVMCodeModel CodeModel, bool function_sections, bool data_sections, ZigLLVMABIType float_abi, + LLVMCodeModel CodeModel, bool function_sections, bool data_sections, ZigLLVMABIType float_abi, const char *abi_name) { std::optional RM; @@ -430,12 +430,12 @@ void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) { cl::ParseCommandLineOptions(argc, argv); } -void ZigLLVMSetModulePICLevel(LLVMModuleRef module) { - unwrap(module)->setPICLevel(PICLevel::Level::BigPIC); +void ZigLLVMSetModulePICLevel(LLVMModuleRef module, bool big) { + unwrap(module)->setPICLevel(big ? PICLevel::Level::BigPIC : PICLevel::Level::SmallPIC); } -void ZigLLVMSetModulePIELevel(LLVMModuleRef module) { - unwrap(module)->setPIELevel(PIELevel::Level::Large); +void ZigLLVMSetModulePIELevel(LLVMModuleRef module, bool large) { + unwrap(module)->setPIELevel(large ? PIELevel::Level::Large : PIELevel::Level::Small); } void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel code_model) { diff --git a/src/zig_llvm.h b/src/zig_llvm.h index d6af27cbab0f..cdc2adfb6d30 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -77,7 +77,7 @@ enum ZigLLVMABIType { ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, - LLVMCodeModel CodeModel, bool function_sections, bool data_sections, enum ZigLLVMABIType float_abi, + LLVMCodeModel CodeModel, bool function_sections, bool data_sections, enum ZigLLVMABIType float_abi, const char *abi_name); ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit); @@ -154,8 +154,8 @@ enum ZigLLVM_CallingConv { ZigLLVM_MaxID = 1023, }; -ZIG_EXTERN_C void ZigLLVMSetModulePICLevel(LLVMModuleRef module); -ZIG_EXTERN_C void ZigLLVMSetModulePIELevel(LLVMModuleRef module); +ZIG_EXTERN_C void ZigLLVMSetModulePICLevel(LLVMModuleRef module, bool big); +ZIG_EXTERN_C void ZigLLVMSetModulePIELevel(LLVMModuleRef module, bool large); ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel code_model); ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv); From e585103306f5b69a62c71e8462dc78a8ef2da9f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 28 Aug 2024 03:03:12 +0200 Subject: [PATCH 2/3] llvm: Disable FastISel on MIPS as a workaround for #21215. Until llvm/llvm-project#106231 trickles down. --- src/codegen/llvm.zig | 2 ++ src/codegen/llvm/bindings.zig | 1 + src/zig_llvm.cpp | 7 ++++++- src/zig_llvm.h | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 57ee1c8a6726..120618563e47 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1280,6 +1280,8 @@ pub const Object = struct { .tsan = options.sanitize_thread, .sancov = options.fuzz, .lto = options.lto, + // https://github.com/ziglang/zig/issues/21215 + .allow_fast_isel = !comp.root_mod.resolved_target.result.cpu.arch.isMIPS(), .asm_filename = null, .bin_filename = options.bin_path, .llvm_ir_filename = options.post_ir_path, diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index a5017568e541..08c5b0b0555d 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -91,6 +91,7 @@ pub const TargetMachine = opaque { tsan: bool, sancov: bool, lto: bool, + allow_fast_isel: bool, asm_filename: ?[*:0]const u8, bin_filename: ?[*:0]const u8, llvm_ir_filename: ?[*:0]const u8, diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index b6b6d05f5760..9465168dbdcd 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -258,7 +258,6 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi options.bin_filename? options.bin_filename : options.asm_filename); TargetMachine &target_machine = *reinterpret_cast(targ_machine_ref); - target_machine.setO0WantsFastISel(true); Module &llvm_module = *unwrap(module_ref); @@ -369,6 +368,12 @@ 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); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index cdc2adfb6d30..0935c780add9 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -59,6 +59,7 @@ struct ZigLLVMEmitOptions { bool tsan; bool sancov; bool lto; + bool allow_fast_isel; const char *asm_filename; const char *bin_filename; const char *llvm_ir_filename; From a2e691d589ac1d234ee624fdf8fa931d89a719b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 27 Aug 2024 08:32:36 +0200 Subject: [PATCH 3/3] Revert "add a workaround for miscompilation regarding alignment" This reverts commit 149aa9afb7b57340c5dd7be8032b843fe439b668. --- lib/std/zig/Server.zig | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/lib/std/zig/Server.zig b/lib/std/zig/Server.zig index 0ed9cfcd0b12..7b69cefffbc0 100644 --- a/lib/std/zig/Server.zig +++ b/lib/std/zig/Server.zig @@ -124,9 +124,9 @@ pub fn receiveMessage(s: *Server) !InMessage.Header { const buf = fifo.readableSlice(0); assert(fifo.readableLength() == buf.len); if (buf.len >= @sizeOf(Header)) { - // workaround for https://github.com/ziglang/zig/issues/14904 - const bytes_len = bswap_and_workaround_u32(buf[4..][0..4]); - const tag = bswap_and_workaround_tag(buf[0..][0..4]); + const header: *align(1) const Header = @ptrCast(buf[0..@sizeOf(Header)]); + const bytes_len = bswap(header.bytes_len); + const tag = bswap(header.tag); if (buf.len - @sizeOf(Header) >= bytes_len) { fifo.discard(@sizeOf(Header)); @@ -307,17 +307,6 @@ fn bswap_u32_array(slice: []u32) void { for (slice) |*elem| elem.* = @byteSwap(elem.*); } -/// workaround for https://github.com/ziglang/zig/issues/14904 -fn bswap_and_workaround_u32(bytes_ptr: *const [4]u8) u32 { - return std.mem.readInt(u32, bytes_ptr, .little); -} - -/// workaround for https://github.com/ziglang/zig/issues/14904 -fn bswap_and_workaround_tag(bytes_ptr: *const [4]u8) InMessage.Tag { - const int = std.mem.readInt(u32, bytes_ptr, .little); - return @as(InMessage.Tag, @enumFromInt(int)); -} - const OutMessage = std.zig.Server.Message; const InMessage = std.zig.Client.Message;