aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-01-17 13:21:30 -0800
committerAndrew Kelley <andrew@ziglang.org>2025-01-17 13:21:30 -0800
commitacf70439551fc3f49b2d292ff93ee519901cdf42 (patch)
treeb70f5c87c1b023e7a4acc5d8ae32429657d9a967 /lib
parent59acfb12635b79fd83950eed10172cf43694b978 (diff)
downloadzig-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.zig28
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;