authorgravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2025-08-07 13:02:01+02:00
committergravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2025-08-12 16:33:57+02:00
log05762ca02ff97e7abfe1b52c090663dbf99bd4fc
tree73e60e53611da67db0dd73cbde39aa93d94f44cf
parent0ef26d113ae5a8b307a3af76db61706846fea22f

address most comments


6 files changed, 61 insertions(+), 99 deletions(-)

src/InternPool.zig+5-3
...@@ -2036,6 +2036,8 @@ pub const Key = union(enum) {...@@ -2036,6 +2036,8 @@ pub const Key = union(enum) {
2036 /// Each element/field stored as an `Index`.2036 /// Each element/field stored as an `Index`.
2037 /// In the case of sentinel-terminated arrays, the sentinel value *is* stored,2037 /// In the case of sentinel-terminated arrays, the sentinel value *is* stored,
2038 /// so the slice length will be one more than the type's array length.2038 /// so the slice length will be one more than the type's array length.
2039 /// There must be at least one element which is not `undefined`. If all elements are
2040 /// undefined, instead create an undefined value of the aggregate type.
2039 aggregate: Aggregate,2041 aggregate: Aggregate,
2040 /// An instance of a union.2042 /// An instance of a union.
2041 un: Union,2043 un: Union,
...@@ -8408,7 +8410,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -8408,7 +8410,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
8408 if (!ip.isUndef(elem)) any_defined = true;8410 if (!ip.isUndef(elem)) any_defined = true;
8409 assert(ip.typeOf(elem) == child);8411 assert(ip.typeOf(elem) == child);
8410 }8412 }
8411 assert(any_defined);8413 assert(any_defined); // aggregate fields must not be all undefined
8412 },8414 },
8413 .struct_type => {8415 .struct_type => {
8414 var any_defined = false;8416 var any_defined = false;
...@@ -8416,7 +8418,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -8416,7 +8418,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
8416 if (!ip.isUndef(elem)) any_defined = true;8418 if (!ip.isUndef(elem)) any_defined = true;
8417 assert(ip.typeOf(elem) == field_ty);8419 assert(ip.typeOf(elem) == field_ty);
8418 }8420 }
8419 assert(any_defined);8421 assert(any_defined); // aggregate fields must not be all undefined
8420 },8422 },
8421 .tuple_type => |tuple_type| {8423 .tuple_type => |tuple_type| {
8422 var any_defined = false;8424 var any_defined = false;
...@@ -8424,7 +8426,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -8424,7 +8426,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
8424 if (!ip.isUndef(elem)) any_defined = true;8426 if (!ip.isUndef(elem)) any_defined = true;
8425 assert(ip.typeOf(elem) == ty);8427 assert(ip.typeOf(elem) == ty);
8426 }8428 }
8427 assert(any_defined);8429 assert(any_defined); // aggregate fields must not be all undefined
8428 },8430 },
8429 else => unreachable,8431 else => unreachable,
8430 };8432 };
src/Sema.zig+40-32
...@@ -13637,6 +13637,8 @@ fn zirShl(...@@ -13637,6 +13637,8 @@ fn zirShl(
13637 const scalar_ty = lhs_ty.scalarType(zcu);13637 const scalar_ty = lhs_ty.scalarType(zcu);
13638 const scalar_rhs_ty = rhs_ty.scalarType(zcu);13638 const scalar_rhs_ty = rhs_ty.scalarType(zcu);
1363913639
13640 // AstGen currently forces the rhs of `<<` to coerce to the correct type before the `.shl` instruction, so
13641 // we already know `scalar_rhs_ty` is valid for `.shl` -- we only need to validate for `.shl_sat`.
13640 if (air_tag == .shl_sat) _ = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);13642 if (air_tag == .shl_sat) _ = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
1364113643
13642 const maybe_lhs_val = try sema.resolveValueResolveLazy(lhs);13644 const maybe_lhs_val = try sema.resolveValueResolveLazy(lhs);
...@@ -13645,25 +13647,29 @@ fn zirShl(...@@ -13645,25 +13647,29 @@ fn zirShl(
13645 const runtime_src = rs: {13647 const runtime_src = rs: {
13646 if (maybe_rhs_val) |rhs_val| {13648 if (maybe_rhs_val) |rhs_val| {
13647 if (maybe_lhs_val) |lhs_val| {13649 if (maybe_lhs_val) |lhs_val| {
13648 return Air.internedToRef((try arith.shl(sema, block, lhs_ty, lhs_val, rhs_val, lhs_src, rhs_src, switch (air_tag) {13650 return .fromValue(try arith.shl(sema, block, lhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, switch (air_tag) {
13649 .shl => .shl,13651 .shl => .shl,
13650 .shl_sat => .shl_sat,13652 .shl_sat => .shl_sat,
13651 .shl_exact => .shl_exact,13653 .shl_exact => .shl_exact,
13652 else => unreachable,13654 else => unreachable,
13653 })).toIntern());13655 }));
13654 }13656 }
13655 if (rhs_val.isUndef(zcu)) switch (air_tag) {13657 if (rhs_val.isUndef(zcu)) switch (air_tag) {
13656 .shl_sat => return pt.undefRef(lhs_ty),13658 .shl_sat => return pt.undefRef(lhs_ty),
13657 .shl, .shl_exact => return sema.failWithUseOfUndef(block, rhs_src, null),13659 .shl, .shl_exact => return sema.failWithUseOfUndef(block, rhs_src, null),
13658 else => unreachable,13660 else => unreachable,
13659 };13661 };
13660 const bits_val = try pt.intValue(.comptime_int, scalar_ty.intInfo(zcu).bits);13662 const bits = scalar_ty.intInfo(zcu).bits;
13661 switch (rhs_ty.zigTypeTag(zcu)) {13663 switch (rhs_ty.zigTypeTag(zcu)) {
13662 .int, .comptime_int => {13664 .int, .comptime_int => {
13663 switch (try rhs_val.orderAgainstZeroSema(pt)) {13665 switch (try rhs_val.orderAgainstZeroSema(pt)) {
13664 .gt => {13666 .gt => {
13665 if (air_tag != .shl_sat and try rhs_val.compareHeteroSema(.gte, bits_val, pt)) {13667 if (air_tag != .shl_sat) {
13666 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);13668 var rhs_space: Value.BigIntSpace = undefined;
13669 const rhs_bigint = try rhs_val.toBigIntSema(&rhs_space, pt);
13670 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
13671 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
13672 }
13667 }13673 }
13668 },13674 },
13669 .eq => return lhs,13675 .eq => return lhs,
...@@ -13672,8 +13678,7 @@ fn zirShl(...@@ -13672,8 +13678,7 @@ fn zirShl(
13672 },13678 },
13673 .vector => {13679 .vector => {
13674 var any_positive: bool = false;13680 var any_positive: bool = false;
13675 var elem_idx: usize = 0;13681 for (0..rhs_ty.vectorLen(zcu)) |elem_idx| {
13676 while (elem_idx < rhs_ty.vectorLen(zcu)) : (elem_idx += 1) {
13677 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);13682 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
13678 if (rhs_elem.isUndef(zcu)) switch (air_tag) {13683 if (rhs_elem.isUndef(zcu)) switch (air_tag) {
13679 .shl_sat => continue,13684 .shl_sat => continue,
...@@ -13682,8 +13687,12 @@ fn zirShl(...@@ -13682,8 +13687,12 @@ fn zirShl(
13682 };13687 };
13683 switch (try rhs_elem.orderAgainstZeroSema(pt)) {13688 switch (try rhs_elem.orderAgainstZeroSema(pt)) {
13684 .gt => {13689 .gt => {
13685 if (air_tag != .shl_sat and try rhs_elem.compareHeteroSema(.gte, bits_val, pt)) {13690 if (air_tag != .shl_sat) {
13686 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);13691 var rhs_elem_space: Value.BigIntSpace = undefined;
13692 const rhs_elem_bigint = try rhs_elem.toBigIntSema(&rhs_elem_space, pt);
13693 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
13694 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
13695 }
13687 }13696 }
13688 any_positive = true;13697 any_positive = true;
13689 },13698 },
...@@ -13713,29 +13722,29 @@ fn zirShl(...@@ -13713,29 +13722,29 @@ fn zirShl(
13713 }13722 }
13714 break :rs rhs_src;13723 break :rs rhs_src;
13715 };13724 };
13716 const rt_rhs = switch (air_tag) {13725 const rt_rhs: Air.Inst.Ref = switch (air_tag) {
13717 else => unreachable,13726 else => unreachable,
13718 .shl, .shl_exact => rhs,13727 .shl, .shl_exact => rhs,
13719 // The backend can handle a large runtime rhs better than we can, but13728 // The backend can handle a large runtime rhs better than we can, but
13720 // we can limit a large comptime rhs better here. This also has the13729 // we can limit a large comptime rhs better here. This also has the
13721 // necessary side effect of preventing rhs from being a `comptime_int`.13730 // necessary side effect of preventing rhs from being a `comptime_int`.
13722 .shl_sat => if (maybe_rhs_val) |rhs_val| Air.internedToRef(rt_rhs: {13731 .shl_sat => if (maybe_rhs_val) |rhs_val| .fromValue(rt_rhs: {
13723 const bit_count = scalar_ty.intInfo(zcu).bits;13732 const bit_count = scalar_ty.intInfo(zcu).bits;
13724 const rt_rhs_scalar_ty = try pt.smallestUnsignedInt(bit_count);13733 const rt_rhs_scalar_ty = try pt.smallestUnsignedInt(bit_count);
13725 if (!rhs_ty.isVector(zcu)) break :rt_rhs (try pt.intValue(13734 if (!rhs_ty.isVector(zcu)) break :rt_rhs try pt.intValue(
13726 rt_rhs_scalar_ty,13735 rt_rhs_scalar_ty,
13727 @min(try rhs_val.getUnsignedIntSema(pt) orelse bit_count, bit_count),13736 @min(try rhs_val.getUnsignedIntSema(pt) orelse bit_count, bit_count),
13728 )).toIntern();13737 );
13729 const rhs_len = rhs_ty.vectorLen(zcu);13738 const rhs_len = rhs_ty.vectorLen(zcu);
13730 const rhs_elems = try sema.arena.alloc(InternPool.Index, rhs_len);13739 const rhs_elems = try sema.arena.alloc(InternPool.Index, rhs_len);
13731 for (rhs_elems, 0..) |*rhs_elem, i| rhs_elem.* = (try pt.intValue(13740 for (rhs_elems, 0..) |*rhs_elem, i| rhs_elem.* = (try pt.intValue(
13732 rt_rhs_scalar_ty,13741 rt_rhs_scalar_ty,
13733 @min(try (try rhs_val.elemValue(pt, i)).getUnsignedIntSema(pt) orelse bit_count, bit_count),13742 @min(try (try rhs_val.elemValue(pt, i)).getUnsignedIntSema(pt) orelse bit_count, bit_count),
13734 )).toIntern();13743 )).toIntern();
13735 break :rt_rhs (try pt.aggregateValue(try pt.vectorType(.{13744 break :rt_rhs try pt.aggregateValue(try pt.vectorType(.{
13736 .len = rhs_len,13745 .len = rhs_len,
13737 .child = rt_rhs_scalar_ty.toIntern(),13746 .child = rt_rhs_scalar_ty.toIntern(),
13738 }), rhs_elems)).toIntern();13747 }), rhs_elems);
13739 }) else rhs,13748 }) else rhs,
13740 };13749 };
1374113750
...@@ -13760,7 +13769,7 @@ fn zirShl(...@@ -13760,7 +13769,7 @@ fn zirShl(
13760 const op_ov = try block.addInst(.{13769 const op_ov = try block.addInst(.{
13761 .tag = .shl_with_overflow,13770 .tag = .shl_with_overflow,
13762 .data = .{ .ty_pl = .{13771 .data = .{ .ty_pl = .{
13763 .ty = Air.internedToRef(op_ov_tuple_ty.toIntern()),13772 .ty = .fromIntern(op_ov_tuple_ty.toIntern()),
13764 .payload = try sema.addExtra(Air.Bin{13773 .payload = try sema.addExtra(Air.Bin{
13765 .lhs = lhs,13774 .lhs = lhs,
13766 .rhs = rhs,13775 .rhs = rhs,
...@@ -13820,21 +13829,23 @@ fn zirShr(...@@ -13820,21 +13829,23 @@ fn zirShr(
13820 const runtime_src = rs: {13829 const runtime_src = rs: {
13821 if (maybe_rhs_val) |rhs_val| {13830 if (maybe_rhs_val) |rhs_val| {
13822 if (maybe_lhs_val) |lhs_val| {13831 if (maybe_lhs_val) |lhs_val| {
13823 return Air.internedToRef((try arith.shr(sema, block, lhs_ty, rhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, switch (air_tag) {13832 return .fromValue(try arith.shr(sema, block, lhs_ty, rhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, switch (air_tag) {
13824 .shr => .shr,13833 .shr => .shr,
13825 .shr_exact => .shr_exact,13834 .shr_exact => .shr_exact,
13826 else => unreachable,13835 else => unreachable,
13827 })).toIntern());13836 }));
13828 }13837 }
13829 if (rhs_val.isUndef(zcu)) {13838 if (rhs_val.isUndef(zcu)) {
13830 return sema.failWithUseOfUndef(block, rhs_src, null);13839 return sema.failWithUseOfUndef(block, rhs_src, null);
13831 }13840 }
13832 const bits_val = try pt.intValue(.comptime_int, scalar_ty.intInfo(zcu).bits);13841 const bits = scalar_ty.intInfo(zcu).bits;
13833 switch (rhs_ty.zigTypeTag(zcu)) {13842 switch (rhs_ty.zigTypeTag(zcu)) {
13834 .int, .comptime_int => {13843 .int, .comptime_int => {
13835 switch (try rhs_val.orderAgainstZeroSema(pt)) {13844 switch (try rhs_val.orderAgainstZeroSema(pt)) {
13836 .gt => {13845 .gt => {
13837 if (try rhs_val.compareHeteroSema(.gte, bits_val, pt)) {13846 var rhs_space: Value.BigIntSpace = undefined;
13847 const rhs_bigint = try rhs_val.toBigIntSema(&rhs_space, pt);
13848 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
13838 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);13849 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
13839 }13850 }
13840 },13851 },
...@@ -13844,16 +13855,17 @@ fn zirShr(...@@ -13844,16 +13855,17 @@ fn zirShr(
13844 },13855 },
13845 .vector => {13856 .vector => {
13846 var any_positive: bool = false;13857 var any_positive: bool = false;
13847 var elem_idx: usize = 0;13858 for (0..rhs_ty.vectorLen(zcu)) |elem_idx| {
13848 while (elem_idx < rhs_ty.vectorLen(zcu)) : (elem_idx += 1) {
13849 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);13859 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
13850 if (rhs_elem.isUndef(zcu)) {13860 if (rhs_elem.isUndef(zcu)) {
13851 return sema.failWithUseOfUndef(block, rhs_src, elem_idx);13861 return sema.failWithUseOfUndef(block, rhs_src, elem_idx);
13852 }13862 }
13853 switch (try rhs_elem.orderAgainstZeroSema(pt)) {13863 switch (try rhs_elem.orderAgainstZeroSema(pt)) {
13854 .gt => {13864 .gt => {
13855 if (try rhs_elem.compareHeteroSema(.gte, bits_val, pt)) {13865 var rhs_elem_space: Value.BigIntSpace = undefined;
13856 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, elem_idx);13866 const rhs_elem_bigint = try rhs_elem.toBigIntSema(&rhs_elem_space, pt);
13867 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
13868 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
13857 }13869 }
13858 any_positive = true;13870 any_positive = true;
13859 },13871 },
...@@ -22718,7 +22730,6 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -22718,7 +22730,6 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
22718 const pt = sema.pt;22730 const pt = sema.pt;
22719 const zcu = pt.zcu;22731 const zcu = pt.zcu;
22720 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;22732 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22721 const src = block.nodeOffset(inst_data.src_node);
22722 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);22733 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
22723 const operand = try sema.resolveInst(inst_data.operand);22734 const operand = try sema.resolveInst(inst_data.operand);
22724 const operand_ty = sema.typeOf(operand);22735 const operand_ty = sema.typeOf(operand);
...@@ -22733,30 +22744,27 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -22733,30 +22744,27 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
22733 );22744 );
22734 }22745 }
22735 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {22746 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22736 return Air.internedToRef(val.toIntern());22747 return .fromValue(val);
22737 }22748 }
22738 if (try sema.resolveValue(operand)) |operand_val| {22749 if (try sema.resolveValue(operand)) |operand_val| {
22739 return Air.internedToRef((try arith.byteSwap(sema, operand_val, operand_ty)).toIntern());22750 return .fromValue(try arith.byteSwap(sema, operand_val, operand_ty));
22740 }22751 }
22741 try sema.requireRuntimeBlock(block, src, operand_src);
22742 return block.addTyOp(.byte_swap, operand_ty, operand);22752 return block.addTyOp(.byte_swap, operand_ty, operand);
22743}22753}
2274422754
22745fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {22755fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
22746 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;22756 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22747 const src = block.nodeOffset(inst_data.src_node);
22748 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);22757 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
22749 const operand = try sema.resolveInst(inst_data.operand);22758 const operand = try sema.resolveInst(inst_data.operand);
22750 const operand_ty = sema.typeOf(operand);22759 const operand_ty = sema.typeOf(operand);
22751 _ = try sema.checkIntOrVector(block, operand, operand_src);22760 _ = try sema.checkIntOrVector(block, operand, operand_src);
2275222761
22753 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {22762 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22754 return Air.internedToRef(val.toIntern());22763 return .fromValue(val);
22755 }22764 }
22756 if (try sema.resolveValue(operand)) |operand_val| {22765 if (try sema.resolveValue(operand)) |operand_val| {
22757 return Air.internedToRef((try arith.bitReverse(sema, operand_val, operand_ty)).toIntern());22766 return .fromValue(try arith.bitReverse(sema, operand_val, operand_ty));
22758 }22767 }
22759 try sema.requireRuntimeBlock(block, src, operand_src);
22760 return block.addTyOp(.bit_reverse, operand_ty, operand);22768 return block.addTyOp(.bit_reverse, operand_ty, operand);
22761}22769}
2276222770
src/Sema/arith.zig+14-61
...@@ -319,16 +319,7 @@ pub fn add(...@@ -319,16 +319,7 @@ pub fn add(
319 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);319 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
320 result_elem.* = (try addScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();320 result_elem.* = (try addScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();
321 }321 }
322322 return pt.aggregateValue(ty, elem_vals);
323 if (is_int) {
324 const result_val = try pt.intern(.{ .aggregate = .{
325 .ty = ty.toIntern(),
326 .storage = .{ .elems = elem_vals },
327 } });
328 return .fromInterned(result_val);
329 } else {
330 return pt.aggregateValue(ty, elem_vals);
331 }
332 },323 },
333 else => unreachable,324 else => unreachable,
334 }325 }
...@@ -482,16 +473,7 @@ pub fn sub(...@@ -482,16 +473,7 @@ pub fn sub(
482 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);473 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
483 result_elem.* = (try subScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();474 result_elem.* = (try subScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();
484 }475 }
485476 return pt.aggregateValue(ty, elem_vals);
486 if (is_int) {
487 const result_val = try pt.intern(.{ .aggregate = .{
488 .ty = ty.toIntern(),
489 .storage = .{ .elems = elem_vals },
490 } });
491 return .fromInterned(result_val);
492 } else {
493 return pt.aggregateValue(ty, elem_vals);
494 }
495 },477 },
496 else => unreachable,478 else => unreachable,
497 }479 }
...@@ -654,16 +636,7 @@ pub fn mul(...@@ -654,16 +636,7 @@ pub fn mul(
654 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);636 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
655 result_elem.* = (try mulScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();637 result_elem.* = (try mulScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();
656 }638 }
657639 return pt.aggregateValue(ty, elem_vals);
658 if (is_int) {
659 const result_val = try pt.intern(.{ .aggregate = .{
660 .ty = ty.toIntern(),
661 .storage = .{ .elems = elem_vals },
662 } });
663 return .fromInterned(result_val);
664 } else {
665 return pt.aggregateValue(ty, elem_vals);
666 }
667 },640 },
668 else => unreachable,641 else => unreachable,
669 }642 }
...@@ -829,16 +802,7 @@ pub fn div(...@@ -829,16 +802,7 @@ pub fn div(
829 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);802 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
830 result_elem.* = (try divScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, op, is_int, elem_idx)).toIntern();803 result_elem.* = (try divScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, op, is_int, elem_idx)).toIntern();
831 }804 }
832805 return pt.aggregateValue(ty, elem_vals);
833 if (is_int) {
834 const result_val = try pt.intern(.{ .aggregate = .{
835 .ty = ty.toIntern(),
836 .storage = .{ .elems = elem_vals },
837 } });
838 return .fromInterned(result_val);
839 } else {
840 return pt.aggregateValue(ty, elem_vals);
841 }
842 },806 },
843 else => unreachable,807 else => unreachable,
844 }808 }
...@@ -998,13 +962,14 @@ pub const ShlOp = enum { shl, shl_sat, shl_exact };...@@ -998,13 +962,14 @@ pub const ShlOp = enum { shl, shl_sat, shl_exact };
998962
999/// Applies the `<<` operator to comptime-known values.963/// Applies the `<<` operator to comptime-known values.
1000/// `lhs_ty` is an int, comptime_int, or vector thereof.964/// `lhs_ty` is an int, comptime_int, or vector thereof.
1001/// If it is a vector, he type of `rhs` has to also be a vector of the same length.965/// If it is a vector, the type of `rhs` has to also be a vector of the same length.
1002pub fn shl(966pub fn shl(
1003 sema: *Sema,967 sema: *Sema,
1004 block: *Block,968 block: *Block,
1005 lhs_ty: Type,969 lhs_ty: Type,
1006 lhs_val: Value,970 lhs_val: Value,
1007 rhs_val: Value,971 rhs_val: Value,
972 src: LazySrcLoc,
1008 lhs_src: LazySrcLoc,973 lhs_src: LazySrcLoc,
1009 rhs_src: LazySrcLoc,974 rhs_src: LazySrcLoc,
1010 op: ShlOp,975 op: ShlOp,
...@@ -1012,7 +977,7 @@ pub fn shl(...@@ -1012,7 +977,7 @@ pub fn shl(
1012 const pt = sema.pt;977 const pt = sema.pt;
1013 const zcu = pt.zcu;978 const zcu = pt.zcu;
1014 switch (lhs_ty.zigTypeTag(zcu)) {979 switch (lhs_ty.zigTypeTag(zcu)) {
1015 .int, .comptime_int => return shlScalar(sema, block, lhs_ty, lhs_val, rhs_val, lhs_src, rhs_src, op, null),980 .int, .comptime_int => return shlScalar(sema, block, lhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, op, null),
1016 .vector => {981 .vector => {
1017 const lhs_elem_ty = lhs_ty.childType(zcu);982 const lhs_elem_ty = lhs_ty.childType(zcu);
1018 const len = lhs_ty.vectorLen(zcu);983 const len = lhs_ty.vectorLen(zcu);
...@@ -1021,22 +986,15 @@ pub fn shl(...@@ -1021,22 +986,15 @@ pub fn shl(
1021 for (elem_vals, 0..) |*result_elem, elem_idx| {986 for (elem_vals, 0..) |*result_elem, elem_idx| {
1022 const lhs_elem = try lhs_val.elemValue(pt, elem_idx);987 const lhs_elem = try lhs_val.elemValue(pt, elem_idx);
1023 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);988 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
1024 result_elem.* = (try shlScalar(sema, block, lhs_elem_ty, lhs_elem, rhs_elem, lhs_src, rhs_src, op, elem_idx)).toIntern();989 result_elem.* = (try shlScalar(sema, block, lhs_elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, op, elem_idx)).toIntern();
1025 }
1026 if (op == .shl_sat) {
1027 return pt.aggregateValue(lhs_ty, elem_vals);
1028 } else {
1029 return .fromInterned(try pt.intern(.{ .aggregate = .{
1030 .ty = lhs_ty.toIntern(),
1031 .storage = .{ .elems = elem_vals },
1032 } }));
1033 }990 }
991 return pt.aggregateValue(lhs_ty, elem_vals);
1034 },992 },
1035 else => unreachable,993 else => unreachable,
1036 }994 }
1037}995}
1038/// `lhs_ty` is an int, comptime_int, or vector thereof.996/// `lhs_ty` is an int, comptime_int, or vector thereof.
1039/// If it is a vector, he type of `rhs` has to also be a vector of the same length.997/// If it is a vector, the type of `rhs` has to also be a vector of the same length.
1040pub fn shlWithOverflow(998pub fn shlWithOverflow(
1041 sema: *Sema,999 sema: *Sema,
1042 block: *Block,1000 block: *Block,
...@@ -1084,6 +1042,7 @@ fn shlScalar(...@@ -1084,6 +1042,7 @@ fn shlScalar(
1084 lhs_ty: Type,1042 lhs_ty: Type,
1085 lhs_val: Value,1043 lhs_val: Value,
1086 rhs_val: Value,1044 rhs_val: Value,
1045 src: LazySrcLoc,
1087 lhs_src: LazySrcLoc,1046 lhs_src: LazySrcLoc,
1088 rhs_src: LazySrcLoc,1047 rhs_src: LazySrcLoc,
1089 op: ShlOp,1048 op: ShlOp,
...@@ -1114,7 +1073,7 @@ fn shlScalar(...@@ -1114,7 +1073,7 @@ fn shlScalar(
1114 .shl_exact => {1073 .shl_exact => {
1115 const shifted = try intShlWithOverflow(sema, block, lhs_ty, lhs_val, rhs_val, rhs_src, false, vec_idx);1074 const shifted = try intShlWithOverflow(sema, block, lhs_ty, lhs_val, rhs_val, rhs_src, false, vec_idx);
1116 if (shifted.overflow) {1075 if (shifted.overflow) {
1117 return sema.failWithIntegerOverflow(block, lhs_src, lhs_ty, shifted.val, vec_idx);1076 return sema.failWithIntegerOverflow(block, src, lhs_ty, shifted.val, vec_idx);
1118 }1077 }
1119 return shifted.val;1078 return shifted.val;
1120 },1079 },
...@@ -1164,7 +1123,7 @@ pub const ShrOp = enum { shr, shr_exact };...@@ -1164,7 +1123,7 @@ pub const ShrOp = enum { shr, shr_exact };
11641123
1165/// Applies the `>>` operator to comptime-known values.1124/// Applies the `>>` operator to comptime-known values.
1166/// `lhs_ty` is an int, comptime_int, or vector thereof.1125/// `lhs_ty` is an int, comptime_int, or vector thereof.
1167/// If it is a vector, he type of `rhs` has to also be a vector of the same length.1126/// If it is a vector, the type of `rhs` has to also be a vector of the same length.
1168pub fn shr(1127pub fn shr(
1169 sema: *Sema,1128 sema: *Sema,
1170 block: *Block,1129 block: *Block,
...@@ -1193,13 +1152,7 @@ pub fn shr(...@@ -1193,13 +1152,7 @@ pub fn shr(
1193 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);1152 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
1194 result_elem.* = (try shrScalar(sema, block, lhs_elem_ty, rhs_elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, op, elem_idx)).toIntern();1153 result_elem.* = (try shrScalar(sema, block, lhs_elem_ty, rhs_elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, op, elem_idx)).toIntern();
1195 }1154 }
1196 switch (op) {1155 return pt.aggregateValue(lhs_ty, elem_vals);
1197 .shr => return pt.aggregateValue(lhs_ty, elem_vals),
1198 .shr_exact => return .fromInterned(try pt.intern(.{ .aggregate = .{
1199 .ty = lhs_ty.toIntern(),
1200 .storage = .{ .elems = elem_vals },
1201 } })),
1202 }
1203 },1156 },
1204 else => unreachable,1157 else => unreachable,
1205 }1158 }
src/Zcu/PerThread.zig+1-1
...@@ -3675,7 +3675,7 @@ pub fn unionValue(pt: Zcu.PerThread, union_ty: Type, tag: Value, val: Value) All...@@ -3675,7 +3675,7 @@ pub fn unionValue(pt: Zcu.PerThread, union_ty: Type, tag: Value, val: Value) All
3675pub fn aggregateValue(pt: Zcu.PerThread, ty: Type, elems: []const InternPool.Index) Allocator.Error!Value {3675pub fn aggregateValue(pt: Zcu.PerThread, ty: Type, elems: []const InternPool.Index) Allocator.Error!Value {
3676 for (elems) |elem| {3676 for (elems) |elem| {
3677 if (!Value.fromInterned(elem).isUndef(pt.zcu)) break;3677 if (!Value.fromInterned(elem).isUndef(pt.zcu)) break;
3678 } else { // all-undef3678 } else if (elems.len > 0) { // all-undef
3679 return pt.undefValue(ty);3679 return pt.undefValue(ty);
3680 }3680 }
3681 return .fromInterned(try pt.intern(.{ .aggregate = .{3681 return .fromInterned(try pt.intern(.{ .aggregate = .{
test/cases/compile_errors/shift_by_larger_than_usize.zig-1
...@@ -4,7 +4,6 @@ export fn f() usize {...@@ -4,7 +4,6 @@ export fn f() usize {
4}4}
55
6// error6// error
7// backend=stage2,llvm
8// target=x86_64-linux7// target=x86_64-linux
9//8//
10// :2:30: error: this implementation only supports comptime shift amounts of up to 2^64 - 1 bits9// :2:30: error: this implementation only supports comptime shift amounts of up to 2^64 - 1 bits
test/cases/compile_errors/shlExact_shifts_out_1_bits.zig+1-1
...@@ -7,4 +7,4 @@ comptime {...@@ -7,4 +7,4 @@ comptime {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :2:25: error: overflow of integer type 'u8' with value '340'10// :2:15: error: overflow of integer type 'u8' with value '340'