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(
1480514805fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1480614806 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1480714807 const extra = sema.code.extraData(Zir.Inst.Select, inst_data.payload_index).data;
14808 const target = sema.mod.getTarget();
1480814809
1480914810 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1481014811 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.
1481314814
1481414815 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
1481514816 try sema.checkVectorElemType(block, elem_ty_src, elem_ty);
14816 const pred = sema.resolveInst(extra.pred);
14817 const a = sema.resolveInst(extra.a);
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 }
14817 const pred_uncoerced = sema.resolveInst(extra.pred);
14818 const pred_ty = sema.typeOf(pred_uncoerced);
1483214819
14833 const vec_len = pred_ty.vectorLen();
14834 const vec_ty = try Type.vector(sema.arena, vec_len, elem_ty);
14820 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison()) {
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);
14837 if (!a_ty.eql(vec_ty, target)) {
14838 return sema.fail(block, a_src, "Expected '{}', found '{}'", .{ vec_ty.fmt(target), a_ty.fmt(target) });
14839 }
14826 const bool_vec_ty = try Type.vector(sema.arena, vec_len, Type.bool);
14827 const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src);
1484014828
14841 const b_ty = sema.typeOf(b);
14842 if (!b_ty.eql(vec_ty, target)) {
14843 return sema.fail(block, b_src, "Expected '{}', found '{}'", .{ vec_ty.fmt(target), b_ty.fmt(target) });
14844 }
14829 const vec_ty = try Type.vector(sema.arena, vec_len, elem_ty);
14830 const a = try sema.coerce(block, vec_ty, sema.resolveInst(extra.a), a_src);
14831 const b = try sema.coerce(block, vec_ty, sema.resolveInst(extra.b), b_src);
1484514832
1484614833 const maybe_pred = try sema.resolveMaybeUndefVal(block, pred_src, pred);
1484714834 const maybe_a = try sema.resolveMaybeUndefVal(block, a_src, a);
test/behavior/select.zig+33-4
......@@ -3,18 +3,18 @@ const builtin = @import("builtin");
33const mem = std.mem;
44const expect = std.testing.expect;
55
6test "@select" {
6test "@select vectors" {
77 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1212
13 try doTheTest();
14 comptime try doTheTest();
13 comptime try selectVectors();
14 try selectVectors();
1515}
1616
17fn doTheTest() !void {
17fn selectVectors() !void {
1818 var a = @Vector(4, bool){ true, false, true, false };
1919 var b = @Vector(4, i32){ -1, 4, 999, -31 };
2020 var c = @Vector(4, i32){ -5, 1, 0, 1234 };
......@@ -30,3 +30,32 @@ fn doTheTest() !void {
3030 var xyz = @select(f32, x, y, z);
3131 try expect(mem.eql(f32, &@as([4]f32, xyz), &[4]f32{ 0.0, 312.1, -145.9, -3381.233 }));
3232}
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}