| ... | ... | @@ -9996,40 +9996,34 @@ fn zirShl( |
| 9996 | 9996 | } else rhs; |
| 9997 | 9997 | |
| 9998 | 9998 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 9999 | | if (block.wantSafety()) { |
| 10000 | | const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) { |
| 10001 | | .shl_exact => .shl_with_overflow, |
| 10002 | | else => null, |
| 10003 | | }; |
| 10004 | | if (maybe_op_ov) |op_ov_tag| { |
| 10005 | | const op_ov_tuple_ty = try sema.overflowArithmeticTupleType(lhs_ty); |
| 10006 | | const op_ov = try block.addInst(.{ |
| 10007 | | .tag = op_ov_tag, |
| 10008 | | .data = .{ .ty_pl = .{ |
| 10009 | | .ty = try sema.addType(op_ov_tuple_ty), |
| 10010 | | .payload = try sema.addExtra(Air.Bin{ |
| 10011 | | .lhs = lhs, |
| 10012 | | .rhs = rhs, |
| 10013 | | }), |
| 9999 | if (block.wantSafety() and air_tag == .shl_exact) { |
| 10000 | const op_ov_tuple_ty = try sema.overflowArithmeticTupleType(lhs_ty); |
| 10001 | const op_ov = try block.addInst(.{ |
| 10002 | .tag = .shl_with_overflow, |
| 10003 | .data = .{ .ty_pl = .{ |
| 10004 | .ty = try sema.addType(op_ov_tuple_ty), |
| 10005 | .payload = try sema.addExtra(Air.Bin{ |
| 10006 | .lhs = lhs, |
| 10007 | .rhs = rhs, |
| 10008 | }), |
| 10009 | } }, |
| 10010 | }); |
| 10011 | const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty); |
| 10012 | const any_ov_bit = if (lhs_ty.zigTypeTag() == .Vector) |
| 10013 | try block.addInst(.{ |
| 10014 | .tag = .reduce, |
| 10015 | .data = .{ .reduce = .{ |
| 10016 | .operand = ov_bit, |
| 10017 | .operation = .Or, |
| 10014 | 10018 | } }, |
| 10015 | | }); |
| 10016 | | const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty); |
| 10017 | | const any_ov_bit = if (lhs_ty.zigTypeTag() == .Vector) |
| 10018 | | try block.addInst(.{ |
| 10019 | | .tag = .reduce, |
| 10020 | | .data = .{ .reduce = .{ |
| 10021 | | .operand = ov_bit, |
| 10022 | | .operation = .Or, |
| 10023 | | } }, |
| 10024 | | }) |
| 10025 | | else |
| 10026 | | ov_bit; |
| 10027 | | const zero_ov = try sema.addConstant(Type.@"u1", Value.zero); |
| 10028 | | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); |
| 10019 | }) |
| 10020 | else |
| 10021 | ov_bit; |
| 10022 | const zero_ov = try sema.addConstant(Type.@"u1", Value.zero); |
| 10023 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); |
| 10029 | 10024 | |
| 10030 | | try sema.addSafetyCheck(block, no_ov, .shl_overflow); |
| 10031 | | return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty); |
| 10032 | | } |
| 10025 | try sema.addSafetyCheck(block, no_ov, .shl_overflow); |
| 10026 | return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty); |
| 10033 | 10027 | } |
| 10034 | 10028 | return block.addBinOp(air_tag, lhs, new_rhs); |
| 10035 | 10029 | } |
| ... | ... | @@ -10107,7 +10101,23 @@ fn zirShr( |
| 10107 | 10101 | } else rhs_src; |
| 10108 | 10102 | |
| 10109 | 10103 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 10110 | | return block.addBinOp(air_tag, lhs, rhs); |
| 10104 | const result = try block.addBinOp(air_tag, lhs, rhs); |
| 10105 | if (block.wantSafety() and air_tag == .shr_exact) { |
| 10106 | const back = try block.addBinOp(.shl, result, rhs); |
| 10107 | |
| 10108 | const ok = if (rhs_ty.zigTypeTag() == .Vector) ok: { |
| 10109 | const eql = try block.addCmpVector(lhs, back, .eq, try sema.addType(rhs_ty)); |
| 10110 | break :ok try block.addInst(.{ |
| 10111 | .tag = .reduce, |
| 10112 | .data = .{ .reduce = .{ |
| 10113 | .operand = eql, |
| 10114 | .operation = .And, |
| 10115 | } }, |
| 10116 | }); |
| 10117 | } else try block.addBinOp(.cmp_eq, lhs, back); |
| 10118 | try sema.addSafetyCheck(block, ok, .shr_overflow); |
| 10119 | } |
| 10120 | return result; |
| 10111 | 10121 | } |
| 10112 | 10122 | |
| 10113 | 10123 | fn zirBitwise( |
| ... | ... | @@ -18802,6 +18812,7 @@ pub const PanicId = enum { |
| 18802 | 18812 | cast_truncated_data, |
| 18803 | 18813 | integer_overflow, |
| 18804 | 18814 | shl_overflow, |
| 18815 | shr_overflow, |
| 18805 | 18816 | }; |
| 18806 | 18817 | |
| 18807 | 18818 | fn addSafetyCheck( |
| ... | ... | @@ -19019,6 +19030,7 @@ fn safetyPanic( |
| 19019 | 19030 | .cast_truncated_data => "integer cast truncated bits", |
| 19020 | 19031 | .integer_overflow => "integer overflow", |
| 19021 | 19032 | .shl_overflow => "left shift overflowed bits", |
| 19033 | .shr_overflow => "right shift overflowed bits", |
| 19022 | 19034 | }; |
| 19023 | 19035 | |
| 19024 | 19036 | const msg_inst = msg_inst: { |