authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-19 18:44:09+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-22 00:12:37+02:00
log5f5ab491684f0f5dd235189416f9c3d85e8e9be0
tree51d450c61c1ece9b6208d0904ab306f660502251
parenta492a607d5410b1136db3a63fabd01c10827144c

Value: implement `compareAllWithZero` for `bytes` and `str_lit`

Closes #10692

4 files changed, 47 insertions(+), 12 deletions(-)

src/Sema.zig+4-4
......@@ -11842,7 +11842,7 @@ fn zirShl(
1184211842 if (scalar_ty.zigTypeTag() == .ComptimeInt) {
1184311843 break :val shifted.wrapped_result;
1184411844 }
11845 if (shifted.overflow_bit.compareAllWithZero(.eq)) {
11845 if (shifted.overflow_bit.compareAllWithZero(.eq, sema.mod)) {
1184611846 break :val shifted.wrapped_result;
1184711847 }
1184811848 return sema.fail(block, src, "operation caused overflow", .{});
......@@ -12831,7 +12831,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1283112831 const lhs_val = maybe_lhs_val orelse unreachable;
1283212832 const rhs_val = maybe_rhs_val orelse unreachable;
1283312833 const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod) catch unreachable;
12834 if (!rem.compareAllWithZero(.eq)) {
12834 if (!rem.compareAllWithZero(.eq, mod)) {
1283512835 return sema.fail(block, src, "ambiguous coercion of division operands '{s}' and '{s}'; non-zero remainder '{}'", .{
1283612836 @tagName(lhs_ty.tag()), @tagName(rhs_ty.tag()), rem.fmtValue(resolved_type, sema.mod),
1283712837 });
......@@ -13024,7 +13024,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1302413024 if (maybe_rhs_val) |rhs_val| {
1302513025 if (is_int) {
1302613026 const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod);
13027 if (!(modulus_val.compareAllWithZero(.eq))) {
13027 if (!(modulus_val.compareAllWithZero(.eq, mod))) {
1302813028 return sema.fail(block, src, "exact division produced remainder", .{});
1302913029 }
1303013030 const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, mod);
......@@ -13035,7 +13035,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1303513035 return sema.addConstant(resolved_type, res);
1303613036 } else {
1303713037 const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod);
13038 if (!(modulus_val.compareAllWithZero(.eq))) {
13038 if (!(modulus_val.compareAllWithZero(.eq, mod))) {
1303913039 return sema.fail(block, src, "exact division produced remainder", .{});
1304013040 }
1304113041 return sema.addConstant(
src/type.zig+3-3
......@@ -5533,7 +5533,7 @@ pub const Type = extern union {
55335533 }
55345534 const S = struct {
55355535 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, m: *Module) ?usize {
5536 if (int_val.compareAllWithZero(.lt)) return null;
5536 if (int_val.compareAllWithZero(.lt, m)) return null;
55375537 var end_payload: Value.Payload.U64 = .{
55385538 .base = .{ .tag = .int_u64 },
55395539 .data = end,
......@@ -6556,12 +6556,12 @@ pub const Type = extern union {
65566556 if (!d.mutable and d.pointee_type.eql(Type.u8, mod)) {
65576557 switch (d.size) {
65586558 .Slice => {
6559 if (sent.compareAllWithZero(.eq)) {
6559 if (sent.compareAllWithZero(.eq, mod)) {
65606560 return Type.initTag(.const_slice_u8_sentinel_0);
65616561 }
65626562 },
65636563 .Many => {
6564 if (sent.compareAllWithZero(.eq)) {
6564 if (sent.compareAllWithZero(.eq, mod)) {
65656565 return Type.initTag(.manyptr_const_u8_sentinel_0);
65666566 }
65676567 },
src/value.zig+29-5
......@@ -2076,13 +2076,22 @@ pub const Value = extern union {
20762076 /// For vectors, returns true if comparison is true for ALL elements.
20772077 ///
20782078 /// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`
2079 pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator) bool {
2080 return compareAllWithZeroAdvanced(lhs, op, null) catch unreachable;
2079 pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, mod: *Module) bool {
2080 return compareAllWithZeroAdvancedExtra(lhs, op, mod, null) catch unreachable;
20812081 }
20822082
20832083 pub fn compareAllWithZeroAdvanced(
20842084 lhs: Value,
20852085 op: std.math.CompareOperator,
2086 sema: *Sema,
2087 ) Module.CompileError!bool {
2088 return compareAllWithZeroAdvancedExtra(lhs, op, sema.mod, sema);
2089 }
2090
2091 pub fn compareAllWithZeroAdvancedExtra(
2092 lhs: Value,
2093 op: std.math.CompareOperator,
2094 mod: *Module,
20862095 opt_sema: ?*Sema,
20872096 ) Module.CompileError!bool {
20882097 if (lhs.isInf()) {
......@@ -2095,10 +2104,25 @@ pub const Value = extern union {
20952104 }
20962105
20972106 switch (lhs.tag()) {
2098 .repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvanced(op, opt_sema),
2107 .repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvancedExtra(op, mod, opt_sema),
20992108 .aggregate => {
21002109 for (lhs.castTag(.aggregate).?.data) |elem_val| {
2101 if (!(try elem_val.compareAllWithZeroAdvanced(op, opt_sema))) return false;
2110 if (!(try elem_val.compareAllWithZeroAdvancedExtra(op, mod, opt_sema))) return false;
2111 }
2112 return true;
2113 },
2114 .str_lit => {
2115 const str_lit = lhs.castTag(.str_lit).?.data;
2116 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
2117 for (bytes) |byte| {
2118 if (!std.math.compare(byte, op, 0)) return false;
2119 }
2120 return true;
2121 },
2122 .bytes => {
2123 const bytes = lhs.castTag(.bytes).?.data;
2124 for (bytes) |byte| {
2125 if (!std.math.compare(byte, op, 0)) return false;
21022126 }
21032127 return true;
21042128 },
......@@ -3103,7 +3127,7 @@ pub const Value = extern union {
31033127 .int_i64,
31043128 .int_big_positive,
31053129 .int_big_negative,
3106 => compareAllWithZero(self, .eq),
3130 => self.orderAgainstZero().compare(.eq),
31073131
31083132 .undef => unreachable,
31093133 .unreachable_value => unreachable,
test/behavior/vector.zig+11
......@@ -1286,3 +1286,14 @@ test "store to vector in slice" {
12861286 s[i] = s[0];
12871287 try expectEqual(v[1], v[0]);
12881288}
1289
1290test "addition of vectors represented as strings" {
1291 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1292 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1293 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1294
1295 const V = @Vector(3, u8);
1296 const foo: V = "foo".*;
1297 const bar: V = @typeName(u32).*;
1298 try expectEqual(V{ 219, 162, 161 }, foo + bar);
1299}