Merge pull request #14853 from schmee/vector-peer-type-resolution

Vector type resolution/coercion fixes
This commit is contained in:
Andrew Kelley 2023-04-10 12:21:55 -04:00 committed by GitHub
commit a2793f8ab8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 0 deletions

View File

@ -2599,6 +2599,20 @@ fn coerceResultPtr(
const trash_inst = trash_block.instructions.pop(); const trash_inst = trash_block.instructions.pop();
switch (air_tags[trash_inst]) { switch (air_tags[trash_inst]) {
// Array coerced to Vector where element size is not equal but coercible.
.aggregate_init => {
const ty_pl = air_datas[trash_inst].ty_pl;
const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{
.pointee_type = try sema.analyzeAsType(block, src, ty_pl.ty),
.@"addrspace" = addr_space,
});
if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
return sema.addConstant(ptr_operand_ty, ptr_val);
} else {
return sema.bitCast(block, ptr_operand_ty, new_ptr, src, null);
}
},
.bitcast => { .bitcast => {
const ty_op = air_datas[trash_inst].ty_op; const ty_op = air_datas[trash_inst].ty_op;
const operand_ty = sema.typeOf(ty_op.operand); const operand_ty = sema.typeOf(ty_op.operand);
@ -30068,6 +30082,31 @@ fn resolvePeerTypes(
continue; continue;
}, },
.Vector => switch (chosen_ty_tag) { .Vector => switch (chosen_ty_tag) {
.Vector => {
const chosen_len = chosen_ty.vectorLen();
const candidate_len = candidate_ty.vectorLen();
if (chosen_len != candidate_len)
continue;
const chosen_child_ty = chosen_ty.childType();
const candidate_child_ty = candidate_ty.childType();
if (chosen_child_ty.zigTypeTag() == .Int and candidate_child_ty.zigTypeTag() == .Int) {
const chosen_info = chosen_child_ty.intInfo(target);
const candidate_info = candidate_child_ty.intInfo(target);
if (chosen_info.bits < candidate_info.bits) {
chosen = candidate;
chosen_i = candidate_i + 1;
}
continue;
}
if (chosen_child_ty.zigTypeTag() == .Float and candidate_child_ty.zigTypeTag() == .Float) {
if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) {
chosen = candidate;
chosen_i = candidate_i + 1;
}
continue;
}
},
.Array => { .Array => {
chosen = candidate; chosen = candidate;
chosen_i = candidate_i + 1; chosen_i = candidate_i + 1;

View File

@ -175,6 +175,44 @@ test "array to vector" {
comptime try S.doTheTest(); comptime try S.doTheTest();
} }
test "array to vector with element type coercion" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const S = struct {
fn doTheTest() !void {
var foo: f16 = 3.14;
var arr32 = [4]f32{ foo, 1.5, 0.0, 0.0 };
var vec: @Vector(4, f32) = [4]f16{ foo, 1.5, 0.0, 0.0 };
try std.testing.expect(std.mem.eql(f32, &@as([4]f32, vec), &arr32));
}
};
try S.doTheTest();
comptime try S.doTheTest();
}
test "peer type resolution with coercible element types" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const S = struct {
fn doTheTest() !void {
var b: @Vector(2, u8) = .{ 1, 2 };
var a: @Vector(2, u16) = .{ 2, 1 };
var t: bool = true;
var c = if (t) a else b;
try std.testing.expect(@TypeOf(c) == @Vector(2, u16));
}
};
comptime try S.doTheTest();
}
test "tuple to vector" { test "tuple to vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO