| author | |
| committer | |
| log | 0606f0aa5576122204886f1a3c9530c0ce75c044 |
| tree | 8e1c9cf9b000a60d4f98aafeb318f6814bea52a7 |
| parent | 505e720421ce4f7ed11730fe68d32e3bba711f3c |
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( | ... | @@ -2538,6 +2538,20 @@ fn coerceResultPtr( |
| 2538 | const trash_inst = trash_block.instructions.pop(); | 2538 | const trash_inst = trash_block.instructions.pop(); |
| 2539 | 2539 | ||
| 2540 | switch (air_tags[trash_inst]) { | 2540 | 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 | }, | ||
| 2541 | .bitcast => { | 2555 | .bitcast => { |
| 2542 | const ty_op = air_datas[trash_inst].ty_op; | 2556 | const ty_op = air_datas[trash_inst].ty_op; |
| 2543 | const operand_ty = sema.typeOf(ty_op.operand); | 2557 | const operand_ty = sema.typeOf(ty_op.operand); |
test/behavior/vector.zig+19| ... | @@ -175,6 +175,25 @@ test "array to vector" { | ... | @@ -175,6 +175,25 @@ test "array to vector" { |
| 175 | comptime try S.doTheTest(); | 175 | comptime try S.doTheTest(); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | test "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 | |||
| 178 | test "peer type resolution with coercible element types" { | 197 | test "peer type resolution with coercible element types" { |
| 179 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 198 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 180 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 199 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |