Auto merge of #122282 - DianQK:simplify_ub_check, r= · rust-lang/rust@acc30d0 (original) (raw)
1
1
`//! Performs various peephole optimizations.
`
2
2
``
3
3
`use crate::simplify::simplify_duplicate_switch_targets;
`
``
4
`+
use rustc_ast::attr;
`
4
5
`use rustc_middle::mir::*;
`
5
6
`use rustc_middle::ty::layout;
`
6
7
`use rustc_middle::ty::layout::ValidityRequirement;
`
7
8
`use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt};
`
``
9
`+
use rustc_span::sym;
`
8
10
`use rustc_span::symbol::Symbol;
`
9
11
`use rustc_target::abi::FieldIdx;
`
10
12
`use rustc_target::spec::abi::Abi;
`
`@@ -22,10 +24,17 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {
`
22
24
`local_decls: &body.local_decls,
`
23
25
`param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()),
`
24
26
`};
`
``
27
`` +
// FIXME(#116171) Coverage related, also see unreachable_prop.rs
.
``
``
28
`+
let rustc_ub_check = attr::contains_name(tcx.hir().krate_attrs(), sym::rustc_ub_check)
`
``
29
`+
|| tcx.sess.instrument_coverage();
`
``
30
`+
let debug_assertions = tcx.sess.opts.debug_assertions;
`
25
31
`for block in body.basic_blocks.as_mut() {
`
26
32
`for statement in block.statements.iter_mut() {
`
27
33
`match statement.kind {
`
28
34
`StatementKind::Assign(box (_place, ref mut rvalue)) => {
`
``
35
`+
if !rustc_ub_check {
`
``
36
`+
ctx.simplify_ub_check(&statement.source_info, rvalue, debug_assertions);
`
``
37
`+
}
`
29
38
` ctx.simplify_bool_cmp(&statement.source_info, rvalue);
`
30
39
` ctx.simplify_ref_deref(&statement.source_info, rvalue);
`
31
40
` ctx.simplify_len(&statement.source_info, rvalue);
`
`@@ -140,6 +149,24 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
`
140
149
`}
`
141
150
`}
`
142
151
``
``
152
`+
fn simplify_ub_check(
`
``
153
`+
&self,
`
``
154
`+
source_info: &SourceInfo,
`
``
155
`+
rvalue: &mut Rvalue<'tcx>,
`
``
156
`+
debug_assertions: bool,
`
``
157
`+
) {
`
``
158
`+
if let Rvalue::NullaryOp(ref null_op, _) = *rvalue {
`
``
159
`+
match null_op {
`
``
160
`+
NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) => {}
`
``
161
`+
NullOp::UbCheck(_) => {
`
``
162
`+
let const_ = Const::from_bool(self.tcx, debug_assertions);
`
``
163
`+
let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
`
``
164
`+
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
`
``
165
`+
}
`
``
166
`+
}
`
``
167
`+
}
`
``
168
`+
}
`
``
169
+
143
170
`fn simplify_cast(&self, rvalue: &mut Rvalue<'tcx>) {
`
144
171
`if let Rvalue::Cast(kind, operand, cast_ty) = rvalue {
`
145
172
`let operand_ty = operand.ty(self.local_decls, self.tcx);
`