Skip to content

Commit cbd7d94

Browse files
committed
llvm: Use inline variants of memcpy/memset intrinsics when using -fno-builtin.
This is a correctness issue: When -fno-builtin is used, we must assume that we could be compiling the memcpy/memset implementations, so generating calls to them is problematic.
1 parent 1d87816 commit cbd7d94

File tree

2 files changed

+65
-9
lines changed

2 files changed

+65
-9
lines changed

src/codegen/llvm.zig

+61-7
Original file line numberDiff line numberDiff line change
@@ -5771,6 +5771,7 @@ pub const FuncGen = struct {
57715771
try o.builder.intValue(.i8, 0xaa),
57725772
len,
57735773
if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal,
5774+
self.ng.ownerModule().no_builtin,
57745775
);
57755776
const owner_mod = self.ng.ownerModule();
57765777
if (owner_mod.valgrind) {
@@ -5821,6 +5822,7 @@ pub const FuncGen = struct {
58215822
try o.builder.intValue(.i8, 0xaa),
58225823
len,
58235824
.normal,
5825+
self.ng.ownerModule().no_builtin,
58245826
);
58255827
const owner_mod = self.ng.ownerModule();
58265828
if (owner_mod.valgrind) {
@@ -9734,6 +9736,7 @@ pub const FuncGen = struct {
97349736
if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8),
97359737
len,
97369738
if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal,
9739+
self.ng.ownerModule().no_builtin,
97379740
);
97389741
if (safety and owner_mod.valgrind) {
97399742
try self.valgrindMarkUndef(dest_ptr, len);
@@ -10041,9 +10044,22 @@ pub const FuncGen = struct {
1004110044
try o.builder.undefValue(.i8);
1004210045
const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
1004310046
if (intrinsic_len0_traps) {
10044-
try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, access_kind);
10047+
try self.safeWasmMemset(
10048+
dest_ptr,
10049+
fill_byte,
10050+
len,
10051+
dest_ptr_align,
10052+
access_kind,
10053+
);
1004510054
} else {
10046-
_ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
10055+
_ = try self.wip.callMemSet(
10056+
dest_ptr,
10057+
dest_ptr_align,
10058+
fill_byte,
10059+
len,
10060+
access_kind,
10061+
self.ng.ownerModule().no_builtin,
10062+
);
1004710063
}
1004810064
const owner_mod = self.ng.ownerModule();
1004910065
if (safety and owner_mod.valgrind) {
@@ -10060,9 +10076,22 @@ pub const FuncGen = struct {
1006010076
const fill_byte = try o.builder.intValue(.i8, byte_val);
1006110077
const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
1006210078
if (intrinsic_len0_traps) {
10063-
try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, access_kind);
10079+
try self.safeWasmMemset(
10080+
dest_ptr,
10081+
fill_byte,
10082+
len,
10083+
dest_ptr_align,
10084+
access_kind,
10085+
);
1006410086
} else {
10065-
_ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
10087+
_ = try self.wip.callMemSet(
10088+
dest_ptr,
10089+
dest_ptr_align,
10090+
fill_byte,
10091+
len,
10092+
access_kind,
10093+
self.ng.ownerModule().no_builtin,
10094+
);
1006610095
}
1006710096
return .none;
1006810097
}
@@ -10077,9 +10106,22 @@ pub const FuncGen = struct {
1007710106
const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
1007810107

1007910108
if (intrinsic_len0_traps) {
10080-
try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, access_kind);
10109+
try self.safeWasmMemset(
10110+
dest_ptr,
10111+
fill_byte,
10112+
len,
10113+
dest_ptr_align,
10114+
access_kind,
10115+
);
1008110116
} else {
10082-
_ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
10117+
_ = try self.wip.callMemSet(
10118+
dest_ptr,
10119+
dest_ptr_align,
10120+
fill_byte,
10121+
len,
10122+
access_kind,
10123+
self.ng.ownerModule().no_builtin,
10124+
);
1008310125
}
1008410126
return .none;
1008510127
}
@@ -10131,6 +10173,7 @@ pub const FuncGen = struct {
1013110173
elem_abi_align.toLlvm(),
1013210174
try o.builder.intValue(llvm_usize_ty, elem_abi_size),
1013310175
access_kind,
10176+
self.ng.ownerModule().no_builtin,
1013410177
);
1013510178
} else _ = try self.wip.store(access_kind, value, it_ptr.toValue(), it_ptr_align);
1013610179
const next_ptr = try self.wip.gep(.inbounds, elem_llvm_ty, it_ptr.toValue(), &.{
@@ -10158,7 +10201,14 @@ pub const FuncGen = struct {
1015810201
const end_block = try self.wip.block(2, "MemsetTrapEnd");
1015910202
_ = try self.wip.brCond(cond, memset_block, end_block, .none);
1016010203
self.wip.cursor = .{ .block = memset_block };
10161-
_ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
10204+
_ = try self.wip.callMemSet(
10205+
dest_ptr,
10206+
dest_ptr_align,
10207+
fill_byte,
10208+
len,
10209+
access_kind,
10210+
self.ng.ownerModule().no_builtin,
10211+
);
1016210212
_ = try self.wip.br(end_block);
1016310213
self.wip.cursor = .{ .block = end_block };
1016410214
}
@@ -10200,6 +10250,7 @@ pub const FuncGen = struct {
1020010250
src_ptr_ty.ptrAlignment(zcu).toLlvm(),
1020110251
len,
1020210252
access_kind,
10253+
self.ng.ownerModule().no_builtin,
1020310254
);
1020410255
_ = try self.wip.br(end_block);
1020510256
self.wip.cursor = .{ .block = end_block };
@@ -10213,6 +10264,7 @@ pub const FuncGen = struct {
1021310264
src_ptr_ty.ptrAlignment(zcu).toLlvm(),
1021410265
len,
1021510266
access_kind,
10267+
self.ng.ownerModule().no_builtin,
1021610268
);
1021710269
return .none;
1021810270
}
@@ -11346,6 +11398,7 @@ pub const FuncGen = struct {
1134611398
ptr_alignment,
1134711399
try o.builder.intValue(try o.lowerType(Type.usize), size_bytes),
1134811400
access_kind,
11401+
fg.ng.ownerModule().no_builtin,
1134911402
);
1135011403
return result_ptr;
1135111404
}
@@ -11513,6 +11566,7 @@ pub const FuncGen = struct {
1151311566
elem_ty.abiAlignment(zcu).toLlvm(),
1151411567
try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(zcu)),
1151511568
access_kind,
11569+
self.ng.ownerModule().no_builtin,
1151611570
);
1151711571
}
1151811572

