Commit 38441b5eab

Andrew Kelley <andrew@ziglang.org>
2021-02-24 20:49:12
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.
1 parent 52c45bf
Changed files (2)
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 {
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"