authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-24 12:49:12-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-24 12:49:12-07:00
log38441b5eab3c9371f8412aa46a277f37fc026a79
tree2d6453a902c1db213842d3d0edeba237995b17b7
parent52c45bf44d797f28594db5a75c306ed209cfb933

MultiArrayList: use @memcpy as a workaround

Reverts bf642204b373e01314ecfb0c50a643dc4b05746f and uses a different workaround, suggested by @LemonBoy. There is either a compiler bug or a design flaw somewhere around here. It does not have to block this branch, but I need to understand exactly what's going on here and make it so that nobody ever has to run into this problem again.

2 files changed, 14 insertions(+), 14 deletions(-)

CMakeLists.txt+1
......@@ -407,6 +407,7 @@ set(ZIG_STAGE2_SOURCES
407407 "${CMAKE_SOURCE_DIR}/lib/std/meta.zig"
408408 "${CMAKE_SOURCE_DIR}/lib/std/meta/trailer_flags.zig"
409409 "${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig"
410 "${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig"
410411 "${CMAKE_SOURCE_DIR}/lib/std/os.zig"
411412 "${CMAKE_SOURCE_DIR}/lib/std/os/bits.zig"
412413 "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux.zig"
lib/std/multi_array_list.zig+13-14
......@@ -203,7 +203,11 @@ pub fn MultiArrayList(comptime S: type) type {
203203 const other_slice = other.slice();
204204 inline for (fields) |field_info, i| {
205205 const field = @intToEnum(Field, i);
206 mem.copy(field_info.field_type, other_slice.items(field), self_slice.items(field));
206 // TODO we should be able to use std.mem.copy here but it causes a
207 // test failure on aarch64 with -OReleaseFast
208 const src_slice = mem.sliceAsBytes(self_slice.items(field));
209 const dst_slice = mem.sliceAsBytes(other_slice.items(field));
210 @memcpy(dst_slice.ptr, src_slice.ptr, src_slice.len);
207211 }
208212 gpa.free(self.allocatedBytes());
209213 self.* = other;
......@@ -256,25 +260,20 @@ pub fn MultiArrayList(comptime S: type) type {
256260 const other_slice = other.slice();
257261 inline for (fields) |field_info, i| {
258262 const field = @intToEnum(Field, i);
259 mem.copy(field_info.field_type, other_slice.items(field), self_slice.items(field));
263 // TODO we should be able to use std.mem.copy here but it causes a
264 // test failure on aarch64 with -OReleaseFast
265 const src_slice = mem.sliceAsBytes(self_slice.items(field));
266 const dst_slice = mem.sliceAsBytes(other_slice.items(field));
267 @memcpy(dst_slice.ptr, src_slice.ptr, src_slice.len);
260268 }
261269 gpa.free(self.allocatedBytes());
262270 self.* = other;
263271 }
264272
265273 fn capacityInBytes(capacity: usize) usize {
266 // TODO move this workaround of LLVM SIMD bugs into the Zig frontend.
267 if (std.Target.current.cpu.arch == .aarch64) {
268 var sum: usize = 0;
269 for (sizes.bytes) |size| {
270 sum += capacity * size;
271 }
272 return sum;
273 } else {
274 const sizes_vector: std.meta.Vector(sizes.bytes.len, usize) = sizes.bytes;
275 const capacity_vector = @splat(sizes.bytes.len, capacity);
276 return @reduce(.Add, capacity_vector * sizes_vector);
277 }
274 const sizes_vector: std.meta.Vector(sizes.bytes.len, usize) = sizes.bytes;
275 const capacity_vector = @splat(sizes.bytes.len, capacity);
276 return @reduce(.Add, capacity_vector * sizes_vector);
278277 }
279278
280279 fn allocatedBytes(self: Self) []align(@alignOf(S)) u8 {