Auto merge of #107921 - cjgillot:codegen-overflow-check, r=tmiasko
Make codegen choose whether to emit overflow checks ConstProp and DataflowConstProp currently have a specific code path not to propagate constants when they overflow. This is meant to have the correct behaviour when inlining from a crate with overflow checks (like `core`) into a crate compiled without. This PR shifts the behaviour change to the `Assert(Overflow*)` MIR terminators: if the crate is compiled without overflow checks, just skip emitting the assertions. This is already what happens with `OverflowNeg`. This allows ConstProp and DataflowConstProp to transform `CheckedBinaryOp(Add, u8::MAX, 1)` into `const (0, true)`, and let codegen ignore the `true`. The interpreter is modified to conform to this behaviour. Fixes #35310
This commit is contained in:
commit
7aa413d592
24 changed files with 250 additions and 217 deletions
|
@ -563,11 +563,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
// with #[rustc_inherit_overflow_checks] and inlined from
|
||||
// another crate (mostly core::num generic/#[inline] fns),
|
||||
// while the current crate doesn't use overflow checks.
|
||||
// NOTE: Unlike binops, negation doesn't have its own
|
||||
// checked operation, just a comparison with the minimum
|
||||
// value, so we have to check for the assert message.
|
||||
if !bx.check_overflow() {
|
||||
if let AssertKind::OverflowNeg(_) = *msg {
|
||||
if !bx.cx().check_overflow() {
|
||||
let overflow_not_to_check = match msg {
|
||||
AssertKind::OverflowNeg(..) => true,
|
||||
AssertKind::Overflow(op, ..) => op.is_checkable(),
|
||||
_ => false,
|
||||
};
|
||||
if overflow_not_to_check {
|
||||
const_cond = Some(expected);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,9 +218,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
args[1].val.unaligned_volatile_store(bx, dst);
|
||||
return;
|
||||
}
|
||||
sym::add_with_overflow
|
||||
| sym::sub_with_overflow
|
||||
| sym::mul_with_overflow
|
||||
| sym::unchecked_div
|
||||
| sym::unchecked_rem
|
||||
| sym::unchecked_shl
|
||||
|
@ -232,28 +229,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let ty = arg_tys[0];
|
||||
match int_type_width_signed(ty, bx.tcx()) {
|
||||
Some((_width, signed)) => match name {
|
||||
sym::add_with_overflow
|
||||
| sym::sub_with_overflow
|
||||
| sym::mul_with_overflow => {
|
||||
let op = match name {
|
||||
sym::add_with_overflow => OverflowOp::Add,
|
||||
sym::sub_with_overflow => OverflowOp::Sub,
|
||||
sym::mul_with_overflow => OverflowOp::Mul,
|
||||
_ => bug!(),
|
||||
};
|
||||
let (val, overflow) =
|
||||
bx.checked_binop(op, ty, args[0].immediate(), args[1].immediate());
|
||||
// Convert `i1` to a `bool`, and write it to the out parameter
|
||||
let val = bx.from_immediate(val);
|
||||
let overflow = bx.from_immediate(overflow);
|
||||
|
||||
let dest = result.project_field(bx, 0);
|
||||
bx.store(val, dest.llval, dest.align);
|
||||
let dest = result.project_field(bx, 1);
|
||||
bx.store(overflow, dest.llval, dest.align);
|
||||
|
||||
return;
|
||||
}
|
||||
sym::exact_div => {
|
||||
if signed {
|
||||
bx.exactsdiv(args[0].immediate(), args[1].immediate())
|
||||
|
|
|
@ -652,15 +652,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
rhs: Bx::Value,
|
||||
input_ty: Ty<'tcx>,
|
||||
) -> OperandValue<Bx::Value> {
|
||||
// This case can currently arise only from functions marked
|
||||
// with #[rustc_inherit_overflow_checks] and inlined from
|
||||
// another crate (mostly core::num generic/#[inline] fns),
|
||||
// while the current crate doesn't use overflow checks.
|
||||
if !bx.cx().check_overflow() {
|
||||
let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty);
|
||||
return OperandValue::Pair(val, bx.cx().const_bool(false));
|
||||
}
|
||||
|
||||
let (val, of) = match op {
|
||||
// These are checked using intrinsics
|
||||
mir::BinOp::Add | mir::BinOp::Sub | mir::BinOp::Mul => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue