Rollup merge of #112168 - scottmcm:lower-div-rem-unchecked-to-mir, r=oli-obk
Lower `unchecked_div`/`_rem` to MIR's `BinOp::Div`/`Rem` As described in <https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.BinOp.html#variant.Div>, the ordinary `BinOp`s for these are already UB for division by zero ([or overflow](https://llvm.org/docs/LangRef.html#sdiv-instruction), [demo](https://rust.godbolt.org/z/71e7P7Exh)), as MIR building is responsible for inserting code to panic for those cases regardless of whether the overflow checks are enabled. So we can lower these in the same arm that lowers `wrapping_add` to MIR `BinOp::Add` and such, as all these cases turn into ordinary `Rvalue::BinaryOp`s.
This commit is contained in:
@@ -82,30 +82,35 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
||||
drop(args);
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => {
|
||||
if let Some(target) = *target {
|
||||
let lhs;
|
||||
let rhs;
|
||||
{
|
||||
let mut args = args.drain(..);
|
||||
lhs = args.next().unwrap();
|
||||
rhs = args.next().unwrap();
|
||||
}
|
||||
let bin_op = match intrinsic_name {
|
||||
sym::wrapping_add => BinOp::Add,
|
||||
sym::wrapping_sub => BinOp::Sub,
|
||||
sym::wrapping_mul => BinOp::Mul,
|
||||
_ => bug!("unexpected intrinsic"),
|
||||
};
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::BinaryOp(bin_op, Box::new((lhs, rhs))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
sym::wrapping_add
|
||||
| sym::wrapping_sub
|
||||
| sym::wrapping_mul
|
||||
| sym::unchecked_div
|
||||
| sym::unchecked_rem => {
|
||||
let target = target.unwrap();
|
||||
let lhs;
|
||||
let rhs;
|
||||
{
|
||||
let mut args = args.drain(..);
|
||||
lhs = args.next().unwrap();
|
||||
rhs = args.next().unwrap();
|
||||
}
|
||||
let bin_op = match intrinsic_name {
|
||||
sym::wrapping_add => BinOp::Add,
|
||||
sym::wrapping_sub => BinOp::Sub,
|
||||
sym::wrapping_mul => BinOp::Mul,
|
||||
sym::unchecked_div => BinOp::Div,
|
||||
sym::unchecked_rem => BinOp::Rem,
|
||||
_ => bug!("unexpected intrinsic"),
|
||||
};
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::BinaryOp(bin_op, Box::new((lhs, rhs))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
|
||||
if let Some(target) = *target {
|
||||
|
||||
Reference in New Issue
Block a user