authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2022-03-24 23:27:23+01:00
committergravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2022-03-25 19:14:11+01:00
logcd46daf7d047eeceb7690e2739af5952d60c3884
treed7aa543ebca4fb0edb1738617e703f90bbaaf2e5
parentf47db0a0dbf64f1fef0ba86bd9f684a5df29bc3d

sema: coerce inputs to vectors in zirSelect


2 files changed, 46 insertions(+), 30 deletions(-)

src/Sema.zig+13-26
...@@ -14805,6 +14805,7 @@ fn analyzeShuffle(...@@ -14805,6 +14805,7 @@ fn analyzeShuffle(
14805fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {14805fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14806 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;14806 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
14807 const extra = sema.code.extraData(Zir.Inst.Select, inst_data.payload_index).data;14807 const extra = sema.code.extraData(Zir.Inst.Select, inst_data.payload_index).data;
14808 const target = sema.mod.getTarget();
1480814809
14809 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };14810 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
14810 const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };14811 const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
...@@ -14813,35 +14814,21 @@ fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14813,35 +14814,21 @@ fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1481314814
14814 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);14815 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
14815 try sema.checkVectorElemType(block, elem_ty_src, elem_ty);14816 try sema.checkVectorElemType(block, elem_ty_src, elem_ty);
14816 const pred = sema.resolveInst(extra.pred);14817 const pred_uncoerced = sema.resolveInst(extra.pred);
14817 const a = sema.resolveInst(extra.a);14818 const pred_ty = sema.typeOf(pred_uncoerced);
14818 const b = sema.resolveInst(extra.b);
14819 const target = sema.mod.getTarget();
14820
14821 const pred_ty = sema.typeOf(pred);
14822 switch (try pred_ty.zigTypeTagOrPoison()) {
14823 .Vector => {
14824 const scalar_ty = pred_ty.childType();
14825 if (!scalar_ty.eql(Type.bool, target)) {
14826 const bool_vec_ty = try Type.vector(sema.arena, pred_ty.vectorLen(), Type.bool);
14827 return sema.fail(block, pred_src, "Expected '{}', found '{}'", .{ bool_vec_ty.fmt(target), pred_ty.fmt(target) });
14828 }
14829 },
14830 else => return sema.fail(block, pred_src, "Expected vector type, found '{}'", .{pred_ty.fmt(target)}),
14831 }
1483214819
14833 const vec_len = pred_ty.vectorLen();14820 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison()) {
14834 const vec_ty = try Type.vector(sema.arena, vec_len, elem_ty);14821 .Vector, .Array => pred_ty.arrayLen(),
14822 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(target)}),
14823 };
14824 const vec_len = try sema.usizeCast(block, pred_src, vec_len_u64);
1483514825
14836 const a_ty = sema.typeOf(a);14826 const bool_vec_ty = try Type.vector(sema.arena, vec_len, Type.bool);
14837 if (!a_ty.eql(vec_ty, target)) {14827 const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src);
14838 return sema.fail(block, a_src, "Expected '{}', found '{}'", .{ vec_ty.fmt(target), a_ty.fmt(target) });
14839 }
1484014828
14841 const b_ty = sema.typeOf(b);14829 const vec_ty = try Type.vector(sema.arena, vec_len, elem_ty);
14842 if (!b_ty.eql(vec_ty, target)) {14830 const a = try sema.coerce(block, vec_ty, sema.resolveInst(extra.a), a_src);
14843 return sema.fail(block, b_src, "Expected '{}', found '{}'", .{ vec_ty.fmt(target), b_ty.fmt(target) });14831 const b = try sema.coerce(block, vec_ty, sema.resolveInst(extra.b), b_src);
14844 }
1484514832
14846 const maybe_pred = try sema.resolveMaybeUndefVal(block, pred_src, pred);14833 const maybe_pred = try sema.resolveMaybeUndefVal(block, pred_src, pred);
14847 const maybe_a = try sema.resolveMaybeUndefVal(block, a_src, a);14834 const maybe_a = try sema.resolveMaybeUndefVal(block, a_src, a);
test/behavior/select.zig+33-4
...@@ -3,18 +3,18 @@ const builtin = @import("builtin");...@@ -3,18 +3,18 @@ const builtin = @import("builtin");
3const mem = std.mem;3const mem = std.mem;
4const expect = std.testing.expect;4const expect = std.testing.expect;
55
6test "@select" {6test "@select vectors" {
7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1212
13 try doTheTest();13 comptime try selectVectors();
14 comptime try doTheTest();14 try selectVectors();
15}15}
1616
17fn doTheTest() !void {17fn selectVectors() !void {
18 var a = @Vector(4, bool){ true, false, true, false };18 var a = @Vector(4, bool){ true, false, true, false };
19 var b = @Vector(4, i32){ -1, 4, 999, -31 };19 var b = @Vector(4, i32){ -1, 4, 999, -31 };
20 var c = @Vector(4, i32){ -5, 1, 0, 1234 };20 var c = @Vector(4, i32){ -5, 1, 0, 1234 };
...@@ -30,3 +30,32 @@ fn doTheTest() !void {...@@ -30,3 +30,32 @@ fn doTheTest() !void {
30 var xyz = @select(f32, x, y, z);30 var xyz = @select(f32, x, y, z);
31 try expect(mem.eql(f32, &@as([4]f32, xyz), &[4]f32{ 0.0, 312.1, -145.9, -3381.233 }));31 try expect(mem.eql(f32, &@as([4]f32, xyz), &[4]f32{ 0.0, 312.1, -145.9, -3381.233 }));
32}32}
33
34test "@select arrays" {
35 if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO
36 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
38 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
39 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
40 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
41
42 comptime try selectArrays();
43 try selectArrays();
44}
45
46fn selectArrays() !void {
47 var a = [4]bool{ false, true, false, true };
48 var b = [4]usize{ 0, 1, 2, 3 };
49 var c = [4]usize{ 4, 5, 6, 7 };
50 var abc = @select(usize, a, b, c);
51 try expect(abc[0] == 4);
52 try expect(abc[1] == 1);
53 try expect(abc[2] == 6);
54 try expect(abc[3] == 3);
55
56 var x = [4]bool{ false, false, false, true };
57 var y = [4]f32{ 0.001, 33.4, 836, -3381.233 };
58 var z = [4]f32{ 0.0, 312.1, -145.9, 9993.55 };
59 var xyz = @select(f32, x, y, z);
60 try expect(mem.eql(f32, &@as([4]f32, xyz), &[4]f32{ 0.0, 312.1, -145.9, -3381.233 }));
61}