11//! Performs various peephole optimizations.
22
33use crate :: simplify:: simplify_duplicate_switch_targets;
4+ use rustc_ast:: attr;
45use rustc_middle:: mir:: * ;
56use rustc_middle:: ty:: layout;
67use rustc_middle:: ty:: layout:: ValidityRequirement ;
78use rustc_middle:: ty:: { self , GenericArgsRef , ParamEnv , Ty , TyCtxt } ;
9+ use rustc_span:: sym;
810use rustc_span:: symbol:: Symbol ;
911use rustc_target:: abi:: FieldIdx ;
1012use rustc_target:: spec:: abi:: Abi ;
@@ -22,10 +24,17 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {
2224 local_decls : & body. local_decls ,
2325 param_env : tcx. param_env_reveal_all_normalized ( body. source . def_id ( ) ) ,
2426 } ;
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 ;
2531 for block in body. basic_blocks . as_mut ( ) {
2632 for statement in block. statements . iter_mut ( ) {
2733 match statement. kind {
2834 StatementKind :: Assign ( box ( _place, ref mut rvalue) ) => {
35+ if !rustc_ub_check {
36+ ctx. simplify_ub_check ( & statement. source_info , rvalue, debug_assertions) ;
37+ }
2938 ctx. simplify_bool_cmp ( & statement. source_info , rvalue) ;
3039 ctx. simplify_ref_deref ( & statement. source_info , rvalue) ;
3140 ctx. simplify_len ( & statement. source_info , rvalue) ;
@@ -140,6 +149,24 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
140149 }
141150 }
142151
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+
143170 fn simplify_cast ( & self , rvalue : & mut Rvalue < ' tcx > ) {
144171 if let Rvalue :: Cast ( kind, operand, cast_ty) = rvalue {
145172 let operand_ty = operand. ty ( self . local_decls , self . tcx ) ;
0 commit comments