authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2023-03-08 23:13:37+01:00
committergravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2023-03-09 00:55:33+01:00
log0606f0aa5576122204886f1a3c9530c0ce75c044
tree8e1c9cf9b000a60d4f98aafeb318f6814bea52a7
parent505e720421ce4f7ed11730fe68d32e3bba711f3c

sema: fix result ptr coercion array -> vector

Previously this worked for array to vector where the element type matched exactly (e.g `[4]u8` to `@Vector(4, u8)`) since that is performed with a simple `.bitcast` operation, but now it also works for types where the array is coercible to the vector type (e.g `[4]u8` to `@Vector(4, u16)`).

2 files changed, 33 insertions(+), 0 deletions(-)

src/Sema.zig+14
......@@ -2538,6 +2538,20 @@ fn coerceResultPtr(
25382538 const trash_inst = trash_block.instructions.pop();
25392539
25402540 switch (air_tags[trash_inst]) {
2541 // Array coerced to Vector where element size is not equal but coercible.
2542 .aggregate_init => {
2543 const ty_pl = air_datas[trash_inst].ty_pl;
2544 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{
2545 .pointee_type = try sema.analyzeAsType(block, src, ty_pl.ty),
2546 .@"addrspace" = addr_space,
2547 });
2548
2549 if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
2550 return sema.addConstant(ptr_operand_ty, ptr_val);
2551 } else {
2552 return sema.bitCast(block, ptr_operand_ty, new_ptr, src, null);
2553 }
2554 },
25412555 .bitcast => {
25422556 const ty_op = air_datas[trash_inst].ty_op;
25432557 const operand_ty = sema.typeOf(ty_op.operand);
test/behavior/vector.zig+19
......@@ -175,6 +175,25 @@ test "array to vector" {
175175 comptime try S.doTheTest();
176176}
177177
178test "array to vector with element type coercion" {
179 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
180 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
181 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
182 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
184
185 const S = struct {
186 fn doTheTest() !void {
187 var foo: f16 = 3.14;
188 var arr32 = [4]f32{ foo, 1.5, 0.0, 0.0 };
189 var vec: @Vector(4, f32) = [4]f16{ foo, 1.5, 0.0, 0.0 };
190 try std.testing.expect(std.mem.eql(f32, &@as([4]f32, vec), &arr32));
191 }
192 };
193 try S.doTheTest();
194 comptime try S.doTheTest();
195}
196
178197test "peer type resolution with coercible element types" {
179198 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
180199 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO