| ... | ... | @@ -11917,6 +11917,47 @@ fn analyzeArithmetic( |
| 11917 | 11917 | }, |
| 11918 | 11918 | else => {}, |
| 11919 | 11919 | } |
| 11920 | if (rs.air_tag == .div_exact) { |
| 11921 | const result = try block.addBinOp(.div_exact, casted_lhs, casted_rhs); |
| 11922 | const ok = if (scalar_tag == .Float) ok: { |
| 11923 | const floored = try block.addUnOp(.floor, result); |
| 11924 | |
| 11925 | if (resolved_type.zigTypeTag() == .Vector) { |
| 11926 | const eql = try block.addCmpVector(result, floored, .eq, try sema.addType(resolved_type)); |
| 11927 | break :ok try block.addInst(.{ |
| 11928 | .tag = .reduce, |
| 11929 | .data = .{ .reduce = .{ |
| 11930 | .operand = eql, |
| 11931 | .operation = .And, |
| 11932 | } }, |
| 11933 | }); |
| 11934 | } else { |
| 11935 | const is_in_range = try block.addBinOp(.cmp_eq, result, floored); |
| 11936 | break :ok is_in_range; |
| 11937 | } |
| 11938 | } else ok: { |
| 11939 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); |
| 11940 | |
| 11941 | if (resolved_type.zigTypeTag() == .Vector) { |
| 11942 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); |
| 11943 | const zero = try sema.addConstant(sema.typeOf(casted_rhs), zero_val); |
| 11944 | const eql = try block.addCmpVector(remainder, zero, .eq, try sema.addType(resolved_type)); |
| 11945 | break :ok try block.addInst(.{ |
| 11946 | .tag = .reduce, |
| 11947 | .data = .{ .reduce = .{ |
| 11948 | .operand = eql, |
| 11949 | .operation = .And, |
| 11950 | } }, |
| 11951 | }); |
| 11952 | } else { |
| 11953 | const zero = try sema.addConstant(sema.typeOf(casted_rhs), Value.zero); |
| 11954 | const is_in_range = try block.addBinOp(.cmp_eq, remainder, zero); |
| 11955 | break :ok is_in_range; |
| 11956 | } |
| 11957 | }; |
| 11958 | try sema.addSafetyCheck(block, ok, .exact_division_remainder); |
| 11959 | return result; |
| 11960 | } |
| 11920 | 11961 | } |
| 11921 | 11962 | return block.addBinOp(rs.air_tag, casted_lhs, casted_rhs); |
| 11922 | 11963 | } |
| ... | ... | @@ -18856,6 +18897,7 @@ pub const PanicId = enum { |
| 18856 | 18897 | shr_overflow, |
| 18857 | 18898 | divide_by_zero, |
| 18858 | 18899 | remainder_division_zero_negative, |
| 18900 | exact_division_remainder, |
| 18859 | 18901 | }; |
| 18860 | 18902 | |
| 18861 | 18903 | fn addSafetyCheck( |
| ... | ... | @@ -19077,6 +19119,7 @@ fn safetyPanic( |
| 19077 | 19119 | .shr_overflow => "right shift overflowed bits", |
| 19078 | 19120 | .divide_by_zero => "division by zero", |
| 19079 | 19121 | .remainder_division_zero_negative => "remainder division by zero or negative value", |
| 19122 | .exact_division_remainder => "exact division produced remainder", |
| 19080 | 19123 | }; |
| 19081 | 19124 | |
| 19082 | 19125 | const msg_inst = msg_inst: { |