Skip to content

Commit

Permalink
compiler-rt: prevent llvm making memcpy recursive
Browse files Browse the repository at this point in the history
before this commit, when compiling for target riscv64-linux-none and
with `-mcpu basline`, recursive jalr instructions were generated that
caused infinite looping and a stack overflow for copy lengths between 16
and 31 (inclusive).

This was caused by LLVM optimisations - in particular LLVM has an
optimisation that can turn copies of a sufficient length into a call to
memcpy. This change breaks up some copies in order to try and prevent
this optimisation from occuring.
  • Loading branch information
dweiller committed Feb 15, 2024
1 parent 099cdf6 commit 81a4c1c
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions lib/compiler_rt/memcpy.zig
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,23 @@ inline fn memcpy_range2(
comptime std.debug.assert(std.math.isPowerOfTwo(min));
const copy_len = min;
const last = len - copy_len;
dest[0..copy_len].* = src[0..copy_len].*;
dest[last..][0..copy_len].* = src[last..][0..copy_len].*;
if (copy_len > size) { // comptime-known
// we do these copies 1 CopyType at a time to prevent llvm turning this into a call to memcpy
const d: [*]align(1) CopyType = @ptrCast(dest);
const s: [*]align(1) const CopyType = @ptrCast(src);
const count = @divExact(copy_len, size);
inline for (d[0..count], s[0..count]) |*r, v| {
r.* = v;
}
const dl: [*]align(1) CopyType = @ptrCast(dest + last);
const sl: [*]align(1) const CopyType = @ptrCast(src + last);
inline for (dl[0..count], sl[0..count]) |*r, v| {
r.* = v;
}
} else {
dest[0..copy_len].* = src[0..copy_len].*;
dest[last..][0..copy_len].* = src[last..][0..copy_len].*;
}
}

test "aligned" {
Expand Down

0 comments on commit 81a4c1c

Please sign in to comment.