Skip to content

Commit

Permalink
Sema: implement comptime @memcpy
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewrk committed Apr 23, 2023
1 parent c9e8099 commit 0b4d061
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
40 changes: 36 additions & 4 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21827,6 +21827,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const src_ptr = try sema.resolveInst(extra.rhs);
const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);
const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr);
const target = sema.mod.getTarget();

if (dest_len == .none and src_len == .none) {
const msg = msg: {
Expand Down Expand Up @@ -21878,9 +21879,41 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void

const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {
if (!dest_ptr_val.isComptimeMutablePtr()) break :rs dest_src;
if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |src_ptr_val| {
_ = src_ptr_val;
return sema.fail(block, src, "TODO: @memcpy at comptime", .{});
if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {
const len_u64 = (try len_val.?.getUnsignedIntAdvanced(target, sema)).?;
const len = try sema.usizeCast(block, dest_src, len_u64);
for (0..len) |i| {
const elem_index = try sema.addIntUnsigned(Type.usize, i);
const dest_elem_ptr = try sema.elemPtr(
block,
src,
dest_ptr,
elem_index,
src,
true, // init
false, // oob_safety
);
const src_elem_ptr = try sema.elemPtr(
block,
src,
src_ptr,
elem_index,
src,
false, // init
false, // oob_safety
);
const uncoerced_elem = try sema.analyzeLoad(block, src, src_elem_ptr, src_src);
try sema.storePtr2(
block,
src,
dest_elem_ptr,
dest_src,
uncoerced_elem,
src_src,
.store,
);
}
return;
} else break :rs src_src;
} else dest_src;

Expand All @@ -21901,7 +21934,6 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void

const dest_elem_ty = dest_ty.elemType2();
const src_elem_ty = src_ty.elemType2();
const target = sema.mod.getTarget();
if (.ok != try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, true, target, dest_src, src_src)) {
return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the element types have different ABI sizes", .{});
}
Expand Down
3 changes: 1 addition & 2 deletions test/behavior/basic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,7 @@ test "memcpy and memset intrinsics" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO

try testMemcpyMemset();
// TODO add comptime test coverage
//comptime try testMemcpyMemset();
try comptime testMemcpyMemset();
}

fn testMemcpyMemset() !void {
Expand Down

0 comments on commit 0b4d061

Please sign in to comment.