Skip to content

Commit abce8c5

Browse files
committed
Remove Rvalue::CheckedBinaryOp
1 parent ee97564 commit abce8c5

File tree

58 files changed

+207
-193
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+207
-193
lines changed

compiler/rustc_borrowck/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1312,8 +1312,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
13121312
);
13131313
}
13141314

1315-
Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
1316-
| Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
1315+
Rvalue::BinaryOp(_bin_op, box (operand1, operand2)) => {
13171316
self.consume_operand(location, (operand1, span), flow_state);
13181317
self.consume_operand(location, (operand2, span), flow_state);
13191318
}

compiler/rustc_borrowck/src/polonius/loan_invalidations.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,7 @@ impl<'cx, 'tcx> LoanInvalidationsGenerator<'cx, 'tcx> {
302302
);
303303
}
304304

305-
Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
306-
| Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
305+
Rvalue::BinaryOp(_bin_op, box (operand1, operand2)) => {
307306
self.consume_operand(location, operand1);
308307
self.consume_operand(location, operand2);
309308
}

compiler/rustc_borrowck/src/type_check/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -2417,8 +2417,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24172417
self.check_operand(op, location);
24182418
}
24192419

2420-
Rvalue::BinaryOp(_, box (left, right))
2421-
| Rvalue::CheckedBinaryOp(_, box (left, right)) => {
2420+
Rvalue::BinaryOp(_, box (left, right)) => {
24222421
self.check_operand(left, location);
24232422
self.check_operand(right, location);
24242423
}
@@ -2445,7 +2444,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24452444
| Rvalue::Cast(..)
24462445
| Rvalue::ShallowInitBox(..)
24472446
| Rvalue::BinaryOp(..)
2448-
| Rvalue::CheckedBinaryOp(..)
24492447
| Rvalue::NullaryOp(..)
24502448
| Rvalue::CopyForDeref(..)
24512449
| Rvalue::UnaryOp(..)

compiler/rustc_codegen_cranelift/src/base.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -576,14 +576,11 @@ fn codegen_stmt<'tcx>(
576576
let lhs = codegen_operand(fx, &lhs_rhs.0);
577577
let rhs = codegen_operand(fx, &lhs_rhs.1);
578578

579-
let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs);
580-
lval.write_cvalue(fx, res);
581-
}
582-
Rvalue::CheckedBinaryOp(bin_op, ref lhs_rhs) => {
583-
let lhs = codegen_operand(fx, &lhs_rhs.0);
584-
let rhs = codegen_operand(fx, &lhs_rhs.1);
585-
586-
let res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);
579+
let res = if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
580+
crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs)
581+
} else {
582+
crate::num::codegen_binop(fx, bin_op, lhs, rhs)
583+
};
587584
lval.write_cvalue(fx, res);
588585
}
589586
Rvalue::UnaryOp(un_op, ref operand) => {

compiler/rustc_codegen_cranelift/src/codegen_i128.rs

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pub(crate) fn maybe_codegen<'tcx>(
7070
}
7171
BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne | BinOp::Cmp => None,
7272
BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked => None,
73+
BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(),
7374
}
7475
}
7576

@@ -132,6 +133,7 @@ pub(crate) fn maybe_codegen_checked<'tcx>(
132133
Some(out_place.to_cvalue(fx))
133134
}
134135
BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(),
136+
BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(),
135137
BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"),
136138
BinOp::Div | BinOp::Rem => unreachable!(),
137139
BinOp::Cmp => unreachable!(),

compiler/rustc_codegen_cranelift/src/num.rs

+3
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ pub(crate) fn codegen_int_binop<'tcx>(
179179
}
180180
}
181181
BinOp::Offset => unreachable!("Offset is not an integer operation"),
182+
BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => {
183+
unreachable!("Overflow binops handled by `codegen_checked_int_binop`")
184+
}
182185
// Compare binops handles by `codegen_binop`.
183186
BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge | BinOp::Cmp => {
184187
unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty);

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+22-16
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
572572
}
573573
}
574574

575+
mir::Rvalue::BinaryOp(op_with_overflow, box (ref lhs, ref rhs))
576+
if let Some(op) = op_with_overflow.overflowing_to_wrapping() =>
577+
{
578+
let lhs = self.codegen_operand(bx, lhs);
579+
let rhs = self.codegen_operand(bx, rhs);
580+
let result = self.codegen_scalar_checked_binop(
581+
bx,
582+
op,
583+
lhs.immediate(),
584+
rhs.immediate(),
585+
lhs.layout.ty,
586+
);
587+
let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty);
588+
let operand_ty = Ty::new_tup(bx.tcx(), &[val_ty, bx.tcx().types.bool]);
589+
OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) }
590+
}
575591
mir::Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) => {
576592
let lhs = self.codegen_operand(bx, lhs);
577593
let rhs = self.codegen_operand(bx, rhs);
@@ -600,20 +616,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
600616
layout: bx.cx().layout_of(op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty)),
601617
}
602618
}
603-
mir::Rvalue::CheckedBinaryOp(op, box (ref lhs, ref rhs)) => {
604-
let lhs = self.codegen_operand(bx, lhs);
605-
let rhs = self.codegen_operand(bx, rhs);
606-
let result = self.codegen_scalar_checked_binop(
607-
bx,
608-
op,
609-
lhs.immediate(),
610-
rhs.immediate(),
611-
lhs.layout.ty,
612-
);
613-
let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty);
614-
let operand_ty = Ty::new_tup(bx.tcx(), &[val_ty, bx.tcx().types.bool]);
615-
OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) }
616-
}
617619

618620
mir::Rvalue::UnaryOp(op, ref operand) => {
619621
let operand = self.codegen_operand(bx, operand);
@@ -792,7 +794,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
792794
debug_assert!(
793795
if bx.cx().type_has_metadata(ty) {
794796
matches!(val, OperandValue::Pair(..))
795-
} else {
797+
} else {
796798
matches!(val, OperandValue::Immediate(..))
797799
},
798800
"Address of place was unexpectedly {val:?} for pointee type {ty:?}",
@@ -938,6 +940,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
938940
bx.select(is_lt, bx.cx().const_i8(Ordering::Less as i8), ge)
939941
}
940942
}
943+
mir::BinOp::AddWithOverflow
944+
| mir::BinOp::SubWithOverflow
945+
| mir::BinOp::MulWithOverflow => {
946+
bug!("{op:?} needs to return a pair, so call codegen_scalar_checked_binop instead")
947+
}
941948
}
942949
}
943950

@@ -1050,7 +1057,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10501057
mir::Rvalue::Cast(..) | // (*)
10511058
mir::Rvalue::ShallowInitBox(..) | // (*)
10521059
mir::Rvalue::BinaryOp(..) |
1053-
mir::Rvalue::CheckedBinaryOp(..) |
10541060
mir::Rvalue::UnaryOp(..) |
10551061
mir::Rvalue::Discriminant(..) |
10561062
mir::Rvalue::NullaryOp(..) |

compiler/rustc_const_eval/src/interpret/step.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
166166
let left = self.read_immediate(&self.eval_operand(left, layout)?)?;
167167
let layout = util::binop_right_homogeneous(bin_op).then_some(left.layout);
168168
let right = self.read_immediate(&self.eval_operand(right, layout)?)?;
169-
self.binop_ignore_overflow(bin_op, &left, &right, &dest)?;
170-
}
171-
172-
CheckedBinaryOp(bin_op, box (ref left, ref right)) => {
173-
// Due to the extra boolean in the result, we can never reuse the `dest.layout`.
174-
let left = self.read_immediate(&self.eval_operand(left, None)?)?;
175-
let layout = util::binop_right_homogeneous(bin_op).then_some(left.layout);
176-
let right = self.read_immediate(&self.eval_operand(right, layout)?)?;
177-
self.binop_with_overflow(bin_op, &left, &right, &dest)?;
169+
if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
170+
self.binop_with_overflow(bin_op, &left, &right, &dest)?;
171+
} else {
172+
self.binop_ignore_overflow(bin_op, &left, &right, &dest)?;
173+
}
178174
}
179175

180176
UnaryOp(un_op, ref operand) => {

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
579579
}
580580
}
581581

