diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-01-17 13:21:30 -0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-01-17 13:21:30 -0800 |
| commit | acf70439551fc3f49b2d292ff93ee519901cdf42 (patch) | |
| tree | b70f5c87c1b023e7a4acc5d8ae32429657d9a967 /lib | |
| parent | 59acfb12635b79fd83950eed10172cf43694b978 (diff) | |
| download | zig-acf70439551fc3f49b2d292ff93ee519901cdf42.tar.gz zig-acf70439551fc3f49b2d292ff93ee519901cdf42.zip | |
work around llvm failing to lower memcpy
triggers an assertion in LegalizeDAG otherwise
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/compiler_rt/memcpy.zig | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/lib/compiler_rt/memcpy.zig b/lib/compiler_rt/memcpy.zig index 614bcc7182..c540e81638 100644 --- a/lib/compiler_rt/memcpy.zig +++ b/lib/compiler_rt/memcpy.zig @@ -9,12 +9,36 @@ comptime { } } +const llvm_cannot_lower = switch (builtin.cpu.arch) { + .arm, .armeb, .thumb, .thumbeb => builtin.zig_backend == .stage2_llvm, + else => false, +}; + fn memcpy(noalias opt_dest: ?[*]u8, noalias opt_src: ?[*]const u8, len: usize) callconv(.C) ?[*]u8 { - return memmove(opt_dest, opt_src, len); + if (llvm_cannot_lower) { + for (0..len) |i| opt_dest.?[i] = opt_src.?[i]; + return opt_dest; + } else { + return memmove(opt_dest, opt_src, len); + } } +/// A port of https://github.com/facebook/folly/blob/1c8bc50e88804e2a7361a57cd9b551dd10f6c5fd/folly/memcpy.S fn memmove(opt_dest: ?[*]u8, opt_src: ?[*]const u8, len: usize) callconv(.C) ?[*]u8 { - // a port of https://github.com/facebook/folly/blob/1c8bc50e88804e2a7361a57cd9b551dd10f6c5fd/folly/memcpy.S + if (llvm_cannot_lower) { + if (@intFromPtr(opt_dest) < @intFromPtr(opt_src)) { + for (0..len) |i| opt_dest.?[i] = opt_src.?[i]; + return opt_dest; + } else { + var index = len; + while (index != 0) { + index -= 1; + opt_dest.?[index] = opt_src.?[index]; + } + return opt_dest; + } + } + if (len == 0) { @branchHint(.unlikely); return opt_dest; |
