Commit 78e982f7c3

Veikka Tuominen <git@vexu.eu>
2024-01-29 12:48:35
llvm: fix alignment of array ptr when bitcasting vector
Closes #17996
1 parent 281b269
Changed files (2)
src
codegen
test
behavior
src/codegen/llvm.zig
@@ -8722,10 +8722,10 @@ pub const FuncGen = struct {
             if (!result_is_ref) {
                 return self.dg.todo("implement bitcast vector to non-ref array", .{});
             }
-            const array_ptr = try self.buildAllocaWorkaround(inst_ty, .default);
+            const alignment = inst_ty.abiAlignment(mod).toLlvm();
+            const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
             const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;
             if (bitcast_ok) {
-                const alignment = inst_ty.abiAlignment(mod).toLlvm();
                 _ = try self.wip.store(.normal, operand, array_ptr, alignment);
             } else {
                 // If the ABI size of the element type is not evenly divisible by size in bits;
test/behavior/vector.zig
@@ -1566,3 +1566,22 @@ test "@reduce on bool vector" {
     try std.testing.expect(@reduce(.And, a));
     try std.testing.expect(@reduce(.And, b));
 }
+
+test "bitcast vector to array of smaller vectors" {
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+    const u8x32 = @Vector(32, u8);
+    const u8x64 = @Vector(64, u8);
+    const S = struct {
+        fn doTheTest(input_vec: u8x64) !void {
+            try compare(@bitCast(input_vec));
+        }
+        fn compare(chunks: [2]u8x32) !void {
+            try expectEqual(@as(u8x32, @splat(1)), chunks[0]);
+            try expectEqual(@as(u8x32, @splat(2)), chunks[1]);
+        }
+    };
+    const input: u8x64 = @bitCast([2]u8x32{ @splat(1), @splat(2) });
+    try S.doTheTest(input);
+}