1
Fork 0

Make overflow flag propagation conditional

This commit is contained in:
Jannis Christopher Köhl 2022-10-15 19:24:02 +02:00
parent 1dde908fae
commit be9013f02b
3 changed files with 69 additions and 2 deletions

View file

@ -7,7 +7,7 @@ use rustc_mir_dataflow::value_analysis::{
Map, ProjElem, State, ValueAnalysis, ValueOrPlace, ValueOrPlaceOrRef,
};
use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects};
use rustc_span::DUMMY_SP;
use rustc_span::{sym, DUMMY_SP};
use crate::MirPass;
@ -38,6 +38,7 @@ struct ConstAnalysis<'tcx> {
tcx: TyCtxt<'tcx>,
ecx: InterpCx<'tcx, 'tcx, DummyMachine>,
param_env: ty::ParamEnv<'tcx>,
propagate_overflow: bool,
}
impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
@ -72,7 +73,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
});
if value_target.is_some() || overflow_target.is_some() {
let (val, overflow) = self.binary_op(state, *op, left, right);
let (val, mut overflow) = self.binary_op(state, *op, left, right);
if !self.propagate_overflow {
overflow = FlatSet::Top;
}
if let Some(value_target) = value_target {
state.assign_idx(value_target, ValueOrPlaceOrRef::Value(val), self.map());
@ -202,11 +207,20 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> {
impl<'tcx> ConstAnalysis<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, map: Map) -> Self {
// It can happen that overflow will be detected even though overflow checks are disabled.
// This is caused by inlining functions that have #[rustc_inherit_overflow_checks]. Such
// overflows must not be propagated if `-C overflow-checks=off`. Also, if the function we
// are optimizing here has #[rustc_inherit_overflow_checks], the overflow checks may
// actually not be triggered by the consuming crate, so we have to ignore them too.
// Related to https://github.com/rust-lang/rust/issues/35310.
let propagate_overflow = tcx.sess.overflow_checks()
&& !tcx.has_attr(body.source.def_id(), sym::rustc_inherit_overflow_checks);
Self {
map,
tcx,
ecx: InterpCx::new(tcx, DUMMY_SP, ty::ParamEnv::empty(), DummyMachine),
param_env: tcx.param_env(body.source.def_id()),
propagate_overflow,
}
}