582-
Rvalue::BinaryOp(op, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(op, box (lhs, rhs)) => {
582+
Rvalue::BinaryOp(op, box (lhs, rhs)) => {
583583
let lhs_ty = lhs.ty(self.body, self.tcx);
584584
let rhs_ty = rhs.ty(self.body, self.tcx);
585585

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ where
260260
| Rvalue::Cast(_, operand, _)
261261
| Rvalue::ShallowInitBox(operand, _) => in_operand::<Q, _>(cx, in_local, operand),
262262

263-
Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
263+
Rvalue::BinaryOp(_, box (lhs, rhs)) => {
264264
in_operand::<Q, _>(cx, in_local, lhs) || in_operand::<Q, _>(cx, in_local, rhs)
265265
}
266266

compiler/rustc_const_eval/src/transform/check_consts/resolver.rs

-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ where
200200
| mir::Rvalue::Repeat(..)
201201
| mir::Rvalue::Len(..)
202202
| mir::Rvalue::BinaryOp(..)
203-
| mir::Rvalue::CheckedBinaryOp(..)
204203
| mir::Rvalue::NullaryOp(..)
205204
| mir::Rvalue::UnaryOp(..)
206205
| mir::Rvalue::Discriminant(..)

compiler/rustc_const_eval/src/transform/validate.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1064,14 +1064,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
10641064
)
10651065
}
10661066
}
1067-
}
1068-
}
1069-
Rvalue::CheckedBinaryOp(op, vals) => {
1070-
use BinOp::*;
1071-
let a = vals.0.ty(&self.body.local_decls, self.tcx);
1072-
let b = vals.1.ty(&self.body.local_decls, self.tcx);
1073-
match op {
1074-
Add | Sub | Mul => {
1067+
AddWithOverflow | SubWithOverflow | MulWithOverflow => {
10751068
for x in [a, b] {
10761069
check_kinds!(
10771070
x,
@@ -1088,7 +1081,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
10881081
);
10891082
}
10901083
}
1091-
_ => self.fail(location, format!("There is no checked version of {op:?}")),
10921084
}
10931085
}
10941086
Rvalue::UnaryOp(op, operand) => {

compiler/rustc_const_eval/src/util/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ pub fn binop_left_homogeneous(op: mir::BinOp) -> bool {
1919
match op {
2020
Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor
2121
| BitAnd | BitOr | Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => true,
22-
Eq | Ne | Lt | Le | Gt | Ge | Cmp => false,
22+
AddWithOverflow | SubWithOverflow | MulWithOverflow | Eq | Ne | Lt | Le | Gt | Ge | Cmp => {
23+
false
24+
}
2325
}
2426
}
2527

@@ -29,8 +31,9 @@ pub fn binop_left_homogeneous(op: mir::BinOp) -> bool {
2931
pub fn binop_right_homogeneous(op: mir::BinOp) -> bool {
3032
use rustc_middle::mir::BinOp::*;
3133
match op {
32-
Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor
33-
| BitAnd | BitOr | Eq | Ne | Lt | Le | Gt | Ge | Cmp => true,
34+
Add | AddUnchecked | AddWithOverflow | Sub | SubUnchecked | SubWithOverflow | Mul
35+
| MulUnchecked | MulWithOverflow | Div | Rem | BitXor | BitAnd | BitOr | Eq | Ne | Lt
36+
| Le | Gt | Ge | Cmp => true,
3437
Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => false,
3538
}
3639
}

compiler/rustc_middle/src/mir/pretty.rs

-3
Original file line numberDiff line numberDiff line change
@@ -971,9 +971,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
971971
with_no_trimmed_paths!(write!(fmt, "{place:?} as {ty} ({kind:?})"))
972972
}
973973
BinaryOp(ref op, box (ref a, ref b)) => write!(fmt, "{op:?}({a:?}, {b:?})"),
974-
CheckedBinaryOp(ref op, box (ref a, ref b)) => {
975-
write!(fmt, "Checked{op:?}({a:?}, {b:?})")
976-
}
977974
UnaryOp(ref op, ref a) => write!(fmt, "{op:?}({a:?})"),
978975
Discriminant(ref place) => write!(fmt, "discriminant({place:?})"),
979976
NullaryOp(ref op, ref t) => {

compiler/rustc_middle/src/mir/statement.rs

-1
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,6 @@ impl<'tcx> Rvalue<'tcx> {
438438
_,
439439
)
440440
| Rvalue::BinaryOp(_, _)
441-
| Rvalue::CheckedBinaryOp(_, _)
442441
| Rvalue::NullaryOp(_, _)
443442
| Rvalue::UnaryOp(_, _)
444443
| Rvalue::Discriminant(_)

compiler/rustc_middle/src/mir/syntax.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -1295,18 +1295,12 @@ pub enum Rvalue<'tcx> {
12951295
/// truncated as needed.
12961296
/// * The `Bit*` operations accept signed integers, unsigned integers, or bools with matching
12971297
/// types and return a value of that type.
1298+
/// * The `FooWithOverflow` are like the `Foo`, but returning `(T, bool)` instead of just `T`,
1299+
/// where the `bool` is true if the result is not equal to the infinite-precision result.
12981300
/// * The remaining operations accept signed integers, unsigned integers, or floats with
12991301
/// matching types and return a value of that type.
13001302
BinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
13011303

1302-
/// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition.
1303-
///
1304-
/// For addition, subtraction, and multiplication on integers the error condition is set when
1305-
/// the infinite precision result would not be equal to the actual result.
1306-
///
1307-
/// Other combinations of types and operators are unsupported.
1308-
CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
1309-
13101304
/// Computes a value as described by the operation.
13111305
NullaryOp(NullOp<'tcx>, Ty<'tcx>),
13121306

@@ -1449,14 +1443,23 @@ pub enum BinOp {
14491443
Add,
14501444
/// Like `Add`, but with UB on overflow. (Integers only.)
14511445
AddUnchecked,
1446+
/// Like `Add`, but returns `(T, bool)` of both the wrapped result
1447+
/// and a bool indicating that it overflowed.
1448+
AddWithOverflow,
14521449
/// The `-` operator (subtraction)
14531450
Sub,
14541451
/// Like `Sub`, but with UB on overflow. (Integers only.)
14551452
SubUnchecked,
1453+
/// Like `Sub`, but returns `(T, bool)` of both the wrapped result
1454+
/// and a bool indicating that it overflowed.
1455+
SubWithOverflow,
14561456
/// The `*` operator (multiplication)
14571457
Mul,
14581458
/// Like `Mul`, but with UB on overflow. (Integers only.)
14591459
MulUnchecked,
1460+
/// Like `Mul`, but returns `(T, bool)` of both the wrapped result
1461+
/// and a bool indicating that it overflowed.
1462+
MulWithOverflow,
14601463
/// The `/` operator (division)
14611464
///
14621465
/// For integer types, division by zero is UB, as is `MIN / -1` for signed.

compiler/rustc_middle/src/mir/tcx.rs

+28-6
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,6 @@ impl<'tcx> Rvalue<'tcx> {
179179
let rhs_ty = rhs.ty(local_decls, tcx);
180180
op.ty(tcx, lhs_ty, rhs_ty)
181181
}
182-
Rvalue::CheckedBinaryOp(op, box (ref lhs, ref rhs)) => {
183-
let lhs_ty = lhs.ty(local_decls, tcx);
184-
let rhs_ty = rhs.ty(local_decls, tcx);
185-
let ty = op.ty(tcx, lhs_ty, rhs_ty);
186-
Ty::new_tup(tcx, &[ty, tcx.types.bool])
187-
}
188182
Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
189183
Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
190184
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
@@ -263,6 +257,11 @@ impl<'tcx> BinOp {
263257
assert_eq!(lhs_ty, rhs_ty);
264258
lhs_ty
265259
}
260+
&BinOp::AddWithOverflow | &BinOp::SubWithOverflow | &BinOp::MulWithOverflow => {
261+
// these should be integers of the same size.
262+
assert_eq!(lhs_ty, rhs_ty);
263+
Ty::new_tup(tcx, &[lhs_ty, tcx.types.bool])
264+
}
266265
&BinOp::Shl
267266
| &BinOp::ShlUnchecked
268267
| &BinOp::Shr
@@ -315,6 +314,9 @@ impl BinOp {
315314
BinOp::Le => hir::BinOpKind::Le,
316315
BinOp::Ge => hir::BinOpKind::Ge,
317316
BinOp::Cmp
317+
| BinOp::AddWithOverflow
318+
| BinOp::SubWithOverflow
319+
| BinOp::MulWithOverflow
318320
| BinOp::AddUnchecked
319321
| BinOp::SubUnchecked
320322
| BinOp::MulUnchecked
@@ -325,4 +327,24 @@ impl BinOp {
325327
}
326328
}
327329
}
330+
331+
/// If this is a `FooWithOverflow`, return `Some(Foo)`.
332+
pub fn overflowing_to_wrapping(self) -> Option<BinOp> {
333+
Some(match self {
334+
BinOp::AddWithOverflow => BinOp::Add,
335+
BinOp::SubWithOverflow => BinOp::Sub,
336+
BinOp::MulWithOverflow => BinOp::Mul,
337+
_ => return None,
338+
})
339+
}
340+
341+
/// If this is a `Foo`, return `Some(FooWithOverflow)`.
342+
pub fn wrapping_to_overflowing(self) -> Option<BinOp> {
343+
Some(match self {
344+
BinOp::Add => BinOp::AddWithOverflow,
345+
BinOp::Sub => BinOp::SubWithOverflow,
346+
BinOp::Mul => BinOp::MulWithOverflow,
347+
_ => return None,
348+
})
349+
}
328350
}

compiler/rustc_middle/src/mir/visit.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,7 @@ macro_rules! make_mir_visitor {
696696
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
697697
}
698698

699-
Rvalue::BinaryOp(_bin_op, box(lhs, rhs))
700-
| Rvalue::CheckedBinaryOp(_bin_op, box(lhs, rhs)) => {
699+
Rvalue::BinaryOp(_bin_op, box(lhs, rhs)) => {
701700
self.visit_operand(lhs, location);
702701
self.visit_operand(rhs, location);
703702
}

0 commit comments

Comments
 (0)