diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 5cb9c6589ccb..f090e1e8e4ca 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -433,6 +433,14 @@ pub fn eql(a: var, b: @TypeOf(a)) bool { if (!eql(e, b[i])) return false; return true; }, + builtin.TypeId.Vector => { + const info = @typeInfo(T).Vector; + var i: usize = 0; + while (i < info.len) : (i += 1) { + if (!eql(a[i], b[i])) return false; + } + return true; + }, builtin.TypeId.Pointer => { const info = @typeInfo(T).Pointer; switch (info.size) { @@ -510,6 +518,13 @@ test "std.meta.eql" { testing.expect(eql(EU.tst(true), EU.tst(true))); testing.expect(eql(EU.tst(false), EU.tst(false))); testing.expect(!eql(EU.tst(false), EU.tst(true))); + + var v1 = @splat(4, @as(u32, 1)); + var v2 = @splat(4, @as(u32, 1)); + var v3 = @splat(4, @as(u32, 2)); + + testing.expect(eql(v1, v2)); + testing.expect(!eql(v1, v3)); } test "intToEnum with error return" { diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index f33b5d5261ef..989653116c57 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -276,8 +276,11 @@ test "mmap" { testing.expectEqual(@as(usize, 1234), data.len); // By definition the data returned by mmap is zero-filled - std.mem.set(u8, data[0 .. data.len - 1], 0x55); - testing.expect(mem.indexOfScalar(u8, data, 0).? == 1234 - 1); + testing.expect(mem.eql(u8, data, &[_]u8{0x00} ** 1234)); + + // Make sure the memory is writeable as requested + std.mem.set(u8, data, 0x55); + testing.expect(mem.eql(u8, data, &[_]u8{0x55} ** 1234)); } const test_out_file = "os_tmp_test"; @@ -300,10 +303,7 @@ test "mmap" { // Map the whole file { - const file = try fs.cwd().createFile(test_out_file, .{ - .read = true, - .truncate = false, - }); + const file = try fs.cwd().openFile(test_out_file, .{}); defer file.close(); const data = try os.mmap( @@ -327,15 +327,12 @@ test "mmap" { // Map the upper half of the file { - const file = try fs.cwd().createFile(test_out_file, .{ - .read = true, - .truncate = false, - }); + const file = try fs.cwd().openFile(test_out_file, .{}); defer file.close(); const data = try os.mmap( null, - alloc_size, + alloc_size / 2, os.PROT_READ, os.MAP_PRIVATE, file.handle, diff --git a/lib/std/testing.zig b/lib/std/testing.zig index f8247b5a9de1..8a4491d1d7a2 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -56,7 +56,6 @@ pub fn expectEqual(expected: var, actual: @TypeOf(expected)) void { .EnumLiteral, .Enum, .Fn, - .Vector, .ErrorSet, => { if (actual != expected) { @@ -88,6 +87,15 @@ pub fn expectEqual(expected: var, actual: @TypeOf(expected)) void { .Array => |array| expectEqualSlices(array.child, &expected, &actual), + .Vector => |vectorType| { + var i: usize = 0; + while (i < vectorType.len) : (i += 1) { + if (!std.meta.eql(expected[i], actual[i])) { + std.debug.panic("index {} incorrect. expected {}, found {}", .{ i, expected[i], actual[i] }); + } + } + }, + .Struct => |structType| { inline for (structType.fields) |field| { expectEqual(@field(expected, field.name), @field(actual, field.name)); @@ -202,3 +210,10 @@ test "expectEqual nested array" { expectEqual(a, b); } + +test "expectEqual vector" { + var a = @splat(4, @as(u32, 4)); + var b = @splat(4, @as(u32, 4)); + + expectEqual(a, b); +} diff --git a/src/analyze.cpp b/src/analyze.cpp index c8b63f4535b2..fc1a805d825c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -6937,9 +6937,9 @@ static void render_const_val_array(CodeGen *g, Buf *buf, Buf *type_name, ZigValu return; } case ConstArraySpecialNone: { - ZigValue *base = &array->data.s_none.elements[start]; - assert(base != nullptr); assert(start + len <= const_val->type->data.array.len); + ZigValue *base = &array->data.s_none.elements[start]; + assert(len == 0 || base != nullptr); buf_appendf(buf, "%s{", buf_ptr(type_name)); for (uint64_t i = 0; i < len; i += 1) { diff --git a/src/ir.cpp b/src/ir.cpp index 3fc2ddadebd0..570fdd0b05d9 100644 --- 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/src/link.cpp b/src/link.cpp index d5722ac2f6ab..2771b694c1fb 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -2642,13 +2642,6 @@ void codegen_link(CodeGen *g) { lj.rpath_table.init(4); lj.codegen = g; - if (g->verbose_llvm_ir) { - fprintf(stderr, "\nOptimization:\n"); - fprintf(stderr, "---------------\n"); - fflush(stderr); - LLVMDumpModule(g->module); - } - if (g->out_type == OutTypeObj) { lj.args.append("-r"); } diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig index 338f24d8062b..e89399c5e257 100644 --- 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(); +}