authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-13 00:38:59+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-13 12:13:56+01:00
logc5260f7f867fd4ccb4eb3fd5b0ab91759cf94546
tree30e35baffe86665fbfe72857cd47c46a4729a0ce
parent4578d13b49d16463b870119005877f7b6e10092e

ir: Allow implicit conversion between vector types

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

2 files changed, 40 insertions(+), 1 deletions(-)

src/ir.cpp+13-1
...@@ -14840,6 +14840,16 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,...@@ -14840,6 +14840,16 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
14840 }14840 }
14841 }14841 }
1484214842
14843 // @Vector(N,T1) to @Vector(N,T2)
14844 if (actual_type->id == ZigTypeIdVector && wanted_type->id == ZigTypeIdVector) {
14845 if (actual_type->data.vector.len == wanted_type->data.vector.len &&
14846 types_match_const_cast_only(ira, wanted_type->data.vector.elem_type,
14847 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
14848 {
14849 return ir_analyze_bit_cast(ira, source_instr, value, wanted_type);
14850 }
14851 }
14852
14843 // *@Frame(func) to anyframe->T or anyframe14853 // *@Frame(func) to anyframe->T or anyframe
14844 // *@Frame(func) to ?anyframe->T or ?anyframe14854 // *@Frame(func) to ?anyframe->T or ?anyframe
14845 // *@Frame(func) to E!anyframe->T or E!anyframe14855 // *@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...@@ -16409,9 +16419,11 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i
16409 case ZigTypeIdComptimeInt:16419 case ZigTypeIdComptimeInt:
16410 case ZigTypeIdInt:16420 case ZigTypeIdInt:
16411 case ZigTypeIdFloat:16421 case ZigTypeIdFloat:
16412 case ZigTypeIdVector:
16413 zig_unreachable(); // handled with the type_is_numeric checks above16422 zig_unreachable(); // handled with the type_is_numeric checks above
1641416423
16424 case ZigTypeIdVector:
16425 // Not every case is handled by the type_is_numeric checks above,
16426 // vectors of bool trigger this code path
16415 case ZigTypeIdBool:16427 case ZigTypeIdBool:
16416 case ZigTypeIdMetaType:16428 case ZigTypeIdMetaType:
16417 case ZigTypeIdVoid:16429 case ZigTypeIdVoid:
test/stage1/behavior/vector.zig+27
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const mem = std.mem;2const mem = std.mem;
3const expect = std.testing.expect;3const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;
4const builtin = @import("builtin");5const builtin = @import("builtin");
56
6test "implicit cast vector to array - bool" {7test "implicit cast vector to array - bool" {
...@@ -250,3 +251,29 @@ test "initialize vector which is a struct field" {...@@ -250,3 +251,29 @@ test "initialize vector which is a struct field" {
250 S.doTheTest();251 S.doTheTest();
251 comptime S.doTheTest();252 comptime S.doTheTest();
252}253}
254
255test "vector comparison operators" {
256 const S = struct {
257 fn doTheTest() void {
258 {
259 const v1: @Vector(4, bool) = [_]bool{ true, false, true, false };
260 const v2: @Vector(4, bool) = [_]bool{ false, true, false, true };
261 expectEqual(@splat(4, true), v1 == v1);
262 expectEqual(@splat(4, false), v1 == v2);
263 expectEqual(@splat(4, true), v1 != v2);
264 expectEqual(@splat(4, false), v2 != v2);
265 }
266 {
267 const v1 = @splat(4, @as(u32, 0xc0ffeeee));
268 const v2: @Vector(4, c_uint) = v1;
269 const v3 = @splat(4, @as(u32, 0xdeadbeef));
270 expectEqual(@splat(4, true), v1 == v2);
271 expectEqual(@splat(4, false), v1 == v3);
272 expectEqual(@splat(4, true), v1 != v3);
273 expectEqual(@splat(4, false), v1 != v2);
274 }
275 }
276 };
277 S.doTheTest();
278 comptime S.doTheTest();
279}