From 38441b5eab3c9371f8412aa46a277f37fc026a79 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 24 Feb 2021 12:49:12 -0700 Subject: [PATCH] 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. --- CMakeLists.txt | 1 + lib/std/multi_array_list.zig | 27 +++++++++++++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f2dc4fa4a..6e89d87ca9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -407,6 +407,7 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/lib/std/meta.zig" "${CMAKE_SOURCE_DIR}/lib/std/meta/trailer_flags.zig" "${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig" + "${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig" "${CMAKE_SOURCE_DIR}/lib/std/os.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/bits.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux.zig" diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig index 689105755c..3306fd3ef0 100644 --- a/lib/std/multi_array_list.zig +++ b/lib/std/multi_array_list.zig @@ -203,7 +203,11 @@ pub fn MultiArrayList(comptime S: type) type { const other_slice = other.slice(); inline for (fields) |field_info, i| { const field = @intToEnum(Field, i); - mem.copy(field_info.field_type, other_slice.items(field), self_slice.items(field)); + // TODO we should be able to use std.mem.copy here but it causes a + // test failure on aarch64 with -OReleaseFast + const src_slice = mem.sliceAsBytes(self_slice.items(field)); + const dst_slice = mem.sliceAsBytes(other_slice.items(field)); + @memcpy(dst_slice.ptr, src_slice.ptr, src_slice.len); } gpa.free(self.allocatedBytes()); self.* = other; @@ -256,25 +260,20 @@ pub fn MultiArrayList(comptime S: type) type { const other_slice = other.slice(); inline for (fields) |field_info, i| { const field = @intToEnum(Field, i); - mem.copy(field_info.field_type, other_slice.items(field), self_slice.items(field)); + // TODO we should be able to use std.mem.copy here but it causes a + // test failure on aarch64 with -OReleaseFast + const src_slice = mem.sliceAsBytes(self_slice.items(field)); + const dst_slice = mem.sliceAsBytes(other_slice.items(field)); + @memcpy(dst_slice.ptr, src_slice.ptr, src_slice.len); } gpa.free(self.allocatedBytes()); self.* = other; } fn capacityInBytes(capacity: usize) usize { - // TODO move this workaround of LLVM SIMD bugs into the Zig frontend. - if (std.Target.current.cpu.arch == .aarch64) { - var sum: usize = 0; - for (sizes.bytes) |size| { - sum += capacity * size; - } - return sum; - } else { - const sizes_vector: std.meta.Vector(sizes.bytes.len, usize) = sizes.bytes; - const capacity_vector = @splat(sizes.bytes.len, capacity); - return @reduce(.Add, capacity_vector * sizes_vector); - } + const sizes_vector: std.meta.Vector(sizes.bytes.len, usize) = sizes.bytes; + const capacity_vector = @splat(sizes.bytes.len, capacity); + return @reduce(.Add, capacity_vector * sizes_vector); } fn allocatedBytes(self: Self) []align(@alignOf(S)) u8 {