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,18 @@ 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 preserve_ub_checks =
29
+ attr:: contains_name ( tcx. hir ( ) . krate_attrs ( ) , sym:: rustc_preserve_ub_checks)
30
+ || tcx. sess . instrument_coverage ( ) ;
31
+ let debug_assertions = tcx. sess . opts . debug_assertions ;
25
32
for block in body. basic_blocks . as_mut ( ) {
26
33
for statement in block. statements . iter_mut ( ) {
27
34
match statement. kind {
28
35
StatementKind :: Assign ( box ( _place, ref mut rvalue) ) => {
36
+ if !preserve_ub_checks {
37
+ ctx. simplify_ub_check ( & statement. source_info , rvalue, debug_assertions) ;
38
+ }
29
39
ctx. simplify_bool_cmp ( & statement. source_info , rvalue) ;
30
40
ctx. simplify_ref_deref ( & statement. source_info , rvalue) ;
31
41
ctx. simplify_len ( & statement. source_info , rvalue) ;
@@ -140,6 +150,19 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
140
150
}
141
151
}
142
152
153
+ fn simplify_ub_check (
154
+ & self ,
155
+ source_info : & SourceInfo ,
156
+ rvalue : & mut Rvalue < ' tcx > ,
157
+ debug_assertions : bool ,
158
+ ) {
159
+ if let Rvalue :: NullaryOp ( NullOp :: UbCheck ( _) , _) = * rvalue {
160
+ let const_ = Const :: from_bool ( self . tcx , debug_assertions) ;
161
+ let constant = ConstOperand { span : source_info. span , const_, user_ty : None } ;
162
+ * rvalue = Rvalue :: Use ( Operand :: Constant ( Box :: new ( constant) ) ) ;
163
+ }
164
+ }
165
+
143
166
fn simplify_cast ( & self , rvalue : & mut Rvalue < ' tcx > ) {
144
167
if let Rvalue :: Cast ( kind, operand, cast_ty) = rvalue {
145
168
let operand_ty = operand. ty ( self . local_decls , self . tcx ) ;
0 commit comments