authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-11 11:55:27+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-11 13:06:22+02:00
logdb4262417009c0060e09a8cf8af088b76320aad0
tree6a06b0bf90d6589cc9bbb13208b5ee2c02e98526
parent98a5998d831fd0fa7b897aafacf4c2af18e64ed1

Sema: enable shl and bitwise for vectors at runtime


2 files changed, 41 insertions(+), 15 deletions(-)

src/Sema.zig+26-15
......@@ -8059,7 +8059,6 @@ fn zirBitwise(
80598059 rhs_ty.arrayLen(),
80608060 });
80618061 }
8062 return sema.fail(block, src, "TODO implement support for vectors in zirBitwise", .{});
80638062 } else if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) {
80648063 return sema.fail(block, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{
80658064 lhs_ty,
......@@ -8075,6 +8074,9 @@ fn zirBitwise(
80758074
80768075 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
80778076 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
8077 if (resolved_type.zigTypeTag() == .Vector) {
8078 return sema.fail(block, src, "TODO implement zirBitwise for vectors at comptime", .{});
8079 }
80788080 const result_val = switch (air_tag) {
80798081 .bit_and => try lhs_val.bitwiseAnd(rhs_val, sema.arena),
80808082 .bit_or => try lhs_val.bitwiseOr(rhs_val, sema.arena),
......@@ -10985,19 +10987,21 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
1098510987 const src = inst_data.src();
1098610988 const operand = sema.resolveInst(inst_data.operand);
1098710989 const operand_ty = sema.typeOf(operand);
10988 return sema.log2IntType(block, operand_ty, src);
10990 const res_ty = try sema.log2IntType(block, operand_ty, src);
10991 return sema.addType(res_ty);
1098910992}
1099010993
1099110994fn zirLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1099210995 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1099310996 const src = inst_data.src();
1099410997 const operand = try sema.resolveType(block, src, inst_data.operand);
10995 return sema.log2IntType(block, operand, src);
10998 const res_ty = try sema.log2IntType(block, operand, src);
10999 return sema.addType(res_ty);
1099611000}
1099711001
10998fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Air.Inst.Ref {
11002fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {
1099911003 switch (operand.zigTypeTag()) {
11000 .ComptimeInt => return Air.Inst.Ref.comptime_int_type,
11004 .ComptimeInt => return Type.@"comptime_int",
1100111005 .Int => {
1100211006 const bits = operand.bitSize(sema.mod.getTarget());
1100311007 const count = if (bits == 0)
......@@ -11010,16 +11014,24 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
1101011014 }
1101111015 break :blk count;
1101211016 };
11013 const res = try Module.makeIntType(sema.arena, .unsigned, count);
11014 return sema.addType(res);
11017 return Module.makeIntType(sema.arena, .unsigned, count);
1101511018 },
11016 else => return sema.fail(
11017 block,
11018 src,
11019 "bit shifting operation expected integer type, found '{}'",
11020 .{operand},
11021 ),
11019 .Vector => {
11020 const elem_ty = operand.elemType2();
11021 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);
11022 return Type.Tag.vector.create(sema.arena, .{
11023 .len = operand.arrayLen(),
11024 .elem_type = log2_elem_ty,
11025 });
11026 },
11027 else => {},
1102211028 }
11029 return sema.fail(
11030 block,
11031 src,
11032 "bit shifting operation expected integer type, found '{}'",
11033 .{operand},
11034 );
1102311035}
1102411036
1102511037fn zirTypeofPeer(
......@@ -15676,8 +15688,7 @@ fn elemPtr(
1567615688 },
1567715689 }
1567815690 },
15679 .Array => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src),
15680 .Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}),
15691 .Array, .Vector => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src),
1568115692 .Struct => {
1568215693 // Tuple field access.
1568315694 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
src/value.zig+15
......@@ -1819,7 +1819,22 @@ pub const Value = extern union {
18191819 }
18201820
18211821 /// Asserts the value is comparable.
1822 /// For vectors this is only valid with op == .eq.
18221823 pub fn compareWithZero(lhs: Value, op: std.math.CompareOperator) bool {
1824 switch (lhs.tag()) {
1825 .repeated => {
1826 assert(op == .eq);
1827 return lhs.castTag(.repeated).?.data.compareWithZero(.eq);
1828 },
1829 .array => {
1830 assert(op == .eq);
1831 for (lhs.cast(Payload.Array).?.data) |elem_val| {
1832 if (!elem_val.compareWithZero(.eq)) return false;
1833 }
1834 return true;
1835 },
1836 else => {},
1837 }
18231838 return orderAgainstZero(lhs).compare(op);
18241839 }
18251840