authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-01-29 13:48:35+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-01-29 13:51:57+02:00
log78e982f7c3e8a441259d26a69690d8934dd32bf0
tree75bd93c8a6fe90688da32e90c27683f93a9e55d0
parent281b2695c480de1d50e1a0c03c5f5dde36010501

llvm: fix alignment of array ptr when bitcasting vector

Closes #17996

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

src/codegen/llvm.zig+2-2
...@@ -8722,10 +8722,10 @@ pub const FuncGen = struct {...@@ -8722,10 +8722,10 @@ pub const FuncGen = struct {
8722 if (!result_is_ref) {8722 if (!result_is_ref) {
8723 return self.dg.todo("implement bitcast vector to non-ref array", .{});8723 return self.dg.todo("implement bitcast vector to non-ref array", .{});
8724 }8724 }
8725 const array_ptr = try self.buildAllocaWorkaround(inst_ty, .default);8725 const alignment = inst_ty.abiAlignment(mod).toLlvm();
8726 const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
8726 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;8727 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;
8727 if (bitcast_ok) {8728 if (bitcast_ok) {
8728 const alignment = inst_ty.abiAlignment(mod).toLlvm();
8729 _ = try self.wip.store(.normal, operand, array_ptr, alignment);8729 _ = try self.wip.store(.normal, operand, array_ptr, alignment);
8730 } else {8730 } else {
8731 // If the ABI size of the element type is not evenly divisible by size in bits;8731 // If the ABI size of the element type is not evenly divisible by size in bits;
test/behavior/vector.zig+19
...@@ -1566,3 +1566,22 @@ test "@reduce on bool vector" {...@@ -1566,3 +1566,22 @@ test "@reduce on bool vector" {
1566 try std.testing.expect(@reduce(.And, a));1566 try std.testing.expect(@reduce(.And, a));
1567 try std.testing.expect(@reduce(.And, b));1567 try std.testing.expect(@reduce(.And, b));
1568}1568}
1569
1570test "bitcast vector to array of smaller vectors" {
1571 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1572 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1573
1574 const u8x32 = @Vector(32, u8);
1575 const u8x64 = @Vector(64, u8);
1576 const S = struct {
1577 fn doTheTest(input_vec: u8x64) !void {
1578 try compare(@bitCast(input_vec));
1579 }
1580 fn compare(chunks: [2]u8x32) !void {
1581 try expectEqual(@as(u8x32, @splat(1)), chunks[0]);
1582 try expectEqual(@as(u8x32, @splat(2)), chunks[1]);
1583 }
1584 };
1585 const input: u8x64 = @bitCast([2]u8x32{ @splat(1), @splat(2) });
1586 try S.doTheTest(input);
1587}