Rollup merge of #125173 - scottmcm:never-checked, r=davidtwco
Remove `Rvalue::CheckedBinaryOp`
Zulip conversation: <438729996
>
cc `@RalfJung`
While it's a draft,
r? ghost
This commit is contained in:
commit
9987e900c0
61 changed files with 212 additions and 215 deletions
|
@ -165,7 +165,9 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Rvalue::CheckedBinaryOp(op, box (left, right)) => {
|
||||
Rvalue::BinaryOp(overflowing_op, box (left, right))
|
||||
if let Some(op) = overflowing_op.overflowing_to_wrapping() =>
|
||||
{
|
||||
// Flood everything now, so we can use `insert_value_idx` directly later.
|
||||
state.flood(target.as_ref(), self.map());
|
||||
|
||||
|
@ -175,7 +177,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
let overflow_target = self.map().apply(target, TrackElem::Field(1_u32.into()));
|
||||
|
||||
if value_target.is_some() || overflow_target.is_some() {
|
||||
let (val, overflow) = self.binary_op(state, *op, left, right);
|
||||
let (val, overflow) = self.binary_op(state, op, left, right);
|
||||
|
||||
if let Some(value_target) = value_target {
|
||||
// We have flooded `target` earlier.
|
||||
|
|
|
@ -564,7 +564,7 @@ impl WriteInfo {
|
|||
| Rvalue::ShallowInitBox(op, _) => {
|
||||
self.add_operand(op);
|
||||
}
|
||||
Rvalue::BinaryOp(_, ops) | Rvalue::CheckedBinaryOp(_, ops) => {
|
||||
Rvalue::BinaryOp(_, ops) => {
|
||||
for op in [&ops.0, &ops.1] {
|
||||
self.add_operand(op);
|
||||
}
|
||||
|
|
|
@ -831,23 +831,18 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
// on both operands for side effect.
|
||||
let lhs = lhs?;
|
||||
let rhs = rhs?;
|
||||
if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
|
||||
return Some(value);
|
||||
|
||||
if let Some(op) = op.overflowing_to_wrapping() {
|
||||
if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
|
||||
return Some(value);
|
||||
}
|
||||
Value::CheckedBinaryOp(op, lhs, rhs)
|
||||
} else {
|
||||
if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
|
||||
return Some(value);
|
||||
}
|
||||
Value::BinaryOp(op, lhs, rhs)
|
||||
}
|
||||
Value::BinaryOp(op, lhs, rhs)
|
||||
}
|
||||
Rvalue::CheckedBinaryOp(op, box (ref mut lhs, ref mut rhs)) => {
|
||||
let ty = lhs.ty(self.local_decls, self.tcx);
|
||||
let lhs = self.simplify_operand(lhs, location);
|
||||
let rhs = self.simplify_operand(rhs, location);
|
||||
// Only short-circuit options after we called `simplify_operand`
|
||||
// on both operands for side effect.
|
||||
let lhs = lhs?;
|
||||
let rhs = rhs?;
|
||||
if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
|
||||
return Some(value);
|
||||
}
|
||||
Value::CheckedBinaryOp(op, lhs, rhs)
|
||||
}
|
||||
Rvalue::UnaryOp(op, ref mut arg) => {
|
||||
let arg = self.simplify_operand(arg, location)?;
|
||||
|
|
|
@ -399,16 +399,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
}
|
||||
Rvalue::BinaryOp(op, box (left, right)) => {
|
||||
trace!("checking BinaryOp(op = {:?}, left = {:?}, right = {:?})", op, left, right);
|
||||
self.check_binary_op(*op, left, right, location)?;
|
||||
}
|
||||
Rvalue::CheckedBinaryOp(op, box (left, right)) => {
|
||||
trace!(
|
||||
"checking CheckedBinaryOp(op = {:?}, left = {:?}, right = {:?})",
|
||||
op,
|
||||
left,
|
||||
right
|
||||
);
|
||||
self.check_binary_op(*op, left, right, location)?;
|
||||
let op = op.overflowing_to_wrapping().unwrap_or(*op);
|
||||
self.check_binary_op(op, left, right, location)?;
|
||||
}
|
||||
|
||||
// Do not try creating references (#67862)
|
||||
|
@ -555,24 +547,18 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
let right = self.eval_operand(right)?;
|
||||
let right = self.use_ecx(|this| this.ecx.read_immediate(&right))?;
|
||||
|
||||
let val =
|
||||
self.use_ecx(|this| this.ecx.wrapping_binary_op(bin_op, &left, &right))?;
|
||||
val.into()
|
||||
}
|
||||
|
||||
CheckedBinaryOp(bin_op, box (ref left, ref right)) => {
|
||||
let left = self.eval_operand(left)?;
|
||||
let left = self.use_ecx(|this| this.ecx.read_immediate(&left))?;
|
||||
|
||||
let right = self.eval_operand(right)?;
|
||||
let right = self.use_ecx(|this| this.ecx.read_immediate(&right))?;
|
||||
|
||||
let (val, overflowed) =
|
||||
self.use_ecx(|this| this.ecx.overflowing_binary_op(bin_op, &left, &right))?;
|
||||
let overflowed = ImmTy::from_bool(overflowed, self.tcx);
|
||||
Value::Aggregate {
|
||||
variant: VariantIdx::ZERO,
|
||||
fields: [Value::from(val), overflowed.into()].into_iter().collect(),
|
||||
if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
|
||||
let (val, overflowed) =
|
||||
self.use_ecx(|this| this.ecx.overflowing_binary_op(bin_op, &left, &right))?;
|
||||
let overflowed = ImmTy::from_bool(overflowed, self.tcx);
|
||||
Value::Aggregate {
|
||||
variant: VariantIdx::ZERO,
|
||||
fields: [Value::from(val), overflowed.into()].into_iter().collect(),
|
||||
}
|
||||
} else {
|
||||
let val =
|
||||
self.use_ecx(|this| this.ecx.wrapping_binary_op(bin_op, &left, &right))?;
|
||||
val.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -140,16 +140,16 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
rhs = args.next().unwrap();
|
||||
}
|
||||
let bin_op = match intrinsic.name {
|
||||
sym::add_with_overflow => BinOp::Add,
|
||||
sym::sub_with_overflow => BinOp::Sub,
|
||||
sym::mul_with_overflow => BinOp::Mul,
|
||||
sym::add_with_overflow => BinOp::AddWithOverflow,
|
||||
sym::sub_with_overflow => BinOp::SubWithOverflow,
|
||||
sym::mul_with_overflow => BinOp::MulWithOverflow,
|
||||
_ => bug!("unexpected intrinsic"),
|
||||
};
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::CheckedBinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
|
||||
Rvalue::BinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
|
|
|
@ -470,7 +470,7 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
self.validate_operand(operand)?;
|
||||
}
|
||||
|
||||
Rvalue::BinaryOp(op, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(op, box (lhs, rhs)) => {
|
||||
Rvalue::BinaryOp(op, box (lhs, rhs)) => {
|
||||
let op = *op;
|
||||
let lhs_ty = lhs.ty(self.body, self.tcx);
|
||||
|
||||
|
@ -539,10 +539,13 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
| BinOp::Offset
|
||||
| BinOp::Add
|
||||
| BinOp::AddUnchecked
|
||||
| BinOp::AddWithOverflow
|
||||
| BinOp::Sub
|
||||
| BinOp::SubUnchecked
|
||||
| BinOp::SubWithOverflow
|
||||
| BinOp::Mul
|
||||
| BinOp::MulUnchecked
|
||||
| BinOp::MulWithOverflow
|
||||
| BinOp::BitXor
|
||||
| BinOp::BitAnd
|
||||
| BinOp::BitOr
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue