1
Fork 0

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:
Matthias Krüger 2024-05-20 18:13:48 +02:00 committed by GitHub
commit 9987e900c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
61 changed files with 212 additions and 215 deletions

View file

@ -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.

View file

@ -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);
}

View file

@ -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)?;

View file

@ -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()
}
}

View file

@ -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 };

View file

@ -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