motiejus/zig

fork of https://codeberg.org/ziglang/zig
git clone https://git.jakstys.lt/motiejus/zig.git
Log | Tree | Refs | README | LICENSE

commit c5260f7f867fd4ccb4eb3fd5b0ab91759cf94546 (tree)
parent 4578d13b49d16463b870119005877f7b6e10092e
Author: LemonBoy <thatlemon@gmail.com>
Date:   Thu, 13 Feb 2020 00:38:59 +0100

ir: Allow implicit conversion between vector types

Only valid when the number of elements match and the types are
compatible.

Fixes #4334

Diffstat:
Msrc/ir.cpp | 14+++++++++++++-
Mtest/stage1/behavior/vector.zig | 27+++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/src/ir.cpp b/src/ir.cpp @@ -14840,6 +14840,16 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, } } + // @Vector(N,T1) to @Vector(N,T2) + if (actual_type->id == ZigTypeIdVector && wanted_type->id == ZigTypeIdVector) { + if (actual_type->data.vector.len == wanted_type->data.vector.len && + types_match_const_cast_only(ira, wanted_type->data.vector.elem_type, + actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) + { + return ir_analyze_bit_cast(ira, source_instr, value, wanted_type); + } + } + // *@Frame(func) to anyframe->T or anyframe // *@Frame(func) to ?anyframe->T or ?anyframe // *@Frame(func) to E!anyframe->T or E!anyframe @@ -16409,9 +16419,11 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i case ZigTypeIdComptimeInt: case ZigTypeIdInt: case ZigTypeIdFloat: - case ZigTypeIdVector: zig_unreachable(); // handled with the type_is_numeric checks above + case ZigTypeIdVector: + // Not every case is handled by the type_is_numeric checks above, + // vectors of bool trigger this code path case ZigTypeIdBool: case ZigTypeIdMetaType: case ZigTypeIdVoid: diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig @@ -1,6 +1,7 @@ const std = @import("std"); const mem = std.mem; const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; const builtin = @import("builtin"); test "implicit cast vector to array - bool" { @@ -250,3 +251,29 @@ test "initialize vector which is a struct field" { S.doTheTest(); comptime S.doTheTest(); } + +test "vector comparison operators" { + const S = struct { + fn doTheTest() void { + { + const v1: @Vector(4, bool) = [_]bool{ true, false, true, false }; + const v2: @Vector(4, bool) = [_]bool{ false, true, false, true }; + expectEqual(@splat(4, true), v1 == v1); + expectEqual(@splat(4, false), v1 == v2); + expectEqual(@splat(4, true), v1 != v2); + expectEqual(@splat(4, false), v2 != v2); + } + { + const v1 = @splat(4, @as(u32, 0xc0ffeeee)); + const v2: @Vector(4, c_uint) = v1; + const v3 = @splat(4, @as(u32, 0xdeadbeef)); + expectEqual(@splat(4, true), v1 == v2); + expectEqual(@splat(4, false), v1 == v3); + expectEqual(@splat(4, true), v1 != v3); + expectEqual(@splat(4, false), v1 != v2); + } + } + }; + S.doTheTest(); + comptime S.doTheTest(); +}