Skip to content

Commit 01b21e5

Browse files
committed
llvm: Remove workaround for zero-length memset/memcpy on wasm.
Closes #16360.
1 parent a720819 commit 01b21e5

File tree

1 file changed

+24
-118
lines changed

1 file changed

+24
-118
lines changed

src/codegen/llvm.zig

+24-118
Original file line numberDiff line numberDiff line change
@@ -9766,14 +9766,6 @@ pub const FuncGen = struct {
97669766
const access_kind: Builder.MemoryAccessKind =
97679767
if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
97689768

9769-
// Any WebAssembly runtime will trap when the destination pointer is out-of-bounds, regardless
9770-
// of the length. This means we need to emit a check where we skip the memset when the length
9771-
// is 0 as we allow for undefined pointers in 0-sized slices.
9772-
// This logic can be removed once https://github.com/ziglang/zig/issues/16360 is done.
9773-
const intrinsic_len0_traps = o.target.cpu.arch.isWasm() and
9774-
ptr_ty.isSlice(zcu) and
9775-
std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory);
9776-
97779769
if (try self.air.value(bin_op.rhs, pt)) |elem_val| {
97789770
if (elem_val.isUndefDeep(zcu)) {
97799771
// Even if safety is disabled, we still emit a memset to undefined since it conveys
@@ -9784,24 +9776,14 @@ pub const FuncGen = struct {
97849776
else
97859777
try o.builder.undefValue(.i8);
97869778
const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
9787-
if (intrinsic_len0_traps) {
9788-
try self.safeWasmMemset(
9789-
dest_ptr,
9790-
fill_byte,
9791-
len,
9792-
dest_ptr_align,
9793-
access_kind,
9794-
);
9795-
} else {
9796-
_ = try self.wip.callMemSet(
9797-
dest_ptr,
9798-
dest_ptr_align,
9799-
fill_byte,
9800-
len,
9801-
access_kind,
9802-
self.disable_intrinsics,
9803-
);
9804-
}
9779+
_ = try self.wip.callMemSet(
9780+
dest_ptr,
9781+
dest_ptr_align,
9782+
fill_byte,
9783+
len,
9784+
access_kind,
9785+
self.disable_intrinsics,
9786+
);
98059787
const owner_mod = self.ng.ownerModule();
98069788
if (safety and owner_mod.valgrind) {
98079789
try self.valgrindMarkUndef(dest_ptr, len);
@@ -9816,24 +9798,14 @@ pub const FuncGen = struct {
98169798
if (try elem_val.hasRepeatedByteRepr(pt)) |byte_val| {
98179799
const fill_byte = try o.builder.intValue(.i8, byte_val);
98189800
const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
9819-
if (intrinsic_len0_traps) {
9820-
try self.safeWasmMemset(
9821-
dest_ptr,
9822-
fill_byte,
9823-
len,
9824-
dest_ptr_align,
9825-
access_kind,
9826-
);
9827-
} else {
9828-
_ = try self.wip.callMemSet(
9829-
dest_ptr,
9830-
dest_ptr_align,
9831-
fill_byte,
9832-
len,
9833-
access_kind,
9834-
self.disable_intrinsics,
9835-
);
9836-
}
9801+
_ = try self.wip.callMemSet(
9802+
dest_ptr,
9803+
dest_ptr_align,
9804+
fill_byte,
9805+
len,
9806+
access_kind,
9807+
self.disable_intrinsics,
9808+
);
98379809
return .none;
98389810
}
98399811
}
@@ -9846,24 +9818,14 @@ pub const FuncGen = struct {
98469818
const fill_byte = try self.bitCast(value, elem_ty, Type.u8);
98479819
const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
98489820

9849-
if (intrinsic_len0_traps) {
9850-
try self.safeWasmMemset(
9851-
dest_ptr,
9852-
fill_byte,
9853-
len,
9854-
dest_ptr_align,
9855-
access_kind,
9856-
);
9857-
} else {
9858-
_ = try self.wip.callMemSet(
9859-
dest_ptr,
9860-
dest_ptr_align,
9861-
fill_byte,
9862-
len,
9863-
access_kind,
9864-
self.disable_intrinsics,
9865-
);
9866-
}
9821+
_ = try self.wip.callMemSet(
9822+
dest_ptr,
9823+
dest_ptr_align,
9824+
fill_byte,
9825+
len,
9826+
access_kind,
9827+
self.disable_intrinsics,
9828+
);
98679829
return .none;
98689830
}
98699831

@@ -9927,33 +9889,6 @@ pub const FuncGen = struct {
99279889
return .none;
99289890
}
99299891

9930-
fn safeWasmMemset(
9931-
self: *FuncGen,
9932-
dest_ptr: Builder.Value,
9933-
fill_byte: Builder.Value,
9934-
len: Builder.Value,
9935-
dest_ptr_align: Builder.Alignment,
9936-
access_kind: Builder.MemoryAccessKind,
9937-
) !void {
9938-
const o = self.ng.object;
9939-
const usize_zero = try o.builder.intValue(try o.lowerType(Type.usize), 0);
9940-
const cond = try self.cmp(.normal, .neq, Type.usize, len, usize_zero);
9941-
const memset_block = try self.wip.block(1, "MemsetTrapSkip");
9942-
const end_block = try self.wip.block(2, "MemsetTrapEnd");
9943-
_ = try self.wip.brCond(cond, memset_block, end_block, .none);
9944-
self.wip.cursor = .{ .block = memset_block };
9945-
_ = try self.wip.callMemSet(
9946-
dest_ptr,
9947-
dest_ptr_align,
9948-
fill_byte,
9949-
len,
9950-
access_kind,
9951-
self.disable_intrinsics,
9952-
);
9953-
_ = try self.wip.br(end_block);
9954-
self.wip.cursor = .{ .block = end_block };
9955-
}
9956-
99579892
fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
99589893
const o = self.ng.object;
99599894
const pt = o.pt;
@@ -9969,35 +9904,6 @@ pub const FuncGen = struct {
99699904
const access_kind: Builder.MemoryAccessKind = if (src_ptr_ty.isVolatilePtr(zcu) or
99709905
dest_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
99719906

9972-
// When bulk-memory is enabled, this will be lowered to WebAssembly's memory.copy instruction.
9973-
// This instruction will trap on an invalid address, regardless of the length.
9974-
// For this reason we must add a check for 0-sized slices as its pointer field can be undefined.
9975-
// We only have to do this for slices as arrays will have a valid pointer.
9976-
// This logic can be removed once https://github.com/ziglang/zig/issues/16360 is done.
9977-
if (o.target.cpu.arch.isWasm() and
9978-
std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory) and
9979-
dest_ptr_ty.isSlice(zcu))
9980-
{
9981-
const usize_zero = try o.builder.intValue(try o.lowerType(Type.usize), 0);
9982-
const cond = try self.cmp(.normal, .neq, Type.usize, len, usize_zero);
9983-
const memcpy_block = try self.wip.block(1, "MemcpyTrapSkip");
9984-
const end_block = try self.wip.block(2, "MemcpyTrapEnd");
9985-
_ = try self.wip.brCond(cond, memcpy_block, end_block, .none);
9986-
self.wip.cursor = .{ .block = memcpy_block };
9987-
_ = try self.wip.callMemCpy(
9988-
dest_ptr,
9989-
dest_ptr_ty.ptrAlignment(zcu).toLlvm(),
9990-
src_ptr,
9991-
src_ptr_ty.ptrAlignment(zcu).toLlvm(),
9992-
len,
9993-
access_kind,
9994-
self.disable_intrinsics,
9995-
);
9996-
_ = try self.wip.br(end_block);
9997-
self.wip.cursor = .{ .block = end_block };
9998-
return .none;
9999-
}
10000-
100019907
_ = try self.wip.callMemCpy(
100029908
dest_ptr,
100039909
dest_ptr_ty.ptrAlignment(zcu).toLlvm(),

0 commit comments

Comments
 (0)