src/codegen/llvm/Builder.zig

+4-2
Original file line numberDiff line numberDiff line change
@@ -6102,6 +6102,7 @@ pub const WipFunction = struct {
61026102
src_align: Alignment,
61036103
len: Value,
61046104
kind: MemoryAccessKind,
6105+
@"inline": bool,
61056106
) Allocator.Error!Instruction.Index {
61066107
var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};
61076108
var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = src_align })};
@@ -6113,7 +6114,7 @@ pub const WipFunction = struct {
61136114
try self.builder.attrs(&dst_attrs),
61146115
try self.builder.attrs(&src_attrs),
61156116
}),
6116-
.memcpy,
6117+
if (@"inline") .@"memcpy.inline" else .memcpy,
61176118
&.{ dst.typeOfWip(self), src.typeOfWip(self), len.typeOfWip(self) },
61186119
&.{ dst, src, len, switch (kind) {
61196120
.normal => Value.false,
@@ -6131,12 +6132,13 @@ pub const WipFunction = struct {
61316132
val: Value,
61326133
len: Value,
61336134
kind: MemoryAccessKind,
6135+
@"inline": bool,
61346136
) Allocator.Error!Instruction.Index {
61356137
var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};
61366138
const value = try self.callIntrinsic(
61376139
.normal,
61386140
try self.builder.fnAttrs(&.{ .none, .none, try self.builder.attrs(&dst_attrs) }),
6139-
.memset,
6141+
if (@"inline") .@"memset.inline" else .memset,
61406142
&.{ dst.typeOfWip(self), len.typeOfWip(self) },
61416143
&.{ dst, val, len, switch (kind) {
61426144
.normal => Value.false,

0 commit comments

Comments
 (0)