authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-05-07 22:12:04+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:29-07:00
log2ffef605c75b62ba49e21bfb3256537a4a2c0a5e
treeba18403418bcd0c1e6f6f52f9effa51dfd91c878
parent4c3c605e5f53c91430efac821ce1b863cbb5bf06

Replace uses of Value.zero, Value.one, Value.negative_one

This is a bit nasty, mainly because Type.onePossibleValue is now errorable, which is a quite viral change.

16 files changed, 286 insertions(+), 223 deletions(-)

src/Air.zig+1-1
...@@ -1485,7 +1485,7 @@ pub fn refToIndexAllowNone(inst: Inst.Ref) ?Inst.Index {...@@ -1485,7 +1485,7 @@ pub fn refToIndexAllowNone(inst: Inst.Ref) ?Inst.Index {
1485}1485}
14861486
1487/// Returns `null` if runtime-known.1487/// Returns `null` if runtime-known.
1488pub fn value(air: Air, inst: Inst.Ref, mod: *const Module) ?Value {1488pub fn value(air: Air, inst: Inst.Ref, mod: *Module) !?Value {
1489 const ref_int = @enumToInt(inst);1489 const ref_int = @enumToInt(inst);
1490 if (ref_int < ref_start_index) {1490 if (ref_int < ref_start_index) {
1491 const ip_index = @intToEnum(InternPool.Index, ref_int);1491 const ip_index = @intToEnum(InternPool.Index, ref_int);
src/Module.zig+11-1
...@@ -5750,7 +5750,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {...@@ -5750,7 +5750,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
57505750
5751 const arg_val = if (!arg_tv.val.isGenericPoison())5751 const arg_val = if (!arg_tv.val.isGenericPoison())
5752 arg_tv.val5752 arg_tv.val
5753 else if (arg_tv.ty.onePossibleValue(mod)) |opv|5753 else if (try arg_tv.ty.onePossibleValue(mod)) |opv|
5754 opv5754 opv
5755 else5755 else
5756 break :t arg_tv.ty;5756 break :t arg_tv.ty;
...@@ -6887,6 +6887,16 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {...@@ -6887,6 +6887,16 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
6887}6887}
68886888
6889pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {6889pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
6890 if (std.debug.runtime_safety) {
6891 // TODO: decide if this also works for ABI int types like enums
6892 const tag = ty.zigTypeTag(mod);
6893 assert(tag == .Int or tag == .ComptimeInt);
6894 }
6895 if (@TypeOf(x) == comptime_int) {
6896 if (comptime std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);
6897 if (comptime std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);
6898 @compileError("Out-of-range comptime_int passed to Module.intValue");
6899 }
6890 if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);6900 if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);
6891 if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);6901 if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);
6892 var limbs_buffer: [4]usize = undefined;6902 var limbs_buffer: [4]usize = undefined;
src/Sema.zig+153-104
...@@ -3062,9 +3062,9 @@ fn zirEnumDecl(...@@ -3062,9 +3062,9 @@ fn zirEnumDecl(
3062 }3062 }
3063 } else if (any_values) {3063 } else if (any_values) {
3064 const tag_val = if (last_tag_val) |val|3064 const tag_val = if (last_tag_val) |val|
3065 try sema.intAdd(val, Value.one, enum_obj.tag_ty)3065 try sema.intAdd(val, try mod.intValue(enum_obj.tag_ty, 1), enum_obj.tag_ty)
3066 else3066 else
3067 Value.zero;3067 try mod.intValue(enum_obj.tag_ty, 0);
3068 last_tag_val = tag_val;3068 last_tag_val = tag_val;
3069 const copied_tag_val = try tag_val.copy(decl_arena_allocator);3069 const copied_tag_val = try tag_val.copy(decl_arena_allocator);
3070 const gop_val = enum_obj.values.getOrPutAssumeCapacityContext(copied_tag_val, .{3070 const gop_val = enum_obj.values.getOrPutAssumeCapacityContext(copied_tag_val, .{
...@@ -4709,7 +4709,7 @@ fn zirValidateArrayInit(...@@ -4709,7 +4709,7 @@ fn zirValidateArrayInit(
4709 // Determine whether the value stored to this pointer is comptime-known.4709 // Determine whether the value stored to this pointer is comptime-known.
47104710
4711 if (array_ty.isTuple()) {4711 if (array_ty.isTuple()) {
4712 if (array_ty.structFieldValueComptime(mod, i)) |opv| {4712 if (try array_ty.structFieldValueComptime(mod, i)) |opv| {
4713 element_vals[i] = opv;4713 element_vals[i] = opv;
4714 continue;4714 continue;
4715 }4715 }
...@@ -8132,7 +8132,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8132,7 +8132,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
8132 if (!op_ty.isAnyError()) {8132 if (!op_ty.isAnyError()) {
8133 const names = op_ty.errorSetNames();8133 const names = op_ty.errorSetNames();
8134 switch (names.len) {8134 switch (names.len) {
8135 0 => return sema.addConstant(Type.err_int, Value.zero),8135 0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)),
8136 1 => return sema.addIntUnsigned(Type.err_int, sema.mod.global_error_set.get(names[0]).?),8136 1 => return sema.addIntUnsigned(Type.err_int, sema.mod.global_error_set.get(names[0]).?),
8137 else => {},8137 else => {},
8138 }8138 }
...@@ -8167,7 +8167,7 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8167,7 +8167,7 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
8167 try sema.requireRuntimeBlock(block, src, operand_src);8167 try sema.requireRuntimeBlock(block, src, operand_src);
8168 if (block.wantSafety()) {8168 if (block.wantSafety()) {
8169 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);8169 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);
8170 const zero_val = try sema.addConstant(Type.err_int, Value.zero);8170 const zero_val = try sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0));
8171 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);8171 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);
8172 const ok = try block.addBinOp(.bit_and, is_lt_len, is_non_zero);8172 const ok = try block.addBinOp(.bit_and, is_lt_len, is_non_zero);
8173 try sema.addSafetyCheck(block, ok, .invalid_error_code);8173 try sema.addSafetyCheck(block, ok, .invalid_error_code);
...@@ -9656,7 +9656,7 @@ fn intCast(...@@ -9656,7 +9656,7 @@ fn intCast(
96569656
9657 if (wanted_bits == 0) {9657 if (wanted_bits == 0) {
9658 const ok = if (is_vector) ok: {9658 const ok = if (is_vector) ok: {
9659 const zeros = try Value.Tag.repeated.create(sema.arena, Value.zero);9659 const zeros = try Value.Tag.repeated.create(sema.arena, try mod.intValue(operand_scalar_ty, 0));
9660 const zero_inst = try sema.addConstant(sema.typeOf(operand), zeros);9660 const zero_inst = try sema.addConstant(sema.typeOf(operand), zeros);
9661 const is_in_range = try block.addCmpVector(operand, zero_inst, .eq);9661 const is_in_range = try block.addCmpVector(operand, zero_inst, .eq);
9662 const all_in_range = try block.addInst(.{9662 const all_in_range = try block.addInst(.{
...@@ -9665,7 +9665,7 @@ fn intCast(...@@ -9665,7 +9665,7 @@ fn intCast(
9665 });9665 });
9666 break :ok all_in_range;9666 break :ok all_in_range;
9667 } else ok: {9667 } else ok: {
9668 const zero_inst = try sema.addConstant(sema.typeOf(operand), Value.zero);9668 const zero_inst = try sema.addConstant(sema.typeOf(operand), try mod.intValue(operand_ty, 0));
9669 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);9669 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);
9670 break :ok is_in_range;9670 break :ok is_in_range;
9671 };9671 };
...@@ -9705,8 +9705,9 @@ fn intCast(...@@ -9705,8 +9705,9 @@ fn intCast(
9705 // If the destination type is signed, then we need to double its9705 // If the destination type is signed, then we need to double its
9706 // range to account for negative values.9706 // range to account for negative values.
9707 const dest_range_val = if (wanted_info.signedness == .signed) range_val: {9707 const dest_range_val = if (wanted_info.signedness == .signed) range_val: {
9708 const range_minus_one = try dest_max_val.shl(Value.one, unsigned_operand_ty, sema.arena, sema.mod);9708 const one = try mod.intValue(unsigned_operand_ty, 1);
9709 break :range_val try sema.intAdd(range_minus_one, Value.one, unsigned_operand_ty);9709 const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, sema.mod);
9710 break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty);
9710 } else dest_max_val;9711 } else dest_max_val;
9711 const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val);9712 const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val);
97129713
...@@ -9747,7 +9748,7 @@ fn intCast(...@@ -9747,7 +9748,7 @@ fn intCast(
9747 // no shrinkage, yes sign loss9748 // no shrinkage, yes sign loss
9748 // requirement: signed to unsigned >= 09749 // requirement: signed to unsigned >= 0
9749 const ok = if (is_vector) ok: {9750 const ok = if (is_vector) ok: {
9750 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);9751 const zero_val = try Value.Tag.repeated.create(sema.arena, try mod.intValue(operand_scalar_ty, 0));
9751 const zero_inst = try sema.addConstant(operand_ty, zero_val);9752 const zero_inst = try sema.addConstant(operand_ty, zero_val);
9752 const is_in_range = try block.addCmpVector(operand, zero_inst, .gte);9753 const is_in_range = try block.addCmpVector(operand, zero_inst, .gte);
9753 const all_in_range = try block.addInst(.{9754 const all_in_range = try block.addInst(.{
...@@ -9759,7 +9760,7 @@ fn intCast(...@@ -9759,7 +9760,7 @@ fn intCast(
9759 });9760 });
9760 break :ok all_in_range;9761 break :ok all_in_range;
9761 } else ok: {9762 } else ok: {
9762 const zero_inst = try sema.addConstant(operand_ty, Value.zero);9763 const zero_inst = try sema.addConstant(operand_ty, try mod.intValue(operand_ty, 0));
9763 const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst);9764 const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst);
9764 break :ok is_in_range;9765 break :ok is_in_range;
9765 };9766 };
...@@ -11250,7 +11251,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11250,7 +11251,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1125011251
11251 while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({11252 while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({
11252 // Previous validation has resolved any possible lazy values.11253 // Previous validation has resolved any possible lazy values.
11253 item = try sema.intAddScalar(item, Value.one, operand_ty);11254 item = try sema.intAddScalar(item, try mod.intValue(operand_ty, 1), operand_ty);
11254 }) {11255 }) {
11255 cases_len += 1;11256 cases_len += 1;
1125611257
...@@ -11696,7 +11697,7 @@ const RangeSetUnhandledIterator = struct {...@@ -11696,7 +11697,7 @@ const RangeSetUnhandledIterator = struct {
11696 fn next(it: *RangeSetUnhandledIterator) !?Value {11697 fn next(it: *RangeSetUnhandledIterator) !?Value {
11697 while (it.range_i < it.ranges.len) : (it.range_i += 1) {11698 while (it.range_i < it.ranges.len) : (it.range_i += 1) {
11698 if (!it.first) {11699 if (!it.first) {
11699 it.cur = try it.sema.intAddScalar(it.cur, Value.one, it.ty);11700 it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty);
11700 }11701 }
11701 it.first = false;11702 it.first = false;
11702 if (it.cur.compareScalar(.lt, it.ranges[it.range_i].first, it.ty, it.sema.mod)) {11703 if (it.cur.compareScalar(.lt, it.ranges[it.range_i].first, it.ty, it.sema.mod)) {
...@@ -11705,7 +11706,7 @@ const RangeSetUnhandledIterator = struct {...@@ -11705,7 +11706,7 @@ const RangeSetUnhandledIterator = struct {
11705 it.cur = it.ranges[it.range_i].last;11706 it.cur = it.ranges[it.range_i].last;
11706 }11707 }
11707 if (!it.first) {11708 if (!it.first) {
11708 it.cur = try it.sema.intAddScalar(it.cur, Value.one, it.ty);11709 it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty);
11709 }11710 }
11710 it.first = false;11711 it.first = false;
11711 if (it.cur.compareScalar(.lte, it.max, it.ty, it.sema.mod)) {11712 if (it.cur.compareScalar(.lte, it.max, it.ty, it.sema.mod)) {
...@@ -12150,7 +12151,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -12150,7 +12151,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
12150 // into the final binary, and never loads the data into memory.12151 // into the final binary, and never loads the data into memory.
12151 // - When a Decl is destroyed, it can free the `*Module.EmbedFile`.12152 // - When a Decl is destroyed, it can free the `*Module.EmbedFile`.
12152 embed_file.owner_decl = try anon_decl.finish(12153 embed_file.owner_decl = try anon_decl.finish(
12153 try Type.array(anon_decl.arena(), embed_file.bytes.len, Value.zero, Type.u8, mod),12154 try Type.array(anon_decl.arena(), embed_file.bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
12154 try Value.Tag.bytes.create(anon_decl.arena(), bytes_including_null),12155 try Value.Tag.bytes.create(anon_decl.arena(), bytes_including_null),
12155 0, // default alignment12156 0, // default alignment
12156 );12157 );
...@@ -12235,14 +12236,14 @@ fn zirShl(...@@ -12235,14 +12236,14 @@ fn zirShl(
12235 var i: usize = 0;12236 var i: usize = 0;
12236 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {12237 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
12237 const rhs_elem = try rhs_val.elemValue(sema.mod, i);12238 const rhs_elem = try rhs_val.elemValue(sema.mod, i);
12238 if (rhs_elem.compareHetero(.lt, Value.zero, mod)) {12239 if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) {
12239 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{12240 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
12240 rhs_elem.fmtValue(scalar_ty, sema.mod),12241 rhs_elem.fmtValue(scalar_ty, sema.mod),
12241 i,12242 i,
12242 });12243 });
12243 }12244 }
12244 }12245 }
12245 } else if (rhs_val.compareHetero(.lt, Value.zero, mod)) {12246 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {
12246 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{12247 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
12247 rhs_val.fmtValue(scalar_ty, sema.mod),12248 rhs_val.fmtValue(scalar_ty, sema.mod),
12248 });12249 });
...@@ -12348,7 +12349,7 @@ fn zirShl(...@@ -12348,7 +12349,7 @@ fn zirShl(
12348 })12349 })
12349 else12350 else
12350 ov_bit;12351 ov_bit;
12351 const zero_ov = try sema.addConstant(Type.u1, Value.zero);12352 const zero_ov = try sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0));
12352 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);12353 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
1235312354
12354 try sema.addSafetyCheck(block, no_ov, .shl_overflow);12355 try sema.addSafetyCheck(block, no_ov, .shl_overflow);
...@@ -12417,14 +12418,14 @@ fn zirShr(...@@ -12417,14 +12418,14 @@ fn zirShr(
12417 var i: usize = 0;12418 var i: usize = 0;
12418 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {12419 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
12419 const rhs_elem = try rhs_val.elemValue(sema.mod, i);12420 const rhs_elem = try rhs_val.elemValue(sema.mod, i);
12420 if (rhs_elem.compareHetero(.lt, Value.zero, mod)) {12421 if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) {
12421 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{12422 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
12422 rhs_elem.fmtValue(scalar_ty, sema.mod),12423 rhs_elem.fmtValue(scalar_ty, sema.mod),
12423 i,12424 i,
12424 });12425 });
12425 }12426 }
12426 }12427 }
12427 } else if (rhs_val.compareHetero(.lt, Value.zero, mod)) {12428 } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) {
12428 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{12429 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
12429 rhs_val.fmtValue(scalar_ty, sema.mod),12430 rhs_val.fmtValue(scalar_ty, sema.mod),
12430 });12431 });
...@@ -13156,9 +13157,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13156,9 +13157,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13156 }13157 }
1315713158
13158 const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector)13159 const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector)
13159 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))13160 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, try mod.intValue(rhs_scalar_ty, 0)))
13160 else13161 else
13161 try sema.resolveInst(.zero);13162 try sema.addConstant(rhs_ty, try mod.intValue(rhs_ty, 0));
1316213163
13163 return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true);13164 return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true);
13164}13165}
...@@ -13180,9 +13181,9 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -13180,9 +13181,9 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
13180 }13181 }
1318113182
13182 const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector)13183 const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector)
13183 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))13184 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, try mod.intValue(rhs_scalar_ty, 0)))
13184 else13185 else
13185 try sema.resolveInst(.zero);13186 try sema.addConstant(rhs_ty, try mod.intValue(rhs_ty, 0));
1318613187
13187 return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true);13188 return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true);
13188}13189}
...@@ -13293,9 +13294,14 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13293,9 +13294,14 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13293 if (maybe_lhs_val) |lhs_val| {13294 if (maybe_lhs_val) |lhs_val| {
13294 if (!lhs_val.isUndef()) {13295 if (!lhs_val.isUndef()) {
13295 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13296 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13297 const scalar_zero = switch (scalar_tag) {
13298 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
13299 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13300 else => unreachable,
13301 };
13296 const zero_val = if (is_vector) b: {13302 const zero_val = if (is_vector) b: {
13297 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);13303 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
13298 } else Value.zero;13304 } else scalar_zero;
13299 return sema.addConstant(resolved_type, zero_val);13305 return sema.addConstant(resolved_type, zero_val);
13300 }13306 }
13301 }13307 }
...@@ -13318,7 +13324,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13318,7 +13324,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13318 if (lhs_val.isUndef()) {13324 if (lhs_val.isUndef()) {
13319 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {13325 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
13320 if (maybe_rhs_val) |rhs_val| {13326 if (maybe_rhs_val) |rhs_val| {
13321 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {13327 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {
13322 return sema.addConstUndef(resolved_type);13328 return sema.addConstUndef(resolved_type);
13323 }13329 }
13324 }13330 }
...@@ -13427,9 +13433,14 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13427,9 +13433,14 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13427 return sema.failWithUseOfUndef(block, rhs_src);13433 return sema.failWithUseOfUndef(block, rhs_src);
13428 } else {13434 } else {
13429 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13435 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13436 const scalar_zero = switch (scalar_tag) {
13437 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
13438 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13439 else => unreachable,
13440 };
13430 const zero_val = if (is_vector) b: {13441 const zero_val = if (is_vector) b: {
13431 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);13442 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
13432 } else Value.zero;13443 } else scalar_zero;
13433 return sema.addConstant(resolved_type, zero_val);13444 return sema.addConstant(resolved_type, zero_val);
13434 }13445 }
13435 }13446 }
...@@ -13507,8 +13518,13 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13507,8 +13518,13 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13507 } else ok: {13518 } else ok: {
13508 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);13519 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);
1350913520
13521 const scalar_zero = switch (scalar_tag) {
13522 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
13523 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13524 else => unreachable,
13525 };
13510 if (resolved_type.zigTypeTag(mod) == .Vector) {13526 if (resolved_type.zigTypeTag(mod) == .Vector) {
13511 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);13527 const zero_val = try Value.Tag.repeated.create(sema.arena, scalar_zero);
13512 const zero = try sema.addConstant(resolved_type, zero_val);13528 const zero = try sema.addConstant(resolved_type, zero_val);
13513 const eql = try block.addCmpVector(remainder, zero, .eq);13529 const eql = try block.addCmpVector(remainder, zero, .eq);
13514 break :ok try block.addInst(.{13530 break :ok try block.addInst(.{
...@@ -13519,7 +13535,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13519,7 +13535,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13519 } },13535 } },
13520 });13536 });
13521 } else {13537 } else {
13522 const zero = try sema.addConstant(resolved_type, Value.zero);13538 const zero = try sema.addConstant(resolved_type, scalar_zero);
13523 const is_in_range = try block.addBinOp(.cmp_eq, remainder, zero);13539 const is_in_range = try block.addBinOp(.cmp_eq, remainder, zero);
13524 break :ok is_in_range;13540 break :ok is_in_range;
13525 }13541 }
...@@ -13592,9 +13608,14 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13592,9 +13608,14 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13592 if (maybe_lhs_val) |lhs_val| {13608 if (maybe_lhs_val) |lhs_val| {
13593 if (!lhs_val.isUndef()) {13609 if (!lhs_val.isUndef()) {
13594 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13610 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13611 const scalar_zero = switch (scalar_tag) {
13612 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
13613 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13614 else => unreachable,
13615 };
13595 const zero_val = if (is_vector) b: {13616 const zero_val = if (is_vector) b: {
13596 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);13617 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
13597 } else Value.zero;13618 } else scalar_zero;
13598 return sema.addConstant(resolved_type, zero_val);13619 return sema.addConstant(resolved_type, zero_val);
13599 }13620 }
13600 }13621 }
...@@ -13612,7 +13633,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13612,7 +13633,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13612 if (lhs_val.isUndef()) {13633 if (lhs_val.isUndef()) {
13613 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {13634 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
13614 if (maybe_rhs_val) |rhs_val| {13635 if (maybe_rhs_val) |rhs_val| {
13615 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {13636 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {
13616 return sema.addConstUndef(resolved_type);13637 return sema.addConstUndef(resolved_type);
13617 }13638 }
13618 }13639 }
...@@ -13708,9 +13729,14 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13708,9 +13729,14 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13708 if (maybe_lhs_val) |lhs_val| {13729 if (maybe_lhs_val) |lhs_val| {
13709 if (!lhs_val.isUndef()) {13730 if (!lhs_val.isUndef()) {
13710 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13731 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13732 const scalar_zero = switch (scalar_tag) {
13733 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
13734 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13735 else => unreachable,
13736 };
13711 const zero_val = if (is_vector) b: {13737 const zero_val = if (is_vector) b: {
13712 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);13738 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
13713 } else Value.zero;13739 } else scalar_zero;
13714 return sema.addConstant(resolved_type, zero_val);13740 return sema.addConstant(resolved_type, zero_val);
13715 }13741 }
13716 }13742 }
...@@ -13727,7 +13753,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13727,7 +13753,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13727 if (lhs_val.isUndef()) {13753 if (lhs_val.isUndef()) {
13728 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {13754 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
13729 if (maybe_rhs_val) |rhs_val| {13755 if (maybe_rhs_val) |rhs_val| {
13730 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {13756 if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) {
13731 return sema.addConstUndef(resolved_type);13757 return sema.addConstUndef(resolved_type);
13732 }13758 }
13733 }13759 }
...@@ -13862,8 +13888,9 @@ fn addDivByZeroSafety(...@@ -13862,8 +13888,9 @@ fn addDivByZeroSafety(
13862 if (maybe_rhs_val != null) return;13888 if (maybe_rhs_val != null) return;
1386313889
13864 const mod = sema.mod;13890 const mod = sema.mod;
13891 const scalar_zero = if (is_int) try mod.intValue(resolved_type.scalarType(mod), 0) else Value.float_zero; // TODO migrate to internpool
13865 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {13892 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {
13866 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);13893 const zero_val = try Value.Tag.repeated.create(sema.arena, scalar_zero);
13867 const zero = try sema.addConstant(resolved_type, zero_val);13894 const zero = try sema.addConstant(resolved_type, zero_val);
13868 const ok = try block.addCmpVector(casted_rhs, zero, .neq);13895 const ok = try block.addCmpVector(casted_rhs, zero, .neq);
13869 break :ok try block.addInst(.{13896 break :ok try block.addInst(.{
...@@ -13874,7 +13901,7 @@ fn addDivByZeroSafety(...@@ -13874,7 +13901,7 @@ fn addDivByZeroSafety(
13874 } },13901 } },
13875 });13902 });
13876 } else ok: {13903 } else ok: {
13877 const zero = try sema.addConstant(resolved_type, Value.zero);13904 const zero = try sema.addConstant(resolved_type, scalar_zero);
13878 break :ok try block.addBinOp(if (is_int) .cmp_neq else .cmp_neq_optimized, casted_rhs, zero);13905 break :ok try block.addBinOp(if (is_int) .cmp_neq else .cmp_neq_optimized, casted_rhs, zero);
13879 };13906 };
13880 try sema.addSafetyCheck(block, ok, .divide_by_zero);13907 try sema.addSafetyCheck(block, ok, .divide_by_zero);
...@@ -13946,9 +13973,14 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13946,9 +13973,14 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13946 return sema.failWithUseOfUndef(block, lhs_src);13973 return sema.failWithUseOfUndef(block, lhs_src);
13947 }13974 }
13948 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13975 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13976 const scalar_zero = switch (scalar_tag) {
13977 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
13978 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
13979 else => unreachable,
13980 };
13949 const zero_val = if (is_vector) b: {13981 const zero_val = if (is_vector) b: {
13950 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);13982 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
13951 } else Value.zero;13983 } else scalar_zero;
13952 return sema.addConstant(resolved_type, zero_val);13984 return sema.addConstant(resolved_type, zero_val);
13953 }13985 }
13954 } else if (lhs_scalar_ty.isSignedInt(mod)) {13986 } else if (lhs_scalar_ty.isSignedInt(mod)) {
...@@ -14325,6 +14357,7 @@ fn zirOverflowArithmetic(...@@ -14325,6 +14357,7 @@ fn zirOverflowArithmetic(
14325 wrapped: Value = Value.@"unreachable",14357 wrapped: Value = Value.@"unreachable",
14326 overflow_bit: Value,14358 overflow_bit: Value,
14327 } = result: {14359 } = result: {
14360 const zero = try mod.intValue(dest_ty.scalarType(mod), 0);
14328 switch (zir_tag) {14361 switch (zir_tag) {
14329 .add_with_overflow => {14362 .add_with_overflow => {
14330 // If either of the arguments is zero, `false` is returned and the other is stored14363 // If either of the arguments is zero, `false` is returned and the other is stored
...@@ -14332,12 +14365,12 @@ fn zirOverflowArithmetic(...@@ -14332,12 +14365,12 @@ fn zirOverflowArithmetic(
14332 // Otherwise, if either of the argument is undefined, undefined is returned.14365 // Otherwise, if either of the argument is undefined, undefined is returned.
14333 if (maybe_lhs_val) |lhs_val| {14366 if (maybe_lhs_val) |lhs_val| {
14334 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {14367 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14335 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs };14368 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };
14336 }14369 }
14337 }14370 }
14338 if (maybe_rhs_val) |rhs_val| {14371 if (maybe_rhs_val) |rhs_val| {
14339 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {14372 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14340 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };14373 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14341 }14374 }
14342 }14375 }
14343 if (maybe_lhs_val) |lhs_val| {14376 if (maybe_lhs_val) |lhs_val| {
...@@ -14358,7 +14391,7 @@ fn zirOverflowArithmetic(...@@ -14358,7 +14391,7 @@ fn zirOverflowArithmetic(
14358 if (rhs_val.isUndef()) {14391 if (rhs_val.isUndef()) {
14359 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14392 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
14360 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14393 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14361 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };14394 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14362 } else if (maybe_lhs_val) |lhs_val| {14395 } else if (maybe_lhs_val) |lhs_val| {
14363 if (lhs_val.isUndef()) {14396 if (lhs_val.isUndef()) {
14364 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14397 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
...@@ -14373,12 +14406,13 @@ fn zirOverflowArithmetic(...@@ -14373,12 +14406,13 @@ fn zirOverflowArithmetic(
14373 // If either of the arguments is zero, the result is zero and no overflow occured.14406 // If either of the arguments is zero, the result is zero and no overflow occured.
14374 // If either of the arguments is one, the result is the other and no overflow occured.14407 // If either of the arguments is one, the result is the other and no overflow occured.
14375 // Otherwise, if either of the arguments is undefined, both results are undefined.14408 // Otherwise, if either of the arguments is undefined, both results are undefined.
14409 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);
14376 if (maybe_lhs_val) |lhs_val| {14410 if (maybe_lhs_val) |lhs_val| {
14377 if (!lhs_val.isUndef()) {14411 if (!lhs_val.isUndef()) {
14378 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14412 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14379 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };14413 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14380 } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, Value.one), dest_ty)) {14414 } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) {
14381 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs };14415 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };
14382 }14416 }
14383 }14417 }
14384 }14418 }
...@@ -14386,9 +14420,9 @@ fn zirOverflowArithmetic(...@@ -14386,9 +14420,9 @@ fn zirOverflowArithmetic(
14386 if (maybe_rhs_val) |rhs_val| {14420 if (maybe_rhs_val) |rhs_val| {
14387 if (!rhs_val.isUndef()) {14421 if (!rhs_val.isUndef()) {
14388 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14422 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14389 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs };14423 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs };
14390 } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, Value.one), dest_ty)) {14424 } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) {
14391 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };14425 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14392 }14426 }
14393 }14427 }
14394 }14428 }
...@@ -14410,12 +14444,12 @@ fn zirOverflowArithmetic(...@@ -14410,12 +14444,12 @@ fn zirOverflowArithmetic(
14410 // Oterhwise if either of the arguments is undefined, both results are undefined.14444 // Oterhwise if either of the arguments is undefined, both results are undefined.
14411 if (maybe_lhs_val) |lhs_val| {14445 if (maybe_lhs_val) |lhs_val| {
14412 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {14446 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14413 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };14447 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14414 }14448 }
14415 }14449 }
14416 if (maybe_rhs_val) |rhs_val| {14450 if (maybe_rhs_val) |rhs_val| {
14417 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {14451 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14418 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };14452 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs };
14419 }14453 }
14420 }14454 }
14421 if (maybe_lhs_val) |lhs_val| {14455 if (maybe_lhs_val) |lhs_val| {
...@@ -14766,6 +14800,11 @@ fn analyzeArithmetic(...@@ -14766,6 +14800,11 @@ fn analyzeArithmetic(
14766 // If either of the operands are inf, and the other operand is zero,14800 // If either of the operands are inf, and the other operand is zero,
14767 // the result is nan.14801 // the result is nan.
14768 // If either of the operands are nan, the result is nan.14802 // If either of the operands are nan, the result is nan.
14803 const scalar_zero = switch (scalar_tag) {
14804 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
14805 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14806 else => unreachable,
14807 };
14769 if (maybe_lhs_val) |lhs_val| {14808 if (maybe_lhs_val) |lhs_val| {
14770 if (!lhs_val.isUndef()) {14809 if (!lhs_val.isUndef()) {
14771 if (lhs_val.isNan()) {14810 if (lhs_val.isNan()) {
...@@ -14783,11 +14822,11 @@ fn analyzeArithmetic(...@@ -14783,11 +14822,11 @@ fn analyzeArithmetic(
14783 break :lz;14822 break :lz;
14784 }14823 }
14785 const zero_val = if (is_vector) b: {14824 const zero_val = if (is_vector) b: {
14786 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);14825 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
14787 } else Value.zero;14826 } else scalar_zero;
14788 return sema.addConstant(resolved_type, zero_val);14827 return sema.addConstant(resolved_type, zero_val);
14789 }14828 }
14790 if (try sema.compareAll(lhs_val, .eq, Value.one, resolved_type)) {14829 if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14791 return casted_rhs;14830 return casted_rhs;
14792 }14831 }
14793 }14832 }
...@@ -14813,11 +14852,11 @@ fn analyzeArithmetic(...@@ -14813,11 +14852,11 @@ fn analyzeArithmetic(
14813 break :rz;14852 break :rz;
14814 }14853 }
14815 const zero_val = if (is_vector) b: {14854 const zero_val = if (is_vector) b: {
14816 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);14855 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
14817 } else Value.zero;14856 } else scalar_zero;
14818 return sema.addConstant(resolved_type, zero_val);14857 return sema.addConstant(resolved_type, zero_val);
14819 }14858 }
14820 if (try sema.compareAll(rhs_val, .eq, Value.one, resolved_type)) {14859 if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14821 return casted_lhs;14860 return casted_lhs;
14822 }14861 }
14823 if (maybe_lhs_val) |lhs_val| {14862 if (maybe_lhs_val) |lhs_val| {
...@@ -14849,15 +14888,20 @@ fn analyzeArithmetic(...@@ -14849,15 +14888,20 @@ fn analyzeArithmetic(
14849 // If either of the operands are zero, result is zero.14888 // If either of the operands are zero, result is zero.
14850 // If either of the operands are one, result is the other operand.14889 // If either of the operands are one, result is the other operand.
14851 // If either of the operands are undefined, result is undefined.14890 // If either of the operands are undefined, result is undefined.
14891 const scalar_zero = switch (scalar_tag) {
14892 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
14893 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14894 else => unreachable,
14895 };
14852 if (maybe_lhs_val) |lhs_val| {14896 if (maybe_lhs_val) |lhs_val| {
14853 if (!lhs_val.isUndef()) {14897 if (!lhs_val.isUndef()) {
14854 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14898 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14855 const zero_val = if (is_vector) b: {14899 const zero_val = if (is_vector) b: {
14856 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);14900 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
14857 } else Value.zero;14901 } else scalar_zero;
14858 return sema.addConstant(resolved_type, zero_val);14902 return sema.addConstant(resolved_type, zero_val);
14859 }14903 }
14860 if (try sema.compareAll(lhs_val, .eq, Value.one, resolved_type)) {14904 if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14861 return casted_rhs;14905 return casted_rhs;
14862 }14906 }
14863 }14907 }
...@@ -14869,11 +14913,11 @@ fn analyzeArithmetic(...@@ -14869,11 +14913,11 @@ fn analyzeArithmetic(
14869 }14913 }
14870 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14914 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14871 const zero_val = if (is_vector) b: {14915 const zero_val = if (is_vector) b: {
14872 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);14916 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
14873 } else Value.zero;14917 } else scalar_zero;
14874 return sema.addConstant(resolved_type, zero_val);14918 return sema.addConstant(resolved_type, zero_val);
14875 }14919 }
14876 if (try sema.compareAll(rhs_val, .eq, Value.one, resolved_type)) {14920 if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14877 return casted_lhs;14921 return casted_lhs;
14878 }14922 }
14879 if (maybe_lhs_val) |lhs_val| {14923 if (maybe_lhs_val) |lhs_val| {
...@@ -14892,15 +14936,20 @@ fn analyzeArithmetic(...@@ -14892,15 +14936,20 @@ fn analyzeArithmetic(
14892 // If either of the operands are zero, result is zero.14936 // If either of the operands are zero, result is zero.
14893 // If either of the operands are one, result is the other operand.14937 // If either of the operands are one, result is the other operand.
14894 // If either of the operands are undefined, result is undefined.14938 // If either of the operands are undefined, result is undefined.
14939 const scalar_zero = switch (scalar_tag) {
14940 .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool
14941 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14942 else => unreachable,
14943 };
14895 if (maybe_lhs_val) |lhs_val| {14944 if (maybe_lhs_val) |lhs_val| {
14896 if (!lhs_val.isUndef()) {14945 if (!lhs_val.isUndef()) {
14897 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14946 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14898 const zero_val = if (is_vector) b: {14947 const zero_val = if (is_vector) b: {
14899 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);14948 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
14900 } else Value.zero;14949 } else scalar_zero;
14901 return sema.addConstant(resolved_type, zero_val);14950 return sema.addConstant(resolved_type, zero_val);
14902 }14951 }
14903 if (try sema.compareAll(lhs_val, .eq, Value.one, resolved_type)) {14952 if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14904 return casted_rhs;14953 return casted_rhs;
14905 }14954 }
14906 }14955 }
...@@ -14911,11 +14960,11 @@ fn analyzeArithmetic(...@@ -14911,11 +14960,11 @@ fn analyzeArithmetic(
14911 }14960 }
14912 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14961 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14913 const zero_val = if (is_vector) b: {14962 const zero_val = if (is_vector) b: {
14914 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);14963 break :b try Value.Tag.repeated.create(sema.arena, scalar_zero);
14915 } else Value.zero;14964 } else scalar_zero;
14916 return sema.addConstant(resolved_type, zero_val);14965 return sema.addConstant(resolved_type, zero_val);
14917 }14966 }
14918 if (try sema.compareAll(rhs_val, .eq, Value.one, resolved_type)) {14967 if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14919 return casted_lhs;14968 return casted_lhs;
14920 }14969 }
14921 if (maybe_lhs_val) |lhs_val| {14970 if (maybe_lhs_val) |lhs_val| {
...@@ -14968,7 +15017,7 @@ fn analyzeArithmetic(...@@ -14968,7 +15017,7 @@ fn analyzeArithmetic(
14968 })15017 })
14969 else15018 else
14970 ov_bit;15019 ov_bit;
14971 const zero_ov = try sema.addConstant(Type.u1, Value.zero);15020 const zero_ov = try sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0));
14972 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);15021 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
1497315022
14974 try sema.addSafetyCheck(block, no_ov, .integer_overflow);15023 try sema.addSafetyCheck(block, no_ov, .integer_overflow);
...@@ -15785,7 +15834,7 @@ fn zirBuiltinSrc(...@@ -15785,7 +15834,7 @@ fn zirBuiltinSrc(
15785 const name = std.mem.span(fn_owner_decl.name);15834 const name = std.mem.span(fn_owner_decl.name);
15786 const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]);15835 const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]);
15787 const new_decl = try anon_decl.finish(15836 const new_decl = try anon_decl.finish(
15788 try Type.array(anon_decl.arena(), bytes.len - 1, Value.zero, Type.u8, mod),15837 try Type.array(anon_decl.arena(), bytes.len - 1, try mod.intValue(Type.u8, 0), Type.u8, mod),
15789 try Value.Tag.bytes.create(anon_decl.arena(), bytes),15838 try Value.Tag.bytes.create(anon_decl.arena(), bytes),
15790 0, // default alignment15839 0, // default alignment
15791 );15840 );
...@@ -15798,7 +15847,7 @@ fn zirBuiltinSrc(...@@ -15798,7 +15847,7 @@ fn zirBuiltinSrc(
15798 // The compiler must not call realpath anywhere.15847 // The compiler must not call realpath anywhere.
15799 const name = try fn_owner_decl.getFileScope().fullPathZ(anon_decl.arena());15848 const name = try fn_owner_decl.getFileScope().fullPathZ(anon_decl.arena());
15800 const new_decl = try anon_decl.finish(15849 const new_decl = try anon_decl.finish(
15801 try Type.array(anon_decl.arena(), name.len, Value.zero, Type.u8, mod),15850 try Type.array(anon_decl.arena(), name.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
15802 try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]),15851 try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]),
15803 0, // default alignment15852 0, // default alignment
15804 );15853 );
...@@ -16148,7 +16197,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16148,7 +16197,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16148 defer anon_decl.deinit();16197 defer anon_decl.deinit();
16149 const bytes = try anon_decl.arena().dupeZ(u8, name);16198 const bytes = try anon_decl.arena().dupeZ(u8, name);
16150 const new_decl = try anon_decl.finish(16199 const new_decl = try anon_decl.finish(
16151 try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod),16200 try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
16152 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),16201 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
16153 0, // default alignment16202 0, // default alignment
16154 );16203 );
...@@ -16256,7 +16305,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16256,7 +16305,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16256 defer anon_decl.deinit();16305 defer anon_decl.deinit();
16257 const bytes = try anon_decl.arena().dupeZ(u8, name);16306 const bytes = try anon_decl.arena().dupeZ(u8, name);
16258 const new_decl = try anon_decl.finish(16307 const new_decl = try anon_decl.finish(
16259 try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod),16308 try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
16260 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),16309 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
16261 0, // default alignment16310 0, // default alignment
16262 );16311 );
...@@ -16344,7 +16393,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16344,7 +16393,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16344 defer anon_decl.deinit();16393 defer anon_decl.deinit();
16345 const bytes = try anon_decl.arena().dupeZ(u8, name);16394 const bytes = try anon_decl.arena().dupeZ(u8, name);
16346 const new_decl = try anon_decl.finish(16395 const new_decl = try anon_decl.finish(
16347 try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod),16396 try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
16348 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),16397 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
16349 0, // default alignment16398 0, // default alignment
16350 );16399 );
...@@ -16454,7 +16503,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16454,7 +16503,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16454 else16503 else
16455 try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i});16504 try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i});
16456 const new_decl = try anon_decl.finish(16505 const new_decl = try anon_decl.finish(
16457 try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod),16506 try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
16458 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),16507 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
16459 0, // default alignment16508 0, // default alignment
16460 );16509 );
...@@ -16496,7 +16545,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16496,7 +16545,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16496 defer anon_decl.deinit();16545 defer anon_decl.deinit();
16497 const bytes = try anon_decl.arena().dupeZ(u8, name);16546 const bytes = try anon_decl.arena().dupeZ(u8, name);
16498 const new_decl = try anon_decl.finish(16547 const new_decl = try anon_decl.finish(
16499 try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod),16548 try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
16500 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),16549 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
16501 0, // default alignment16550 0, // default alignment
16502 );16551 );
...@@ -16692,7 +16741,7 @@ fn typeInfoNamespaceDecls(...@@ -16692,7 +16741,7 @@ fn typeInfoNamespaceDecls(
16692 defer anon_decl.deinit();16741 defer anon_decl.deinit();
16693 const bytes = try anon_decl.arena().dupeZ(u8, mem.sliceTo(decl.name, 0));16742 const bytes = try anon_decl.arena().dupeZ(u8, mem.sliceTo(decl.name, 0));
16694 const new_decl = try anon_decl.finish(16743 const new_decl = try anon_decl.finish(
16695 try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod),16744 try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
16696 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),16745 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
16697 0, // default alignment16746 0, // default alignment
16698 );16747 );
...@@ -17884,7 +17933,7 @@ fn zirStructInit(...@@ -17884,7 +17933,7 @@ fn zirStructInit(
17884 }17933 }
17885 found_fields[field_index] = item.data.field_type;17934 found_fields[field_index] = item.data.field_type;
17886 field_inits[field_index] = try sema.resolveInst(item.data.init);17935 field_inits[field_index] = try sema.resolveInst(item.data.init);
17887 if (!is_packed) if (resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| {17936 if (!is_packed) if (try resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| {
17888 const init_val = (try sema.resolveMaybeUndefVal(field_inits[field_index])) orelse {17937 const init_val = (try sema.resolveMaybeUndefVal(field_inits[field_index])) orelse {
17889 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");17938 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");
17890 };17939 };
...@@ -18544,8 +18593,8 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -18544,8 +18593,8 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
18544 const operand = try sema.resolveInst(inst_data.operand);18593 const operand = try sema.resolveInst(inst_data.operand);
18545 if (try sema.resolveMaybeUndefVal(operand)) |val| {18594 if (try sema.resolveMaybeUndefVal(operand)) |val| {
18546 if (val.isUndef()) return sema.addConstUndef(Type.u1);18595 if (val.isUndef()) return sema.addConstUndef(Type.u1);
18547 if (val.toBool(mod)) return sema.addConstant(Type.u1, Value.one);18596 if (val.toBool(mod)) return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 1));
18548 return sema.addConstant(Type.u1, Value.zero);18597 return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0));
18549 }18598 }
18550 return block.addUnOp(.bool_to_int, operand);18599 return block.addUnOp(.bool_to_int, operand);
18551}18600}
...@@ -19761,7 +19810,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19761,7 +19810,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19761 const bytes = try ty.nameAllocArena(anon_decl.arena(), mod);19810 const bytes = try ty.nameAllocArena(anon_decl.arena(), mod);
1976219811
19763 const new_decl = try anon_decl.finish(19812 const new_decl = try anon_decl.finish(
19764 try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod),19813 try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
19765 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),19814 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
19766 0, // default alignment19815 0, // default alignment
19767 );19816 );
...@@ -19804,17 +19853,17 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -19804,17 +19853,17 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
19804 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);19853 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
19805 if (dest_ty.intInfo(mod).bits == 0) {19854 if (dest_ty.intInfo(mod).bits == 0) {
19806 if (block.wantSafety()) {19855 if (block.wantSafety()) {
19807 const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(operand_ty, Value.zero));19856 const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(operand_ty, try mod.intValue(operand_ty, 0)));
19808 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);19857 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);
19809 }19858 }
19810 return sema.addConstant(dest_ty, Value.zero);19859 return sema.addConstant(dest_ty, try mod.intValue(dest_ty, 0));
19811 }19860 }
19812 const result = try block.addTyOp(if (block.float_mode == .Optimized) .float_to_int_optimized else .float_to_int, dest_ty, operand);19861 const result = try block.addTyOp(if (block.float_mode == .Optimized) .float_to_int_optimized else .float_to_int, dest_ty, operand);
19813 if (block.wantSafety()) {19862 if (block.wantSafety()) {
19814 const back = try block.addTyOp(.int_to_float, operand_ty, result);19863 const back = try block.addTyOp(.int_to_float, operand_ty, result);
19815 const diff = try block.addBinOp(.sub, operand, back);19864 const diff = try block.addBinOp(.sub, operand, back);
19816 const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(operand_ty, Value.one));19865 const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(operand_ty, try mod.intValue(operand_ty, 1)));
19817 const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(operand_ty, Value.negative_one));19866 const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(operand_ty, try mod.intValue(operand_ty, -1)));
19818 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);19867 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);
19819 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);19868 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);
19820 }19869 }
...@@ -21398,7 +21447,7 @@ fn analyzeShuffle(...@@ -21398,7 +21447,7 @@ fn analyzeShuffle(
21398 expand_mask_values[i] = try mod.intValue(Type.comptime_int, i);21447 expand_mask_values[i] = try mod.intValue(Type.comptime_int, i);
21399 }21448 }
21400 while (i < max_len) : (i += 1) {21449 while (i < max_len) : (i += 1) {
21401 expand_mask_values[i] = Value.negative_one;21450 expand_mask_values[i] = try mod.intValue(Type.comptime_int, -1);
21402 }21451 }
21403 const expand_mask = try Value.Tag.aggregate.create(sema.arena, expand_mask_values);21452 const expand_mask = try Value.Tag.aggregate.create(sema.arena, expand_mask_values);
2140421453
...@@ -24504,7 +24553,7 @@ fn finishFieldCallBind(...@@ -24504,7 +24553,7 @@ fn finishFieldCallBind(
2450424553
24505 const container_ty = ptr_ty.childType(mod);24554 const container_ty = ptr_ty.childType(mod);
24506 if (container_ty.zigTypeTag(mod) == .Struct) {24555 if (container_ty.zigTypeTag(mod) == .Struct) {
24507 if (container_ty.structFieldValueComptime(mod, field_index)) |default_val| {24556 if (try container_ty.structFieldValueComptime(mod, field_index)) |default_val| {
24508 return .{ .direct = try sema.addConstant(field_ty, default_val) };24557 return .{ .direct = try sema.addConstant(field_ty, default_val) };
24509 }24558 }
24510 }24559 }
...@@ -24815,7 +24864,7 @@ fn tupleFieldValByIndex(...@@ -24815,7 +24864,7 @@ fn tupleFieldValByIndex(
24815 const mod = sema.mod;24864 const mod = sema.mod;
24816 const field_ty = tuple_ty.structFieldType(field_index);24865 const field_ty = tuple_ty.structFieldType(field_index);
2481724866
24818 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {24867 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {
24819 return sema.addConstant(field_ty, default_value);24868 return sema.addConstant(field_ty, default_value);
24820 }24869 }
2482124870
...@@ -24828,7 +24877,7 @@ fn tupleFieldValByIndex(...@@ -24828,7 +24877,7 @@ fn tupleFieldValByIndex(
24828 return sema.addConstant(field_ty, field_values[field_index]);24877 return sema.addConstant(field_ty, field_values[field_index]);
24829 }24878 }
2483024879
24831 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {24880 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
24832 return sema.addConstant(field_ty, default_val);24881 return sema.addConstant(field_ty, default_val);
24833 }24882 }
2483424883
...@@ -25205,7 +25254,7 @@ fn tupleFieldPtr(...@@ -25205,7 +25254,7 @@ fn tupleFieldPtr(
25205 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod),25254 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod),
25206 });25255 });
2520725256
25208 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {25257 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
25209 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{25258 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{
25210 .field_ty = field_ty,25259 .field_ty = field_ty,
25211 .field_val = default_val,25260 .field_val = default_val,
...@@ -25256,13 +25305,13 @@ fn tupleField(...@@ -25256,13 +25305,13 @@ fn tupleField(
2525625305
25257 const field_ty = tuple_ty.structFieldType(field_index);25306 const field_ty = tuple_ty.structFieldType(field_index);
2525825307
25259 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {25308 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {
25260 return sema.addConstant(field_ty, default_value); // comptime field25309 return sema.addConstant(field_ty, default_value); // comptime field
25261 }25310 }
2526225311
25263 if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| {25312 if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| {
25264 if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);25313 if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
25265 return sema.addConstant(field_ty, tuple_val.fieldValue(tuple_ty, mod, field_index));25314 return sema.addConstant(field_ty, try tuple_val.fieldValue(tuple_ty, mod, field_index));
25266 }25315 }
2526725316
25268 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);25317 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
...@@ -25812,7 +25861,7 @@ fn coerceExtra(...@@ -25812,7 +25861,7 @@ fn coerceExtra(
25812 if (inst_info.size == .Slice) {25861 if (inst_info.size == .Slice) {
25813 assert(dest_info.sentinel == null);25862 assert(dest_info.sentinel == null);
25814 if (inst_info.sentinel == null or25863 if (inst_info.sentinel == null or
25815 !inst_info.sentinel.?.eql(Value.zero, dest_info.pointee_type, sema.mod))25864 !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, sema.mod))
25816 break :p;25865 break :p;
2581725866
25818 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);25867 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -25879,7 +25928,7 @@ fn coerceExtra(...@@ -25879,7 +25928,7 @@ fn coerceExtra(
25879 try mod.intValue(Type.usize, dest_info.@"align")25928 try mod.intValue(Type.usize, dest_info.@"align")
25880 else25929 else
25881 try dest_info.pointee_type.lazyAbiAlignment(mod, sema.arena),25930 try dest_info.pointee_type.lazyAbiAlignment(mod, sema.arena),
25882 .len = Value.zero,25931 .len = try mod.intValue(Type.usize, 0),
25883 });25932 });
25884 return sema.addConstant(dest_ty, slice_val);25933 return sema.addConstant(dest_ty, slice_val);
25885 }25934 }
...@@ -28234,7 +28283,7 @@ fn beginComptimePtrLoad(...@@ -28234,7 +28283,7 @@ fn beginComptimePtrLoad(
28234 const field_ty = field_ptr.container_ty.structFieldType(field_index);28283 const field_ty = field_ptr.container_ty.structFieldType(field_index);
28235 deref.pointee = TypedValue{28284 deref.pointee = TypedValue{
28236 .ty = field_ty,28285 .ty = field_ty,
28237 .val = tv.val.fieldValue(tv.ty, mod, field_index),28286 .val = try tv.val.fieldValue(tv.ty, mod, field_index),
28238 };28287 };
28239 }28288 }
28240 break :blk deref;28289 break :blk deref;
...@@ -32532,9 +32581,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32532,9 +32581,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32532 break :blk try val.copy(decl_arena_allocator);32581 break :blk try val.copy(decl_arena_allocator);
32533 } else blk: {32582 } else blk: {
32534 const val = if (last_tag_val) |val|32583 const val = if (last_tag_val) |val|
32535 try sema.intAdd(val, Value.one, int_tag_ty)32584 try sema.intAdd(val, try mod.intValue(int_tag_ty, 1), int_tag_ty)
32536 else32585 else
32537 Value.zero;32586 try mod.intValue(int_tag_ty, 0);
32538 last_tag_val = val;32587 last_tag_val = val;
3253932588
32540 break :blk try val.copy(decl_arena_allocator);32589 break :blk try val.copy(decl_arena_allocator);
...@@ -32903,7 +32952,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -32903,7 +32952,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
32903 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {32952 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
32904 .int_type => |int_type| {32953 .int_type => |int_type| {
32905 if (int_type.bits == 0) {32954 if (int_type.bits == 0) {
32906 return Value.zero;32955 return try mod.intValue(ty, 0);
32907 } else {32956 } else {
32908 return null;32957 return null;
32909 }32958 }
...@@ -33049,7 +33098,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33049,7 +33098,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33049 }33098 }
33050 if (enum_obj.fields.count() == 1) {33099 if (enum_obj.fields.count() == 1) {
33051 if (enum_obj.values.count() == 0) {33100 if (enum_obj.values.count() == 0) {
33052 return Value.zero; // auto-numbered33101 return try mod.intValue(ty, 0); // auto-numbered
33053 } else {33102 } else {
33054 return enum_obj.values.keys()[0];33103 return enum_obj.values.keys()[0];
33055 }33104 }
...@@ -33066,7 +33115,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33066,7 +33115,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33066 switch (enum_obj.fields.count()) {33115 switch (enum_obj.fields.count()) {
33067 0 => return Value.@"unreachable",33116 0 => return Value.@"unreachable",
33068 1 => if (enum_obj.values.count() == 0) {33117 1 => if (enum_obj.values.count() == 0) {
33069 return Value.zero; // auto-numbered33118 return try mod.intValue(ty, 0); // auto-numbered
33070 } else {33119 } else {
33071 return enum_obj.values.keys()[0];33120 return enum_obj.values.keys()[0];
33072 },33121 },
...@@ -33078,14 +33127,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33078,14 +33127,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33078 const enum_simple = resolved_ty.castTag(.enum_simple).?.data;33127 const enum_simple = resolved_ty.castTag(.enum_simple).?.data;
33079 switch (enum_simple.fields.count()) {33128 switch (enum_simple.fields.count()) {
33080 0 => return Value.@"unreachable",33129 0 => return Value.@"unreachable",
33081 1 => return Value.zero,33130 1 => return try mod.intValue(ty, 0),
33082 else => return null,33131 else => return null,
33083 }33132 }
33084 },33133 },
33085 .enum_nonexhaustive => {33134 .enum_nonexhaustive => {
33086 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;33135 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;
33087 if (tag_ty.zigTypeTag(mod) != .ComptimeInt and !(try sema.typeHasRuntimeBits(tag_ty))) {33136 if (tag_ty.zigTypeTag(mod) != .ComptimeInt and !(try sema.typeHasRuntimeBits(tag_ty))) {
33088 return Value.zero;33137 return try mod.intValue(ty, 0);
33089 } else {33138 } else {
33090 return null;33139 return null;
33091 }33140 }
src/TypedValue.zig+8-5
...@@ -61,7 +61,10 @@ pub fn format(...@@ -61,7 +61,10 @@ pub fn format(
61) !void {61) !void {
62 _ = options;62 _ = options;
63 comptime std.debug.assert(fmt.len == 0);63 comptime std.debug.assert(fmt.len == 0);
64 return ctx.tv.print(writer, 3, ctx.mod);64 return ctx.tv.print(writer, 3, ctx.mod) catch |err| switch (err) {
65 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
66 else => |e| return e,
67 };
65}68}
6669
67/// Prints the Value according to the Type, not according to the Value Tag.70/// Prints the Value according to the Type, not according to the Value Tag.
...@@ -70,7 +73,7 @@ pub fn print(...@@ -70,7 +73,7 @@ pub fn print(
70 writer: anytype,73 writer: anytype,
71 level: u8,74 level: u8,
72 mod: *Module,75 mod: *Module,
73) @TypeOf(writer).Error!void {76) (@TypeOf(writer).Error || Allocator.Error)!void {
74 var val = tv.val;77 var val = tv.val;
75 var ty = tv.ty;78 var ty = tv.ty;
76 if (val.isVariable(mod))79 if (val.isVariable(mod))
...@@ -95,7 +98,7 @@ pub fn print(...@@ -95,7 +98,7 @@ pub fn print(
95 }98 }
96 try print(.{99 try print(.{
97 .ty = ty.structFieldType(i),100 .ty = ty.structFieldType(i),
98 .val = val.fieldValue(ty, mod, i),101 .val = try val.fieldValue(ty, mod, i),
99 }, writer, level - 1, mod);102 }, writer, level - 1, mod);
100 }103 }
101 if (ty.structFieldCount() > max_aggregate_items) {104 if (ty.structFieldCount() > max_aggregate_items) {
...@@ -112,7 +115,7 @@ pub fn print(...@@ -112,7 +115,7 @@ pub fn print(
112115
113 var i: u32 = 0;116 var i: u32 = 0;
114 while (i < max_len) : (i += 1) {117 while (i < max_len) : (i += 1) {
115 const elem = val.fieldValue(ty, mod, i);118 const elem = try val.fieldValue(ty, mod, i);
116 if (elem.isUndef()) break :str;119 if (elem.isUndef()) break :str;
117 buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str;120 buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str;
118 }121 }
...@@ -129,7 +132,7 @@ pub fn print(...@@ -129,7 +132,7 @@ pub fn print(
129 if (i != 0) try writer.writeAll(", ");132 if (i != 0) try writer.writeAll(", ");
130 try print(.{133 try print(.{
131 .ty = elem_ty,134 .ty = elem_ty,
132 .val = val.fieldValue(ty, mod, i),135 .val = try val.fieldValue(ty, mod, i),
133 }, writer, level - 1, mod);136 }, writer, level - 1, mod);
134 }137 }
135 if (len > max_aggregate_items) {138 if (len > max_aggregate_items) {
src/arch/aarch64/CodeGen.zig+2-2
...@@ -4311,7 +4311,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4311,7 +4311,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43114311
4312 // Due to incremental compilation, how function calls are generated depends4312 // Due to incremental compilation, how function calls are generated depends
4313 // on linking.4313 // on linking.
4314 if (self.air.value(callee, mod)) |func_value| {4314 if (try self.air.value(callee, mod)) |func_value| {
4315 if (func_value.castTag(.function)) |func_payload| {4315 if (func_value.castTag(.function)) |func_payload| {
4316 const func = func_payload.data;4316 const func = func_payload.data;
43174317
...@@ -6154,7 +6154,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {...@@ -6154,7 +6154,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
61546154
6155 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{6155 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{
6156 .ty = inst_ty,6156 .ty = inst_ty,
6157 .val = self.air.value(inst, mod).?,6157 .val = (try self.air.value(inst, mod)).?,
6158 });6158 });
61596159
6160 switch (self.air.instructions.items(.tag)[inst_index]) {6160 switch (self.air.instructions.items(.tag)[inst_index]) {
src/arch/arm/CodeGen.zig+2-2
...@@ -4291,7 +4291,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4291,7 +4291,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42914291
4292 // Due to incremental compilation, how function calls are generated depends4292 // Due to incremental compilation, how function calls are generated depends
4293 // on linking.4293 // on linking.
4294 if (self.air.value(callee, mod)) |func_value| {4294 if (try self.air.value(callee, mod)) |func_value| {
4295 if (func_value.castTag(.function)) |func_payload| {4295 if (func_value.castTag(.function)) |func_payload| {
4296 const func = func_payload.data;4296 const func = func_payload.data;
42974297
...@@ -6101,7 +6101,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {...@@ -6101,7 +6101,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
61016101
6102 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{6102 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{
6103 .ty = inst_ty,6103 .ty = inst_ty,
6104 .val = self.air.value(inst, mod).?,6104 .val = (try self.air.value(inst, mod)).?,
6105 });6105 });
61066106
6107 switch (self.air.instructions.items(.tag)[inst_index]) {6107 switch (self.air.instructions.items(.tag)[inst_index]) {
src/arch/riscv64/CodeGen.zig+2-2
...@@ -1743,7 +1743,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1743,7 +1743,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1743 }1743 }
1744 }1744 }
17451745
1746 if (self.air.value(callee, mod)) |func_value| {1746 if (try self.air.value(callee, mod)) |func_value| {
1747 if (func_value.castTag(.function)) |func_payload| {1747 if (func_value.castTag(.function)) |func_payload| {
1748 const func = func_payload.data;1748 const func = func_payload.data;
1749 const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);1749 const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
...@@ -2551,7 +2551,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {...@@ -2551,7 +2551,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
25512551
2552 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{2552 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{
2553 .ty = inst_ty,2553 .ty = inst_ty,
2554 .val = self.air.value(inst, mod).?,2554 .val = (try self.air.value(inst, mod)).?,
2555 });2555 });
25562556
2557 switch (self.air.instructions.items(.tag)[inst_index]) {2557 switch (self.air.instructions.items(.tag)[inst_index]) {
src/arch/sparc64/CodeGen.zig+2-2
...@@ -1343,7 +1343,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1343,7 +1343,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13431343
1344 // Due to incremental compilation, how function calls are generated depends1344 // Due to incremental compilation, how function calls are generated depends
1345 // on linking.1345 // on linking.
1346 if (self.air.value(callee, mod)) |func_value| {1346 if (try self.air.value(callee, mod)) |func_value| {
1347 if (self.bin_file.tag == link.File.Elf.base_tag) {1347 if (self.bin_file.tag == link.File.Elf.base_tag) {
1348 if (func_value.castTag(.function)) |func_payload| {1348 if (func_value.castTag(.function)) |func_payload| {
1349 const func = func_payload.data;1349 const func = func_payload.data;
...@@ -4575,7 +4575,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -4575,7 +4575,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
45754575
4576 return self.genTypedValue(.{4576 return self.genTypedValue(.{
4577 .ty = ty,4577 .ty = ty,
4578 .val = self.air.value(ref, mod).?,4578 .val = (try self.air.value(ref, mod)).?,
4579 });4579 });
4580}4580}
45814581
src/arch/wasm/CodeGen.zig+5-5
...@@ -789,7 +789,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {...@@ -789,7 +789,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
789 assert(!gop.found_existing);789 assert(!gop.found_existing);
790790
791 const mod = func.bin_file.base.options.module.?;791 const mod = func.bin_file.base.options.module.?;
792 const val = func.air.value(ref, mod).?;792 const val = (try func.air.value(ref, mod)).?;
793 const ty = func.typeOf(ref);793 const ty = func.typeOf(ref);
794 if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) {794 if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) {
795 gop.value_ptr.* = WValue{ .none = {} };795 gop.value_ptr.* = WValue{ .none = {} };
...@@ -2195,7 +2195,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2195,7 +2195,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2195 const first_param_sret = firstParamSRet(fn_info.cc, fn_info.return_type, mod);2195 const first_param_sret = firstParamSRet(fn_info.cc, fn_info.return_type, mod);
21962196
2197 const callee: ?Decl.Index = blk: {2197 const callee: ?Decl.Index = blk: {
2198 const func_val = func.air.value(pl_op.operand, mod) orelse break :blk null;2198 const func_val = (try func.air.value(pl_op.operand, mod)) orelse break :blk null;
21992199
2200 if (func_val.castTag(.function)) |function| {2200 if (func_val.castTag(.function)) |function| {
2201 _ = try func.bin_file.getOrCreateAtomForDecl(function.data.owner_decl);2201 _ = try func.bin_file.getOrCreateAtomForDecl(function.data.owner_decl);
...@@ -3138,7 +3138,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3138,7 +3138,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3138 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3138 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3139 // We use the error type directly as the type.3139 // We use the error type directly as the type.
3140 const is_pl = val.errorUnionIsPayload();3140 const is_pl = val.errorUnionIsPayload();
3141 const err_val = if (!is_pl) val else Value.zero;3141 const err_val = if (!is_pl) val else try mod.intValue(error_type, 0);
3142 return func.lowerConstant(err_val, error_type);3142 return func.lowerConstant(err_val, error_type);
3143 }3143 }
3144 return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});3144 return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});
...@@ -3792,7 +3792,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3792,7 +3792,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3792 errdefer func.gpa.free(values);3792 errdefer func.gpa.free(values);
37933793
3794 for (items, 0..) |ref, i| {3794 for (items, 0..) |ref, i| {
3795 const item_val = func.air.value(ref, mod).?;3795 const item_val = (try func.air.value(ref, mod)).?;
3796 const int_val = func.valueAsI32(item_val, target_ty);3796 const int_val = func.valueAsI32(item_val, target_ty);
3797 if (lowest_maybe == null or int_val < lowest_maybe.?) {3797 if (lowest_maybe == null or int_val < lowest_maybe.?) {
3798 lowest_maybe = int_val;3798 lowest_maybe = int_val;
...@@ -5048,7 +5048,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5048,7 +5048,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5048 const result = try func.allocStack(result_ty);5048 const result = try func.allocStack(result_ty);
5049 const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset5049 const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset
5050 for (elements, 0..) |elem, elem_index| {5050 for (elements, 0..) |elem, elem_index| {
5051 if (result_ty.structFieldValueComptime(mod, elem_index) != null) continue;5051 if ((try result_ty.structFieldValueComptime(mod, elem_index)) != null) continue;
50525052
5053 const elem_ty = result_ty.structFieldType(elem_index);5053 const elem_ty = result_ty.structFieldType(elem_index);
5054 const elem_size = @intCast(u32, elem_ty.abiSize(mod));5054 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
src/arch/x86_64/CodeGen.zig+6-6
...@@ -2768,7 +2768,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2768,7 +2768,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
27682768
2769 const full_ty = try mod.vectorType(.{2769 const full_ty = try mod.vectorType(.{
2770 .len = @intCast(u32, @divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)),2770 .len = @intCast(u32, @divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)),
2771 .child = src_ty.childType(mod).ip_index,2771 .child = elem_ty.ip_index,
2772 });2772 });
2773 const full_abi_size = @intCast(u32, full_ty.abiSize(mod));2773 const full_abi_size = @intCast(u32, full_ty.abiSize(mod));
27742774
...@@ -8107,7 +8107,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8107,7 +8107,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81078107
8108 // Due to incremental compilation, how function calls are generated depends8108 // Due to incremental compilation, how function calls are generated depends
8109 // on linking.8109 // on linking.
8110 if (self.air.value(callee, mod)) |func_value| {8110 if (try self.air.value(callee, mod)) |func_value| {
8111 if (if (func_value.castTag(.function)) |func_payload|8111 if (if (func_value.castTag(.function)) |func_payload|
8112 func_payload.data.owner_decl8112 func_payload.data.owner_decl
8113 else if (func_value.castTag(.decl_ref)) |decl_ref_payload|8113 else if (func_value.castTag(.decl_ref)) |decl_ref_payload|
...@@ -11265,7 +11265,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11265,7 +11265,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11265 .{ .immediate = result_ty.abiSize(mod) },11265 .{ .immediate = result_ty.abiSize(mod) },
11266 );11266 );
11267 for (elements, 0..) |elem, elem_i| {11267 for (elements, 0..) |elem, elem_i| {
11268 if (result_ty.structFieldValueComptime(mod, elem_i) != null) continue;11268 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;
1126911269
11270 const elem_ty = result_ty.structFieldType(elem_i);11270 const elem_ty = result_ty.structFieldType(elem_i);
11271 const elem_bit_size = @intCast(u32, elem_ty.bitSize(mod));11271 const elem_bit_size = @intCast(u32, elem_ty.bitSize(mod));
...@@ -11337,7 +11337,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11337,7 +11337,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11337 }11337 }
11338 }11338 }
11339 } else for (elements, 0..) |elem, elem_i| {11339 } else for (elements, 0..) |elem, elem_i| {
11340 if (result_ty.structFieldValueComptime(mod, elem_i) != null) continue;11340 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;
1134111341
11342 const elem_ty = result_ty.structFieldType(elem_i);11342 const elem_ty = result_ty.structFieldType(elem_i);
11343 const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, mod));11343 const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, mod));
...@@ -11601,7 +11601,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -11601,7 +11601,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
11601 const gop = try self.const_tracking.getOrPut(self.gpa, inst);11601 const gop = try self.const_tracking.getOrPut(self.gpa, inst);
11602 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{11602 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{
11603 .ty = ty,11603 .ty = ty,
11604 .val = self.air.value(ref, mod).?,11604 .val = (try self.air.value(ref, mod)).?,
11605 }));11605 }));
11606 break :tracking gop.value_ptr;11606 break :tracking gop.value_ptr;
11607 },11607 },
...@@ -11614,7 +11614,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -11614,7 +11614,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
11614 }11614 }
11615 }11615 }
1161611616
11617 return self.genTypedValue(.{ .ty = ty, .val = self.air.value(ref, mod).? });11617 return self.genTypedValue(.{ .ty = ty, .val = (try self.air.value(ref, mod)).? });
11618}11618}
1161911619
11620fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking {11620fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking {
src/codegen.zig+4-4
...@@ -675,7 +675,7 @@ pub fn generateSymbol(...@@ -675,7 +675,7 @@ pub fn generateSymbol(
675 const is_payload = typed_value.val.errorUnionIsPayload();675 const is_payload = typed_value.val.errorUnionIsPayload();
676676
677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
678 const err_val = if (is_payload) Value.zero else typed_value.val;678 const err_val = if (is_payload) try mod.intValue(error_ty, 0) else typed_value.val;
679 return generateSymbol(bin_file, src_loc, .{679 return generateSymbol(bin_file, src_loc, .{
680 .ty = error_ty,680 .ty = error_ty,
681 .val = err_val,681 .val = err_val,
...@@ -690,7 +690,7 @@ pub fn generateSymbol(...@@ -690,7 +690,7 @@ pub fn generateSymbol(
690 if (error_align > payload_align) {690 if (error_align > payload_align) {
691 switch (try generateSymbol(bin_file, src_loc, .{691 switch (try generateSymbol(bin_file, src_loc, .{
692 .ty = error_ty,692 .ty = error_ty,
693 .val = if (is_payload) Value.zero else typed_value.val,693 .val = if (is_payload) try mod.intValue(error_ty, 0) else typed_value.val,
694 }, code, debug_output, reloc_info)) {694 }, code, debug_output, reloc_info)) {
695 .ok => {},695 .ok => {},
696 .fail => |em| return Result{ .fail = em },696 .fail => |em| return Result{ .fail = em },
...@@ -722,7 +722,7 @@ pub fn generateSymbol(...@@ -722,7 +722,7 @@ pub fn generateSymbol(
722 const begin = code.items.len;722 const begin = code.items.len;
723 switch (try generateSymbol(bin_file, src_loc, .{723 switch (try generateSymbol(bin_file, src_loc, .{
724 .ty = error_ty,724 .ty = error_ty,
725 .val = if (is_payload) Value.zero else typed_value.val,725 .val = if (is_payload) try mod.intValue(error_ty, 0) else typed_value.val,
726 }, code, debug_output, reloc_info)) {726 }, code, debug_output, reloc_info)) {
727 .ok => {},727 .ok => {},
728 .fail => |em| return Result{ .fail = em },728 .fail => |em| return Result{ .fail = em },
...@@ -1280,7 +1280,7 @@ pub fn genTypedValue(...@@ -1280,7 +1280,7 @@ pub fn genTypedValue(
12801280
1281 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {1281 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
1282 // We use the error type directly as the type.1282 // We use the error type directly as the type.
1283 const err_val = if (!is_pl) typed_value.val else Value.zero;1283 const err_val = if (!is_pl) typed_value.val else try mod.intValue(error_type, 0);
1284 return genTypedValue(bin_file, src_loc, .{1284 return genTypedValue(bin_file, src_loc, .{
1285 .ty = error_type,1285 .ty = error_type,
1286 .val = err_val,1286 .val = err_val,
src/codegen/c.zig+32-32
...@@ -287,7 +287,7 @@ pub const Function = struct {...@@ -287,7 +287,7 @@ pub const Function = struct {
287 if (gop.found_existing) return gop.value_ptr.*;287 if (gop.found_existing) return gop.value_ptr.*;
288288
289 const mod = f.object.dg.module;289 const mod = f.object.dg.module;
290 const val = f.air.value(ref, mod).?;290 const val = (try f.air.value(ref, mod)).?;
291 const ty = f.typeOf(ref);291 const ty = f.typeOf(ref);
292292
293 const result: CValue = if (lowersToArray(ty, mod)) result: {293 const result: CValue = if (lowersToArray(ty, mod)) result: {
...@@ -356,7 +356,7 @@ pub const Function = struct {...@@ -356,7 +356,7 @@ pub const Function = struct {
356 .constant => |inst| {356 .constant => |inst| {
357 const mod = f.object.dg.module;357 const mod = f.object.dg.module;
358 const ty = f.typeOf(inst);358 const ty = f.typeOf(inst);
359 const val = f.air.value(inst, mod).?;359 const val = (try f.air.value(inst, mod)).?;
360 return f.object.dg.renderValue(w, ty, val, location);360 return f.object.dg.renderValue(w, ty, val, location);
361 },361 },
362 .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location),362 .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location),
...@@ -369,7 +369,7 @@ pub const Function = struct {...@@ -369,7 +369,7 @@ pub const Function = struct {
369 .constant => |inst| {369 .constant => |inst| {
370 const mod = f.object.dg.module;370 const mod = f.object.dg.module;
371 const ty = f.typeOf(inst);371 const ty = f.typeOf(inst);
372 const val = f.air.value(inst, mod).?;372 const val = (try f.air.value(inst, mod)).?;
373 try w.writeAll("(*");373 try w.writeAll("(*");
374 try f.object.dg.renderValue(w, ty, val, .Other);374 try f.object.dg.renderValue(w, ty, val, .Other);
375 return w.writeByte(')');375 return w.writeByte(')');
...@@ -383,7 +383,7 @@ pub const Function = struct {...@@ -383,7 +383,7 @@ pub const Function = struct {
383 .constant => |inst| {383 .constant => |inst| {
384 const mod = f.object.dg.module;384 const mod = f.object.dg.module;
385 const ty = f.typeOf(inst);385 const ty = f.typeOf(inst);
386 const val = f.air.value(inst, mod).?;386 const val = (try f.air.value(inst, mod)).?;
387 try f.object.dg.renderValue(w, ty, val, .Other);387 try f.object.dg.renderValue(w, ty, val, .Other);
388 try w.writeByte('.');388 try w.writeByte('.');
389 return f.writeCValue(w, member, .Other);389 return f.writeCValue(w, member, .Other);
...@@ -397,7 +397,7 @@ pub const Function = struct {...@@ -397,7 +397,7 @@ pub const Function = struct {
397 .constant => |inst| {397 .constant => |inst| {
398 const mod = f.object.dg.module;398 const mod = f.object.dg.module;
399 const ty = f.typeOf(inst);399 const ty = f.typeOf(inst);
400 const val = f.air.value(inst, mod).?;400 const val = (try f.air.value(inst, mod)).?;
401 try w.writeByte('(');401 try w.writeByte('(');
402 try f.object.dg.renderValue(w, ty, val, .Other);402 try f.object.dg.renderValue(w, ty, val, .Other);
403 try w.writeAll(")->");403 try w.writeAll(")->");
...@@ -690,7 +690,7 @@ pub const DeclGen = struct {...@@ -690,7 +690,7 @@ pub const DeclGen = struct {
690 location,690 location,
691 );691 );
692 try writer.print(") + {})", .{692 try writer.print(") + {})", .{
693 try dg.fmtIntLiteral(Type.usize, Value.one, .Other),693 try dg.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1), .Other),
694 });694 });
695 },695 },
696 }696 }
...@@ -1253,7 +1253,7 @@ pub const DeclGen = struct {...@@ -1253,7 +1253,7 @@ pub const DeclGen = struct {
1253 .ErrorUnion => {1253 .ErrorUnion => {
1254 const payload_ty = ty.errorUnionPayload();1254 const payload_ty = ty.errorUnionPayload();
1255 const error_ty = ty.errorUnionSet();1255 const error_ty = ty.errorUnionSet();
1256 const error_val = if (val.errorUnionIsPayload()) Value.zero else val;1256 const error_val = if (val.errorUnionIsPayload()) try mod.intValue(Type.anyerror, 0) else val;
12571257
1258 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {1258 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1259 return dg.renderValue(writer, error_ty, error_val, location);1259 return dg.renderValue(writer, error_ty, error_val, location);
...@@ -3611,7 +3611,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3611,7 +3611,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3611 const ptr_val = try f.resolveInst(bin_op.lhs);3611 const ptr_val = try f.resolveInst(bin_op.lhs);
3612 const src_ty = f.typeOf(bin_op.rhs);3612 const src_ty = f.typeOf(bin_op.rhs);
36133613
3614 const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false;3614 const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false;
36153615
3616 if (val_is_undef) {3616 if (val_is_undef) {
3617 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3617 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
...@@ -4183,7 +4183,7 @@ fn airCall(...@@ -4183,7 +4183,7 @@ fn airCall(
4183 callee: {4183 callee: {
4184 known: {4184 known: {
4185 const fn_decl = fn_decl: {4185 const fn_decl = fn_decl: {
4186 const callee_val = f.air.value(pl_op.operand, mod) orelse break :known;4186 const callee_val = (try f.air.value(pl_op.operand, mod)) orelse break :known;
4187 break :fn_decl switch (callee_val.tag()) {4187 break :fn_decl switch (callee_val.tag()) {
4188 .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl,4188 .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl,
4189 .function => callee_val.castTag(.function).?.data.owner_decl,4189 .function => callee_val.castTag(.function).?.data.owner_decl,
...@@ -4269,7 +4269,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4269,7 +4269,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4269 const mod = f.object.dg.module;4269 const mod = f.object.dg.module;
4270 const pl_op = f.air.instructions.items(.data)[inst].pl_op;4270 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
4271 const name = f.air.nullTerminatedString(pl_op.payload);4271 const name = f.air.nullTerminatedString(pl_op.payload);
4272 const operand_is_undef = if (f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep() else false;4272 const operand_is_undef = if (try f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep() else false;
4273 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);4273 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
42744274
4275 try reap(f, inst, &.{pl_op.operand});4275 try reap(f, inst, &.{pl_op.operand});
...@@ -4735,7 +4735,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4735,7 +4735,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4735 try f.renderType(writer, Type.usize);4735 try f.renderType(writer, Type.usize);
4736 try writer.writeByte(')');4736 try writer.writeByte(')');
4737 }4737 }
4738 try f.object.dg.renderValue(writer, condition_ty, f.air.value(item, mod).?, .Other);4738 try f.object.dg.renderValue(writer, condition_ty, (try f.air.value(item, mod)).?, .Other);
4739 try writer.writeByte(':');4739 try writer.writeByte(':');
4740 }4740 }
4741 try writer.writeByte(' ');4741 try writer.writeByte(' ');
...@@ -5069,7 +5069,7 @@ fn airIsNull(...@@ -5069,7 +5069,7 @@ fn airIsNull(
5069 // operand is a regular pointer, test `operand !=/== NULL`5069 // operand is a regular pointer, test `operand !=/== NULL`
5070 TypedValue{ .ty = optional_ty, .val = Value.null }5070 TypedValue{ .ty = optional_ty, .val = Value.null }
5071 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)5071 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
5072 TypedValue{ .ty = payload_ty, .val = Value.zero }5072 TypedValue{ .ty = payload_ty, .val = try mod.intValue(payload_ty, 0) }
5073 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {5073 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
5074 try writer.writeAll(".ptr");5074 try writer.writeAll(".ptr");
5075 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod);5075 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod);
...@@ -5325,7 +5325,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5325,7 +5325,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5325 },5325 },
5326 .end => {5326 .end => {
5327 try f.writeCValue(writer, field_ptr_val, .Other);5327 try f.writeCValue(writer, field_ptr_val, .Other);
5328 try writer.print(" - {}", .{try f.fmtIntLiteral(Type.usize, Value.one)});5328 try writer.print(" - {}", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))});
5329 },5329 },
5330 }5330 }
53315331
...@@ -5378,7 +5378,7 @@ fn fieldPtr(...@@ -5378,7 +5378,7 @@ fn fieldPtr(
5378 .end => {5378 .end => {
5379 try writer.writeByte('(');5379 try writer.writeByte('(');
5380 try f.writeCValue(writer, container_ptr_val, .Other);5380 try f.writeCValue(writer, container_ptr_val, .Other);
5381 try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, Value.one)});5381 try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))});
5382 },5382 },
5383 }5383 }
53845384
...@@ -5546,7 +5546,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5546,7 +5546,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5546 else5546 else
5547 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })5547 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
5548 else5548 else
5549 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);5549 try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Initializer);
5550 }5550 }
5551 try writer.writeAll(";\n");5551 try writer.writeAll(";\n");
5552 return local;5552 return local;
...@@ -5673,7 +5673,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5673,7 +5673,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5673 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {5673 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5674 try f.writeCValueDeref(writer, operand);5674 try f.writeCValueDeref(writer, operand);
5675 try writer.writeAll(" = ");5675 try writer.writeAll(" = ");
5676 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);5676 try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other);
5677 try writer.writeAll(";\n ");5677 try writer.writeAll(";\n ");
56785678
5679 return operand;5679 return operand;
...@@ -5681,7 +5681,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5681,7 +5681,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5681 try reap(f, inst, &.{ty_op.operand});5681 try reap(f, inst, &.{ty_op.operand});
5682 try f.writeCValueDeref(writer, operand);5682 try f.writeCValueDeref(writer, operand);
5683 try writer.writeAll(".error = ");5683 try writer.writeAll(".error = ");
5684 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);5684 try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other);
5685 try writer.writeAll(";\n");5685 try writer.writeAll(";\n");
56865686
5687 // Then return the payload pointer (only if it is used)5687 // Then return the payload pointer (only if it is used)
...@@ -5737,7 +5737,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5737,7 +5737,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5737 else5737 else
5738 try f.writeCValueMember(writer, local, .{ .identifier = "error" });5738 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
5739 try a.assign(f, writer);5739 try a.assign(f, writer);
5740 try f.object.dg.renderValue(writer, err_ty, Value.zero, .Other);5740 try f.object.dg.renderValue(writer, err_ty, try mod.intValue(err_ty, 0), .Other);
5741 try a.end(f, writer);5741 try a.end(f, writer);
5742 }5742 }
5743 return local;5743 return local;
...@@ -5768,11 +5768,11 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -5768,11 +5768,11 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
5768 else5768 else
5769 try f.writeCValue(writer, operand, .Other)5769 try f.writeCValue(writer, operand, .Other)
5770 else5770 else
5771 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);5771 try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other);
5772 try writer.writeByte(' ');5772 try writer.writeByte(' ');
5773 try writer.writeAll(operator);5773 try writer.writeAll(operator);
5774 try writer.writeByte(' ');5774 try writer.writeByte(' ');
5775 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);5775 try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other);
5776 try writer.writeAll(";\n");5776 try writer.writeAll(";\n");
5777 return local;5777 return local;
5778}5778}
...@@ -5798,7 +5798,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5798,7 +5798,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
5798 } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {5798 } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5799 try writer.writeAll("&(");5799 try writer.writeAll("&(");
5800 try f.writeCValueDeref(writer, operand);5800 try f.writeCValueDeref(writer, operand);
5801 try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, Value.zero)});5801 try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 0))});
5802 } else try f.writeCValue(writer, operand, .Initializer);5802 } else try f.writeCValue(writer, operand, .Initializer);
5803 try writer.writeAll("; ");5803 try writer.writeAll("; ");
58045804
...@@ -6022,7 +6022,7 @@ fn airCmpBuiltinCall(...@@ -6022,7 +6022,7 @@ fn airCmpBuiltinCall(
6022 try writer.writeByte(')');6022 try writer.writeByte(')');
6023 if (!ref_ret) try writer.print(" {s} {}", .{6023 if (!ref_ret) try writer.print(" {s} {}", .{
6024 compareOperatorC(operator),6024 compareOperatorC(operator),
6025 try f.fmtIntLiteral(Type.i32, Value.zero),6025 try f.fmtIntLiteral(Type.i32, try mod.intValue(Type.i32, 0)),
6026 });6026 });
6027 try writer.writeAll(";\n");6027 try writer.writeAll(";\n");
6028 try v.end(f, inst, writer);6028 try v.end(f, inst, writer);
...@@ -6278,7 +6278,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6278,7 +6278,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6278 const value = try f.resolveInst(bin_op.rhs);6278 const value = try f.resolveInst(bin_op.rhs);
6279 const elem_ty = f.typeOf(bin_op.rhs);6279 const elem_ty = f.typeOf(bin_op.rhs);
6280 const elem_abi_size = elem_ty.abiSize(mod);6280 const elem_abi_size = elem_ty.abiSize(mod);
6281 const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;6281 const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
6282 const writer = f.object.writer();6282 const writer = f.object.writer();
62836283
6284 if (val_is_undef) {6284 if (val_is_undef) {
...@@ -6326,7 +6326,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6326,7 +6326,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6326 try writer.writeAll("for (");6326 try writer.writeAll("for (");
6327 try f.writeCValue(writer, index, .Other);6327 try f.writeCValue(writer, index, .Other);
6328 try writer.writeAll(" = ");6328 try writer.writeAll(" = ");
6329 try f.object.dg.renderValue(writer, Type.usize, Value.zero, .Initializer);6329 try f.object.dg.renderValue(writer, Type.usize, try mod.intValue(Type.usize, 0), .Initializer);
6330 try writer.writeAll("; ");6330 try writer.writeAll("; ");
6331 try f.writeCValue(writer, index, .Other);6331 try f.writeCValue(writer, index, .Other);
6332 try writer.writeAll(" != ");6332 try writer.writeAll(" != ");
...@@ -6677,27 +6677,27 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6677,27 +6677,27 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6677 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());6677 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
66786678
6679 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {6679 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {
6680 .Or, .Xor, .Add => Value.zero,6680 .Or, .Xor, .Add => try mod.intValue(scalar_ty, 0),
6681 .And => switch (scalar_ty.zigTypeTag(mod)) {6681 .And => switch (scalar_ty.zigTypeTag(mod)) {
6682 .Bool => Value.one,6682 .Bool => try mod.intValue(Type.comptime_int, 1),
6683 else => switch (scalar_ty.intInfo(mod).signedness) {6683 else => switch (scalar_ty.intInfo(mod).signedness) {
6684 .unsigned => try scalar_ty.maxIntScalar(mod),6684 .unsigned => try scalar_ty.maxIntScalar(mod),
6685 .signed => Value.negative_one,6685 .signed => try mod.intValue(scalar_ty, -1),
6686 },6686 },
6687 },6687 },
6688 .Min => switch (scalar_ty.zigTypeTag(mod)) {6688 .Min => switch (scalar_ty.zigTypeTag(mod)) {
6689 .Bool => Value.one,6689 .Bool => try mod.intValue(Type.comptime_int, 1),
6690 .Int => try scalar_ty.maxIntScalar(mod),6690 .Int => try scalar_ty.maxIntScalar(mod),
6691 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),6691 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),
6692 else => unreachable,6692 else => unreachable,
6693 },6693 },
6694 .Max => switch (scalar_ty.zigTypeTag(mod)) {6694 .Max => switch (scalar_ty.zigTypeTag(mod)) {
6695 .Bool => Value.zero,6695 .Bool => try mod.intValue(scalar_ty, 0),
6696 .Int => try scalar_ty.minInt(stack.get(), mod),6696 .Int => try scalar_ty.minInt(stack.get(), mod),
6697 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),6697 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),
6698 else => unreachable,6698 else => unreachable,
6699 },6699 },
6700 .Mul => Value.one,6700 .Mul => try mod.intValue(Type.comptime_int, 1),
6701 }, .Initializer);6701 }, .Initializer);
6702 try writer.writeAll(";\n");6702 try writer.writeAll(";\n");
67036703
...@@ -7686,13 +7686,13 @@ const Vectorize = struct {...@@ -7686,13 +7686,13 @@ const Vectorize = struct {
76867686
7687 try writer.writeAll("for (");7687 try writer.writeAll("for (");
7688 try f.writeCValue(writer, local, .Other);7688 try f.writeCValue(writer, local, .Other);
7689 try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, Value.zero)});7689 try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 0))});
7690 try f.writeCValue(writer, local, .Other);7690 try f.writeCValue(writer, local, .Other);
7691 try writer.print(" < {d}; ", .{7691 try writer.print(" < {d}; ", .{
7692 try f.fmtIntLiteral(Type.usize, len_val),7692 try f.fmtIntLiteral(Type.usize, len_val),
7693 });7693 });
7694 try f.writeCValue(writer, local, .Other);7694 try f.writeCValue(writer, local, .Other);
7695 try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, Value.one)});7695 try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))});
7696 f.object.indent_writer.pushIndent();7696 f.object.indent_writer.pushIndent();
76977697
7698 break :index .{ .index = local };7698 break :index .{ .index = local };
src/codegen/llvm.zig+9-9
...@@ -2854,7 +2854,7 @@ pub const DeclGen = struct {...@@ -2854,7 +2854,7 @@ pub const DeclGen = struct {
2854 },2854 },
2855 .Array => {2855 .Array => {
2856 const elem_ty = t.childType(mod);2856 const elem_ty = t.childType(mod);
2857 assert(elem_ty.onePossibleValue(mod) == null);2857 if (std.debug.runtime_safety) assert((try elem_ty.onePossibleValue(mod)) == null);
2858 const elem_llvm_ty = try dg.lowerType(elem_ty);2858 const elem_llvm_ty = try dg.lowerType(elem_ty);
2859 const total_len = t.arrayLen(mod) + @boolToInt(t.sentinel(mod) != null);2859 const total_len = t.arrayLen(mod) + @boolToInt(t.sentinel(mod) != null);
2860 return elem_llvm_ty.arrayType(@intCast(c_uint, total_len));2860 return elem_llvm_ty.arrayType(@intCast(c_uint, total_len));
...@@ -3588,7 +3588,7 @@ pub const DeclGen = struct {...@@ -3588,7 +3588,7 @@ pub const DeclGen = struct {
35883588
3589 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3589 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3590 // We use the error type directly as the type.3590 // We use the error type directly as the type.
3591 const err_val = if (!is_pl) tv.val else Value.zero;3591 const err_val = if (!is_pl) tv.val else try mod.intValue(Type.anyerror, 0);
3592 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });3592 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });
3593 }3593 }
35943594
...@@ -3596,7 +3596,7 @@ pub const DeclGen = struct {...@@ -3596,7 +3596,7 @@ pub const DeclGen = struct {
3596 const error_align = Type.anyerror.abiAlignment(mod);3596 const error_align = Type.anyerror.abiAlignment(mod);
3597 const llvm_error_value = try dg.lowerValue(.{3597 const llvm_error_value = try dg.lowerValue(.{
3598 .ty = Type.anyerror,3598 .ty = Type.anyerror,
3599 .val = if (is_pl) Value.zero else tv.val,3599 .val = if (is_pl) try mod.intValue(Type.anyerror, 0) else tv.val,
3600 });3600 });
3601 const llvm_payload_value = try dg.lowerValue(.{3601 const llvm_payload_value = try dg.lowerValue(.{
3602 .ty = payload_type,3602 .ty = payload_type,
...@@ -4476,7 +4476,7 @@ pub const FuncGen = struct {...@@ -4476,7 +4476,7 @@ pub const FuncGen = struct {
4476 const mod = self.dg.module;4476 const mod = self.dg.module;
4477 const llvm_val = try self.resolveValue(.{4477 const llvm_val = try self.resolveValue(.{
4478 .ty = self.typeOf(inst),4478 .ty = self.typeOf(inst),
4479 .val = self.air.value(inst, mod).?,4479 .val = (try self.air.value(inst, mod)).?,
4480 });4480 });
4481 gop.value_ptr.* = llvm_val;4481 gop.value_ptr.* = llvm_val;
4482 return llvm_val;4482 return llvm_val;
...@@ -6873,7 +6873,7 @@ pub const FuncGen = struct {...@@ -6873,7 +6873,7 @@ pub const FuncGen = struct {
6873 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);6873 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
68746874
6875 const payload_ty = err_union_ty.errorUnionPayload();6875 const payload_ty = err_union_ty.errorUnionPayload();
6876 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });6876 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.anyerror, 0) });
6877 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6877 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6878 _ = self.builder.buildStore(non_error_val, operand);6878 _ = self.builder.buildStore(non_error_val, operand);
6879 return operand;6879 return operand;
...@@ -8203,7 +8203,7 @@ pub const FuncGen = struct {...@@ -8203,7 +8203,7 @@ pub const FuncGen = struct {
8203 const ptr_ty = self.typeOf(bin_op.lhs);8203 const ptr_ty = self.typeOf(bin_op.lhs);
8204 const operand_ty = ptr_ty.childType(mod);8204 const operand_ty = ptr_ty.childType(mod);
82058205
8206 const val_is_undef = if (self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;8206 const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
8207 if (val_is_undef) {8207 if (val_is_undef) {
8208 // Even if safety is disabled, we still emit a memset to undefined since it conveys8208 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8209 // extra information to LLVM. However, safety makes the difference between using8209 // extra information to LLVM. However, safety makes the difference between using
...@@ -8494,7 +8494,7 @@ pub const FuncGen = struct {...@@ -8494,7 +8494,7 @@ pub const FuncGen = struct {
8494 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);8494 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
8495 const is_volatile = ptr_ty.isVolatilePtr(mod);8495 const is_volatile = ptr_ty.isVolatilePtr(mod);
84968496
8497 if (self.air.value(bin_op.rhs, mod)) |elem_val| {8497 if (try self.air.value(bin_op.rhs, mod)) |elem_val| {
8498 if (elem_val.isUndefDeep()) {8498 if (elem_val.isUndefDeep()) {
8499 // Even if safety is disabled, we still emit a memset to undefined since it conveys8499 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8500 // extra information to LLVM. However, safety makes the difference between using8500 // extra information to LLVM. However, safety makes the difference between using
...@@ -9323,7 +9323,7 @@ pub const FuncGen = struct {...@@ -9323,7 +9323,7 @@ pub const FuncGen = struct {
93239323
9324 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };9324 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };
9325 for (elements, 0..) |elem, i| {9325 for (elements, 0..) |elem, i| {
9326 if (result_ty.structFieldValueComptime(mod, i) != null) continue;9326 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;
93279327
9328 const llvm_elem = try self.resolveInst(elem);9328 const llvm_elem = try self.resolveInst(elem);
9329 const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?;9329 const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?;
...@@ -9344,7 +9344,7 @@ pub const FuncGen = struct {...@@ -9344,7 +9344,7 @@ pub const FuncGen = struct {
9344 } else {9344 } else {
9345 var result = llvm_result_ty.getUndef();9345 var result = llvm_result_ty.getUndef();
9346 for (elements, 0..) |elem, i| {9346 for (elements, 0..) |elem, i| {
9347 if (result_ty.structFieldValueComptime(mod, i) != null) continue;9347 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;
93489348
9349 const llvm_elem = try self.resolveInst(elem);9349 const llvm_elem = try self.resolveInst(elem);
9350 const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?;9350 const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?;
src/codegen/spirv.zig+5-5
...@@ -232,7 +232,7 @@ pub const DeclGen = struct {...@@ -232,7 +232,7 @@ pub const DeclGen = struct {
232 /// Fetch the result-id for a previously generated instruction or constant.232 /// Fetch the result-id for a previously generated instruction or constant.
233 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {233 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {
234 const mod = self.module;234 const mod = self.module;
235 if (self.air.value(inst, mod)) |val| {235 if (try self.air.value(inst, mod)) |val| {
236 const ty = self.typeOf(inst);236 const ty = self.typeOf(inst);
237 if (ty.zigTypeTag(mod) == .Fn) {237 if (ty.zigTypeTag(mod) == .Fn) {
238 const fn_decl_index = switch (val.tag()) {238 const fn_decl_index = switch (val.tag()) {
...@@ -584,7 +584,7 @@ pub const DeclGen = struct {...@@ -584,7 +584,7 @@ pub const DeclGen = struct {
584 // TODO: Properly lower function pointers. For now we are going to hack around it and584 // TODO: Properly lower function pointers. For now we are going to hack around it and
585 // just generate an empty pointer. Function pointers are represented by usize for now,585 // just generate an empty pointer. Function pointers are represented by usize for now,
586 // though.586 // though.
587 try self.addInt(Type.usize, Value.zero);587 try self.addInt(Type.usize, Value.zero_usize);
588 // TODO: Add dependency588 // TODO: Add dependency
589 return;589 return;
590 },590 },
...@@ -803,7 +803,7 @@ pub const DeclGen = struct {...@@ -803,7 +803,7 @@ pub const DeclGen = struct {
803 .ErrorUnion => {803 .ErrorUnion => {
804 const payload_ty = ty.errorUnionPayload();804 const payload_ty = ty.errorUnionPayload();
805 const is_pl = val.errorUnionIsPayload();805 const is_pl = val.errorUnionIsPayload();
806 const error_val = if (!is_pl) val else Value.zero;806 const error_val = if (!is_pl) val else try mod.intValue(Type.anyerror, 0);
807807
808 const eu_layout = dg.errorUnionLayout(payload_ty);808 const eu_layout = dg.errorUnionLayout(payload_ty);
809 if (!eu_layout.payload_has_bits) {809 if (!eu_layout.payload_has_bits) {
...@@ -2801,7 +2801,7 @@ pub const DeclGen = struct {...@@ -2801,7 +2801,7 @@ pub const DeclGen = struct {
2801 const value = try self.resolve(bin_op.rhs);2801 const value = try self.resolve(bin_op.rhs);
2802 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);2802 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
28032803
2804 const val_is_undef = if (self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;2804 const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
2805 if (val_is_undef) {2805 if (val_is_undef) {
2806 const undef = try self.spv.constUndef(ptr_ty_ref);2806 const undef = try self.spv.constUndef(ptr_ty_ref);
2807 try self.store(ptr_ty, ptr, undef);2807 try self.store(ptr_ty, ptr, undef);
...@@ -3141,7 +3141,7 @@ pub const DeclGen = struct {...@@ -3141,7 +3141,7 @@ pub const DeclGen = struct {
3141 const label = IdRef{ .id = first_case_label.id + case_i };3141 const label = IdRef{ .id = first_case_label.id + case_i };
31423142
3143 for (items) |item| {3143 for (items) |item| {
3144 const value = self.air.value(item, mod) orelse {3144 const value = (try self.air.value(item, mod)) orelse {
3145 return self.todo("switch on runtime value???", .{});3145 return self.todo("switch on runtime value???", .{});
3146 };3146 };
3147 const int_val = switch (cond_ty.zigTypeTag(mod)) {3147 const int_val = switch (cond_ty.zigTypeTag(mod)) {
src/type.zig+22-22
...@@ -3377,7 +3377,7 @@ pub const Type = struct {...@@ -3377,7 +3377,7 @@ pub const Type = struct {
3377 }3377 }
33783378
3379 /// For vectors, returns the element type. Otherwise returns self.3379 /// For vectors, returns the element type. Otherwise returns self.
3380 pub fn scalarType(ty: Type, mod: *const Module) Type {3380 pub fn scalarType(ty: Type, mod: *Module) Type {
3381 return switch (ty.zigTypeTag(mod)) {3381 return switch (ty.zigTypeTag(mod)) {
3382 .Vector => ty.childType(mod),3382 .Vector => ty.childType(mod),
3383 else => ty,3383 else => ty,
...@@ -3941,13 +3941,13 @@ pub const Type = struct {...@@ -3941,13 +3941,13 @@ pub const Type = struct {
39413941
3942 /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which3942 /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which
3943 /// resolves field types rather than asserting they are already resolved.3943 /// resolves field types rather than asserting they are already resolved.
3944 pub fn onePossibleValue(starting_type: Type, mod: *const Module) ?Value {3944 pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
3945 var ty = starting_type;3945 var ty = starting_type;
39463946
3947 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {3947 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3948 .int_type => |int_type| {3948 .int_type => |int_type| {
3949 if (int_type.bits == 0) {3949 if (int_type.bits == 0) {
3950 return Value.zero;3950 return try mod.intValue(ty, 0);
3951 } else {3951 } else {
3952 return null;3952 return null;
3953 }3953 }
...@@ -3956,13 +3956,13 @@ pub const Type = struct {...@@ -3956,13 +3956,13 @@ pub const Type = struct {
3956 .array_type => |array_type| {3956 .array_type => |array_type| {
3957 if (array_type.len == 0)3957 if (array_type.len == 0)
3958 return Value.initTag(.empty_array);3958 return Value.initTag(.empty_array);
3959 if (array_type.child.toType().onePossibleValue(mod) != null)3959 if ((try array_type.child.toType().onePossibleValue(mod)) != null)
3960 return Value.initTag(.the_only_possible_value);3960 return Value.initTag(.the_only_possible_value);
3961 return null;3961 return null;
3962 },3962 },
3963 .vector_type => |vector_type| {3963 .vector_type => |vector_type| {
3964 if (vector_type.len == 0) return Value.initTag(.empty_array);3964 if (vector_type.len == 0) return Value.initTag(.empty_array);
3965 if (vector_type.child.toType().onePossibleValue(mod)) |v| return v;3965 if (try vector_type.child.toType().onePossibleValue(mod)) |v| return v;
3966 return null;3966 return null;
3967 },3967 },
3968 .opt_type => |child| {3968 .opt_type => |child| {
...@@ -4055,7 +4055,7 @@ pub const Type = struct {...@@ -4055,7 +4055,7 @@ pub const Type = struct {
4055 assert(s.haveFieldTypes());4055 assert(s.haveFieldTypes());
4056 for (s.fields.values()) |field| {4056 for (s.fields.values()) |field| {
4057 if (field.is_comptime) continue;4057 if (field.is_comptime) continue;
4058 if (field.ty.onePossibleValue(mod) != null) continue;4058 if ((try field.ty.onePossibleValue(mod)) != null) continue;
4059 return null;4059 return null;
4060 }4060 }
4061 return Value.initTag(.empty_struct_value);4061 return Value.initTag(.empty_struct_value);
...@@ -4066,7 +4066,7 @@ pub const Type = struct {...@@ -4066,7 +4066,7 @@ pub const Type = struct {
4066 for (tuple.values, 0..) |val, i| {4066 for (tuple.values, 0..) |val, i| {
4067 const is_comptime = val.ip_index != .unreachable_value;4067 const is_comptime = val.ip_index != .unreachable_value;
4068 if (is_comptime) continue;4068 if (is_comptime) continue;
4069 if (tuple.types[i].onePossibleValue(mod) != null) continue;4069 if ((try tuple.types[i].onePossibleValue(mod)) != null) continue;
4070 return null;4070 return null;
4071 }4071 }
4072 return Value.initTag(.empty_struct_value);4072 return Value.initTag(.empty_struct_value);
...@@ -4089,7 +4089,7 @@ pub const Type = struct {...@@ -4089,7 +4089,7 @@ pub const Type = struct {
4089 switch (enum_full.fields.count()) {4089 switch (enum_full.fields.count()) {
4090 0 => return Value.@"unreachable",4090 0 => return Value.@"unreachable",
4091 1 => if (enum_full.values.count() == 0) {4091 1 => if (enum_full.values.count() == 0) {
4092 return Value.zero; // auto-numbered4092 return try mod.intValue(ty, 0); // auto-numbered
4093 } else {4093 } else {
4094 return enum_full.values.keys()[0];4094 return enum_full.values.keys()[0];
4095 },4095 },
...@@ -4100,24 +4100,24 @@ pub const Type = struct {...@@ -4100,24 +4100,24 @@ pub const Type = struct {
4100 const enum_simple = ty.castTag(.enum_simple).?.data;4100 const enum_simple = ty.castTag(.enum_simple).?.data;
4101 switch (enum_simple.fields.count()) {4101 switch (enum_simple.fields.count()) {
4102 0 => return Value.@"unreachable",4102 0 => return Value.@"unreachable",
4103 1 => return Value.zero,4103 1 => return try mod.intValue(ty, 0),
4104 else => return null,4104 else => return null,
4105 }4105 }
4106 },4106 },
4107 .enum_nonexhaustive => {4107 .enum_nonexhaustive => {
4108 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;4108 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;
4109 if (!tag_ty.hasRuntimeBits(mod)) {4109 if (!tag_ty.hasRuntimeBits(mod)) {
4110 return Value.zero;4110 return try mod.intValue(ty, 0);
4111 } else {4111 } else {
4112 return null;4112 return null;
4113 }4113 }
4114 },4114 },
4115 .@"union", .union_safety_tagged, .union_tagged => {4115 .@"union", .union_safety_tagged, .union_tagged => {
4116 const union_obj = ty.cast(Payload.Union).?.data;4116 const union_obj = ty.cast(Payload.Union).?.data;
4117 const tag_val = union_obj.tag_ty.onePossibleValue(mod) orelse return null;4117 const tag_val = (try union_obj.tag_ty.onePossibleValue(mod)) orelse return null;
4118 if (union_obj.fields.count() == 0) return Value.@"unreachable";4118 if (union_obj.fields.count() == 0) return Value.@"unreachable";
4119 const only_field = union_obj.fields.values()[0];4119 const only_field = union_obj.fields.values()[0];
4120 const val_val = only_field.ty.onePossibleValue(mod) orelse return null;4120 const val_val = (try only_field.ty.onePossibleValue(mod)) orelse return null;
4121 _ = tag_val;4121 _ = tag_val;
4122 _ = val_val;4122 _ = val_val;
4123 return Value.initTag(.empty_struct_value);4123 return Value.initTag(.empty_struct_value);
...@@ -4128,7 +4128,7 @@ pub const Type = struct {...@@ -4128,7 +4128,7 @@ pub const Type = struct {
4128 .array => {4128 .array => {
4129 if (ty.arrayLen(mod) == 0)4129 if (ty.arrayLen(mod) == 0)
4130 return Value.initTag(.empty_array);4130 return Value.initTag(.empty_array);
4131 if (ty.childType(mod).onePossibleValue(mod) != null)4131 if ((try ty.childType(mod).onePossibleValue(mod)) != null)
4132 return Value.initTag(.the_only_possible_value);4132 return Value.initTag(.the_only_possible_value);
4133 return null;4133 return null;
4134 },4134 },
...@@ -4365,8 +4365,8 @@ pub const Type = struct {...@@ -4365,8 +4365,8 @@ pub const Type = struct {
4365 /// Asserts that the type is an integer.4365 /// Asserts that the type is an integer.
4366 pub fn minIntScalar(ty: Type, mod: *Module) !Value {4366 pub fn minIntScalar(ty: Type, mod: *Module) !Value {
4367 const info = ty.intInfo(mod);4367 const info = ty.intInfo(mod);
4368 if (info.signedness == .unsigned) return Value.zero;4368 if (info.signedness == .unsigned) return mod.intValue(ty, 0);
4369 if (info.bits == 0) return Value.negative_one;4369 if (info.bits == 0) return mod.intValue(ty, -1);
43704370
4371 if (std.math.cast(u6, info.bits - 1)) |shift| {4371 if (std.math.cast(u6, info.bits - 1)) |shift| {
4372 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);4372 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);
...@@ -4392,17 +4392,17 @@ pub const Type = struct {...@@ -4392,17 +4392,17 @@ pub const Type = struct {
4392 }4392 }
43934393
4394 /// Asserts that the type is an integer.4394 /// Asserts that the type is an integer.
4395 pub fn maxIntScalar(self: Type, mod: *Module) !Value {4395 pub fn maxIntScalar(ty: Type, mod: *Module) !Value {
4396 const info = self.intInfo(mod);4396 const info = ty.intInfo(mod);
43974397
4398 switch (info.bits) {4398 switch (info.bits) {
4399 0 => return switch (info.signedness) {4399 0 => return switch (info.signedness) {
4400 .signed => Value.negative_one,4400 .signed => mod.intValue(ty, -1),
4401 .unsigned => Value.zero,4401 .unsigned => mod.intValue(ty, 0),
4402 },4402 },
4403 1 => return switch (info.signedness) {4403 1 => return switch (info.signedness) {
4404 .signed => Value.zero,4404 .signed => mod.intValue(ty, 0),
4405 .unsigned => Value.one,4405 .unsigned => mod.intValue(ty, 0),
4406 },4406 },
4407 else => {},4407 else => {},
4408 }4408 }
...@@ -4662,7 +4662,7 @@ pub const Type = struct {...@@ -4662,7 +4662,7 @@ pub const Type = struct {
4662 }4662 }
4663 }4663 }
46644664
4665 pub fn structFieldValueComptime(ty: Type, mod: *const Module, index: usize) ?Value {4665 pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value {
4666 switch (ty.tag()) {4666 switch (ty.tag()) {
4667 .@"struct" => {4667 .@"struct" => {
4668 const struct_obj = ty.castTag(.@"struct").?.data;4668 const struct_obj = ty.castTag(.@"struct").?.data;
src/value.zig+22-21
...@@ -1022,7 +1022,7 @@ pub const Value = struct {...@@ -1022,7 +1022,7 @@ pub const Value = struct {
1022 if (opt_val) |some| {1022 if (opt_val) |some| {
1023 return some.writeToMemory(child, mod, buffer);1023 return some.writeToMemory(child, mod, buffer);
1024 } else {1024 } else {
1025 return writeToMemory(Value.zero, Type.usize, mod, buffer);1025 return writeToMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer);
1026 }1026 }
1027 },1027 },
1028 else => return error.Unimplemented,1028 else => return error.Unimplemented,
...@@ -1124,7 +1124,7 @@ pub const Value = struct {...@@ -1124,7 +1124,7 @@ pub const Value = struct {
1124 .Packed => {1124 .Packed => {
1125 const field_index = ty.unionTagFieldIndex(val.unionTag(), mod);1125 const field_index = ty.unionTagFieldIndex(val.unionTag(), mod);
1126 const field_type = ty.unionFields().values()[field_index.?].ty;1126 const field_type = ty.unionFields().values()[field_index.?].ty;
1127 const field_val = val.fieldValue(field_type, mod, field_index.?);1127 const field_val = try val.fieldValue(field_type, mod, field_index.?);
11281128
1129 return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);1129 return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);
1130 },1130 },
...@@ -1141,7 +1141,7 @@ pub const Value = struct {...@@ -1141,7 +1141,7 @@ pub const Value = struct {
1141 if (opt_val) |some| {1141 if (opt_val) |some| {
1142 return some.writeToPackedMemory(child, mod, buffer, bit_offset);1142 return some.writeToPackedMemory(child, mod, buffer, bit_offset);
1143 } else {1143 } else {
1144 return writeToPackedMemory(Value.zero, Type.usize, mod, buffer, bit_offset);1144 return writeToPackedMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer, bit_offset);
1145 }1145 }
1146 },1146 },
1147 else => @panic("TODO implement writeToPackedMemory for more types"),1147 else => @panic("TODO implement writeToPackedMemory for more types"),
...@@ -1173,7 +1173,7 @@ pub const Value = struct {...@@ -1173,7 +1173,7 @@ pub const Value = struct {
1173 const int_info = ty.intInfo(mod);1173 const int_info = ty.intInfo(mod);
1174 const bits = int_info.bits;1174 const bits = int_info.bits;
1175 const byte_count = (bits + 7) / 8;1175 const byte_count = (bits + 7) / 8;
1176 if (bits == 0 or buffer.len == 0) return Value.zero;1176 if (bits == 0 or buffer.len == 0) return mod.intValue(ty, 0);
11771177
1178 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u641178 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64
1179 .signed => {1179 .signed => {
...@@ -1290,12 +1290,12 @@ pub const Value = struct {...@@ -1290,12 +1290,12 @@ pub const Value = struct {
1290 }1290 }
1291 },1291 },
1292 .Int, .Enum => {1292 .Int, .Enum => {
1293 if (buffer.len == 0) return Value.zero;1293 if (buffer.len == 0) return mod.intValue(ty, 0);
1294 const int_info = ty.intInfo(mod);1294 const int_info = ty.intInfo(mod);
1295 const abi_size = @intCast(usize, ty.abiSize(mod));1295 const abi_size = @intCast(usize, ty.abiSize(mod));
12961296
1297 const bits = int_info.bits;1297 const bits = int_info.bits;
1298 if (bits == 0) return Value.zero;1298 if (bits == 0) return mod.intValue(ty, 0);
1299 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u641299 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64
1300 .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),1300 .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),
1301 .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),1301 .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),
...@@ -2091,11 +2091,11 @@ pub const Value = struct {...@@ -2091,11 +2091,11 @@ pub const Value = struct {
2091 // .the_one_possible_value,2091 // .the_one_possible_value,
2092 // .aggregate,2092 // .aggregate,
2093 // Note that we already checked above for matching tags, e.g. both .aggregate.2093 // Note that we already checked above for matching tags, e.g. both .aggregate.
2094 return ty.onePossibleValue(mod) != null;2094 return (try ty.onePossibleValue(mod)) != null;
2095 },2095 },
2096 .Union => {2096 .Union => {
2097 // Here we have to check for value equality, as-if `a` has been coerced to `ty`.2097 // Here we have to check for value equality, as-if `a` has been coerced to `ty`.
2098 if (ty.onePossibleValue(mod) != null) {2098 if ((try ty.onePossibleValue(mod)) != null) {
2099 return true;2099 return true;
2100 }2100 }
2101 if (a_ty.castTag(.anon_struct)) |payload| {2101 if (a_ty.castTag(.anon_struct)) |payload| {
...@@ -2604,7 +2604,7 @@ pub const Value = struct {...@@ -2604,7 +2604,7 @@ pub const Value = struct {
2604 if (data.container_ptr.pointerDecl()) |decl_index| {2604 if (data.container_ptr.pointerDecl()) |decl_index| {
2605 const container_decl = mod.declPtr(decl_index);2605 const container_decl = mod.declPtr(decl_index);
2606 const field_type = data.container_ty.structFieldType(data.field_index);2606 const field_type = data.container_ty.structFieldType(data.field_index);
2607 const field_val = container_decl.val.fieldValue(field_type, mod, data.field_index);2607 const field_val = try container_decl.val.fieldValue(field_type, mod, data.field_index);
2608 return field_val.elemValue(mod, index);2608 return field_val.elemValue(mod, index);
2609 } else unreachable;2609 } else unreachable;
2610 },2610 },
...@@ -2723,7 +2723,7 @@ pub const Value = struct {...@@ -2723,7 +2723,7 @@ pub const Value = struct {
2723 };2723 };
2724 }2724 }
27252725
2726 pub fn fieldValue(val: Value, ty: Type, mod: *const Module, index: usize) Value {2726 pub fn fieldValue(val: Value, ty: Type, mod: *Module, index: usize) !Value {
2727 switch (val.ip_index) {2727 switch (val.ip_index) {
2728 .undef => return Value.undef,2728 .undef => return Value.undef,
2729 .none => switch (val.tag()) {2729 .none => switch (val.tag()) {
...@@ -2737,14 +2737,14 @@ pub const Value = struct {...@@ -2737,14 +2737,14 @@ pub const Value = struct {
2737 return payload.val;2737 return payload.val;
2738 },2738 },
27392739
2740 .the_only_possible_value => return ty.onePossibleValue(mod).?,2740 .the_only_possible_value => return (try ty.onePossibleValue(mod)).?,
27412741
2742 .empty_struct_value => {2742 .empty_struct_value => {
2743 if (ty.isSimpleTupleOrAnonStruct()) {2743 if (ty.isSimpleTupleOrAnonStruct()) {
2744 const tuple = ty.tupleFields();2744 const tuple = ty.tupleFields();
2745 return tuple.values[index];2745 return tuple.values[index];
2746 }2746 }
2747 if (ty.structFieldValueComptime(mod, index)) |some| {2747 if (try ty.structFieldValueComptime(mod, index)) |some| {
2748 return some;2748 return some;
2749 }2749 }
2750 unreachable;2750 unreachable;
...@@ -2968,7 +2968,7 @@ pub const Value = struct {...@@ -2968,7 +2968,7 @@ pub const Value = struct {
2968 switch (val.ip_index) {2968 switch (val.ip_index) {
2969 .undef => return val,2969 .undef => return val,
2970 .none => switch (val.tag()) {2970 .none => switch (val.tag()) {
2971 .the_only_possible_value => return Value.zero, // for i0, u02971 .the_only_possible_value => return Value.float_zero, // for i0, u0
2972 .lazy_align => {2972 .lazy_align => {
2973 const ty = val.castTag(.lazy_align).?.data;2973 const ty = val.castTag(.lazy_align).?.data;
2974 if (opt_sema) |sema| {2974 if (opt_sema) |sema| {
...@@ -3402,7 +3402,7 @@ pub const Value = struct {...@@ -3402,7 +3402,7 @@ pub const Value = struct {
3402 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;3402 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
34033403
3404 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);3404 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);
3405 const all_ones = if (ty.isSignedInt(mod)) Value.negative_one else try ty.maxIntScalar(mod);3405 const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod);
3406 return bitwiseXor(anded, all_ones, ty, arena, mod);3406 return bitwiseXor(anded, all_ones, ty, arena, mod);
3407 }3407 }
34083408
...@@ -3803,7 +3803,7 @@ pub const Value = struct {...@@ -3803,7 +3803,7 @@ pub const Value = struct {
3803 bits: u16,3803 bits: u16,
3804 mod: *Module,3804 mod: *Module,
3805 ) !Value {3805 ) !Value {
3806 if (bits == 0) return Value.zero;3806 if (bits == 0) return mod.intValue(ty, 0);
38073807
3808 var val_space: Value.BigIntSpace = undefined;3808 var val_space: Value.BigIntSpace = undefined;
3809 const val_bigint = val.toBigInt(&val_space, mod);3809 const val_bigint = val.toBigInt(&val_space, mod);
...@@ -4011,9 +4011,9 @@ pub const Value = struct {...@@ -4011,9 +4011,9 @@ pub const Value = struct {
4011 // The shift is enough to remove all the bits from the number, which means the4011 // The shift is enough to remove all the bits from the number, which means the
4012 // result is 0 or -1 depending on the sign.4012 // result is 0 or -1 depending on the sign.
4013 if (lhs_bigint.positive) {4013 if (lhs_bigint.positive) {
4014 return Value.zero;4014 return mod.intValue(ty, 0);
4015 } else {4015 } else {
4016 return Value.negative_one;4016 return mod.intValue(ty, -1);
4017 }4017 }
4018 }4018 }
40194019
...@@ -5151,10 +5151,9 @@ pub const Value = struct {...@@ -5151,10 +5151,9 @@ pub const Value = struct {
51515151
5152 pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;5152 pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;
51535153
5154 pub const zero: Value = .{ .ip_index = .zero, .legacy = undefined };5154 pub const zero_usize: Value = .{ .ip_index = .zero_usize, .legacy = undefined };
5155 pub const one: Value = .{ .ip_index = .one, .legacy = undefined };
5156 pub const negative_one: Value = .{ .ip_index = .negative_one, .legacy = undefined };
5157 pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined };5155 pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined };
5156 pub const float_zero: Value = .{ .ip_index = .zero, .legacy = undefined }; // TODO: replace this!
5158 pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };5157 pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };
5159 pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined };5158 pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined };
5160 pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined };5159 pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined };
...@@ -5169,7 +5168,9 @@ pub const Value = struct {...@@ -5169,7 +5168,9 @@ pub const Value = struct {
5169 }5168 }
51705169
5171 pub fn boolToInt(x: bool) Value {5170 pub fn boolToInt(x: bool) Value {
5172 return if (x) Value.one else Value.zero;5171 const zero: Value = .{ .ip_index = .zero, .legacy = undefined };
5172 const one: Value = .{ .ip_index = .one, .legacy = undefined };
5173 return if (x) one else zero;
5173 }5174 }
51745175
5175 pub const RuntimeIndex = enum(u32) {5176 pub const RuntimeIndex = enum(u32) {