@@ -39,26 +39,26 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
3939 attr:: contains_name ( tcx. hir_krate_attrs ( ) , sym:: rustc_preserve_ub_checks) ;
4040 for block in body. basic_blocks . as_mut ( ) {
4141 for statement in block. statements . iter_mut ( ) {
42- match statement. kind {
43- StatementKind :: Assign ( box ( _place, ref mut rvalue) ) => {
44- if !preserve_ub_checks {
45- ctx. simplify_ub_check ( rvalue) ;
46- }
47- ctx. simplify_bool_cmp ( rvalue) ;
48- ctx. simplify_ref_deref ( rvalue) ;
49- ctx. simplify_ptr_aggregate ( rvalue) ;
50- ctx. simplify_cast ( rvalue) ;
51- ctx. simplify_repeated_aggregate ( rvalue) ;
52- ctx. simplify_repeat_once ( rvalue) ;
53- }
54- _ => { }
42+ let StatementKind :: Assign ( box ( .., rvalue) ) = & mut statement. kind else {
43+ continue ;
44+ } ;
45+
46+ if !preserve_ub_checks {
47+ ctx. simplify_ub_check ( rvalue) ;
5548 }
49+ ctx. simplify_bool_cmp ( rvalue) ;
50+ ctx. simplify_ref_deref ( rvalue) ;
51+ ctx. simplify_ptr_aggregate ( rvalue) ;
52+ ctx. simplify_cast ( rvalue) ;
53+ ctx. simplify_repeated_aggregate ( rvalue) ;
54+ ctx. simplify_repeat_once ( rvalue) ;
5655 }
5756
58- ctx. simplify_primitive_clone ( block. terminator . as_mut ( ) . unwrap ( ) , & mut block. statements ) ;
59- ctx. simplify_intrinsic_assert ( block. terminator . as_mut ( ) . unwrap ( ) ) ;
60- ctx. simplify_nounwind_call ( block. terminator . as_mut ( ) . unwrap ( ) ) ;
61- simplify_duplicate_switch_targets ( block. terminator . as_mut ( ) . unwrap ( ) ) ;
57+ let terminator = block. terminator . as_mut ( ) . unwrap ( ) ;
58+ ctx. simplify_primitive_clone ( terminator, & mut block. statements ) ;
59+ ctx. simplify_intrinsic_assert ( terminator) ;
60+ ctx. simplify_nounwind_call ( terminator) ;
61+ simplify_duplicate_switch_targets ( terminator) ;
6262 }
6363 }
6464
@@ -105,43 +105,34 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
105105
106106 /// Transform boolean comparisons into logical operations.
107107 fn simplify_bool_cmp ( & self , rvalue : & mut Rvalue < ' tcx > ) {
108- match rvalue {
109- Rvalue :: BinaryOp ( op @ ( BinOp :: Eq | BinOp :: Ne ) , box ( a, b) ) => {
110- let new = match ( op, self . try_eval_bool ( a) , self . try_eval_bool ( b) ) {
111- // Transform "Eq(a, true)" ==> "a"
112- ( BinOp :: Eq , _, Some ( true ) ) => Some ( Rvalue :: Use ( a. clone ( ) ) ) ,
113-
114- // Transform "Ne(a, false)" ==> "a"
115- ( BinOp :: Ne , _, Some ( false ) ) => Some ( Rvalue :: Use ( a. clone ( ) ) ) ,
108+ let Rvalue :: BinaryOp ( op @ ( BinOp :: Eq | BinOp :: Ne ) , box ( a, b) ) = & * rvalue else { return } ;
109+ * rvalue = match ( op, self . try_eval_bool ( a) , self . try_eval_bool ( b) ) {
110+ // Transform "Eq(a, true)" ==> "a"
111+ ( BinOp :: Eq , _, Some ( true ) ) => Rvalue :: Use ( a. clone ( ) ) ,
116112
117- // Transform "Eq(true, b )" ==> "b "
118- ( BinOp :: Eq , Some ( true ) , _ ) => Some ( Rvalue :: Use ( b . clone ( ) ) ) ,
113+ // Transform "Ne(a, false )" ==> "a "
114+ ( BinOp :: Ne , _ , Some ( false ) ) => Rvalue :: Use ( a . clone ( ) ) ,
119115
120- // Transform "Ne(false , b)" ==> "b"
121- ( BinOp :: Ne , Some ( false ) , _) => Some ( Rvalue :: Use ( b. clone ( ) ) ) ,
116+ // Transform "Eq(true , b)" ==> "b"
117+ ( BinOp :: Eq , Some ( true ) , _) => Rvalue :: Use ( b. clone ( ) ) ,
122118
123- // Transform "Eq (false, b)" ==> "Not(b) "
124- ( BinOp :: Eq , Some ( false ) , _) => Some ( Rvalue :: UnaryOp ( UnOp :: Not , b. clone ( ) ) ) ,
119+ // Transform "Ne (false, b)" ==> "b "
120+ ( BinOp :: Ne , Some ( false ) , _) => Rvalue :: Use ( b. clone ( ) ) ,
125121
126- // Transform "Ne(true , b)" ==> "Not(b)"
127- ( BinOp :: Ne , Some ( true ) , _) => Some ( Rvalue :: UnaryOp ( UnOp :: Not , b. clone ( ) ) ) ,
122+ // Transform "Eq(false , b)" ==> "Not(b)"
123+ ( BinOp :: Eq , Some ( false ) , _) => Rvalue :: UnaryOp ( UnOp :: Not , b. clone ( ) ) ,
128124
129- // Transform "Eq(a, false )" ==> "Not(a )"
130- ( BinOp :: Eq , _ , Some ( false ) ) => Some ( Rvalue :: UnaryOp ( UnOp :: Not , a . clone ( ) ) ) ,
125+ // Transform "Ne(true, b )" ==> "Not(b )"
126+ ( BinOp :: Ne , Some ( true ) , _ ) => Rvalue :: UnaryOp ( UnOp :: Not , b . clone ( ) ) ,
131127
132- // Transform "Ne(a, true)" ==> "Not(a)"
133- ( BinOp :: Ne , _, Some ( true ) ) => Some ( Rvalue :: UnaryOp ( UnOp :: Not , a. clone ( ) ) ) ,
134-
135- _ => None ,
136- } ;
128+ // Transform "Eq(a, false)" ==> "Not(a)"
129+ ( BinOp :: Eq , _, Some ( false ) ) => Rvalue :: UnaryOp ( UnOp :: Not , a. clone ( ) ) ,
137130
138- if let Some ( new) = new {
139- * rvalue = new;
140- }
141- }
131+ // Transform "Ne(a, true)" ==> "Not(a)"
132+ ( BinOp :: Ne , _, Some ( true ) ) => Rvalue :: UnaryOp ( UnOp :: Not , a. clone ( ) ) ,
142133
143- _ => { }
144- }
134+ _ => return ,
135+ } ;
145136 }
146137
147138 fn try_eval_bool ( & self , a : & Operand < ' _ > ) -> Option < bool > {
@@ -151,64 +142,61 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
151142
152143 /// Transform `&(*a)` ==> `a`.
153144 fn simplify_ref_deref ( & self , rvalue : & mut Rvalue < ' tcx > ) {
154- if let Rvalue :: Ref ( _, _, place) | Rvalue :: RawPtr ( _, place) = rvalue {
155- if let Some ( ( base, ProjectionElem :: Deref ) ) = place. as_ref ( ) . last_projection ( ) {
156- if rvalue. ty ( self . local_decls , self . tcx ) != base. ty ( self . local_decls , self . tcx ) . ty {
157- return ;
158- }
159-
160- * rvalue = Rvalue :: Use ( Operand :: Copy ( Place {
161- local : base. local ,
162- projection : self . tcx . mk_place_elems ( base. projection ) ,
163- } ) ) ;
145+ if let Rvalue :: Ref ( _, _, place) | Rvalue :: RawPtr ( _, place) = rvalue
146+ && let Some ( ( base, ProjectionElem :: Deref ) ) = place. as_ref ( ) . last_projection ( )
147+ {
148+ if rvalue. ty ( self . local_decls , self . tcx ) != base. ty ( self . local_decls , self . tcx ) . ty {
149+ return ;
164150 }
151+
152+ * rvalue = Rvalue :: Use ( Operand :: Copy ( Place {
153+ local : base. local ,
154+ projection : self . tcx . mk_place_elems ( base. projection ) ,
155+ } ) ) ;
165156 }
166157 }
167158
168159 /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
169160 fn simplify_ptr_aggregate ( & self , rvalue : & mut Rvalue < ' tcx > ) {
170161 if let Rvalue :: Aggregate ( box AggregateKind :: RawPtr ( pointee_ty, mutability) , fields) = rvalue
162+ && let meta_ty = fields. raw [ 1 ] . ty ( self . local_decls , self . tcx )
163+ && meta_ty. is_unit ( )
171164 {
172- let meta_ty = fields. raw [ 1 ] . ty ( self . local_decls , self . tcx ) ;
173- if meta_ty. is_unit ( ) {
174- // The mutable borrows we're holding prevent printing `rvalue` here
175- let mut fields = std:: mem:: take ( fields) ;
176- let _meta = fields. pop ( ) . unwrap ( ) ;
177- let data = fields. pop ( ) . unwrap ( ) ;
178- let ptr_ty = Ty :: new_ptr ( self . tcx , * pointee_ty, * mutability) ;
179- * rvalue = Rvalue :: Cast ( CastKind :: PtrToPtr , data, ptr_ty) ;
180- }
165+ // The mutable borrows we're holding prevent printing `rvalue` here
166+ let mut fields = std:: mem:: take ( fields) ;
167+ let _meta = fields. pop ( ) . unwrap ( ) ;
168+ let data = fields. pop ( ) . unwrap ( ) ;
169+ let ptr_ty = Ty :: new_ptr ( self . tcx , * pointee_ty, * mutability) ;
170+ * rvalue = Rvalue :: Cast ( CastKind :: PtrToPtr , data, ptr_ty) ;
181171 }
182172 }
183173
184174 fn simplify_ub_check ( & self , rvalue : & mut Rvalue < ' tcx > ) {
185- if let Rvalue :: NullaryOp ( NullOp :: UbChecks , _) = * rvalue {
186- let const_ = Const :: from_bool ( self . tcx , self . tcx . sess . ub_checks ( ) ) ;
187- let constant = ConstOperand { span : DUMMY_SP , const_ , user_ty : None } ;
188- * rvalue = Rvalue :: Use ( Operand :: Constant ( Box :: new ( constant ) ) ) ;
189- }
175+ let Rvalue :: NullaryOp ( NullOp :: UbChecks , _) = * rvalue else { return } ;
176+
177+ let const_ = Const :: from_bool ( self . tcx , self . tcx . sess . ub_checks ( ) ) ;
178+ let constant = ConstOperand { span : DUMMY_SP , const_ , user_ty : None } ;
179+ * rvalue = Rvalue :: Use ( Operand :: Constant ( Box :: new ( constant ) ) ) ;
190180 }
191181
192182 fn simplify_cast ( & self , rvalue : & mut Rvalue < ' tcx > ) {
193- if let Rvalue :: Cast ( kind, operand, cast_ty) = rvalue {
194- let operand_ty = operand. ty ( self . local_decls , self . tcx ) ;
195- if operand_ty == * cast_ty {
196- * rvalue = Rvalue :: Use ( operand. clone ( ) ) ;
197- } else if * kind == CastKind :: Transmute {
198- // Transmuting an integer to another integer is just a signedness cast
199- if let ( ty:: Int ( int) , ty:: Uint ( uint) ) | ( ty:: Uint ( uint) , ty:: Int ( int) ) =
200- ( operand_ty. kind ( ) , cast_ty. kind ( ) )
201- && int. bit_width ( ) == uint. bit_width ( )
202- {
203- // The width check isn't strictly necessary, as different widths
204- // are UB and thus we'd be allowed to turn it into a cast anyway.
205- // But let's keep the UB around for codegen to exploit later.
206- // (If `CastKind::Transmute` ever becomes *not* UB for mismatched sizes,
207- // then the width check is necessary for big-endian correctness.)
208- * kind = CastKind :: IntToInt ;
209- return ;
210- }
211- }
183+ let Rvalue :: Cast ( kind, operand, cast_ty) = rvalue else { return } ;
184+
185+ let operand_ty = operand. ty ( self . local_decls , self . tcx ) ;
186+ if operand_ty == * cast_ty {
187+ * rvalue = Rvalue :: Use ( operand. clone ( ) ) ;
188+ } else if * kind == CastKind :: Transmute
189+ // Transmuting an integer to another integer is just a signedness cast
190+ && let ( ty:: Int ( int) , ty:: Uint ( uint) ) | ( ty:: Uint ( uint) , ty:: Int ( int) ) =
191+ ( operand_ty. kind ( ) , cast_ty. kind ( ) )
192+ && int. bit_width ( ) == uint. bit_width ( )
193+ {
194+ // The width check isn't strictly necessary, as different widths
195+ // are UB and thus we'd be allowed to turn it into a cast anyway.
196+ // But let's keep the UB around for codegen to exploit later.
197+ // (If `CastKind::Transmute` ever becomes *not* UB for mismatched sizes,
198+ // then the width check is necessary for big-endian correctness.)
199+ * kind = CastKind :: IntToInt ;
212200 }
213201 }
214202
@@ -277,7 +265,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
277265 }
278266
279267 fn simplify_nounwind_call ( & self , terminator : & mut Terminator < ' tcx > ) {
280- let TerminatorKind :: Call { func, unwind, .. } = & mut terminator. kind else {
268+ let TerminatorKind :: Call { ref func, ref mut unwind, .. } = terminator. kind else {
281269 return ;
282270 } ;
283271
@@ -290,7 +278,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
290278 ty:: FnDef ( ..) => body_ty. fn_sig ( self . tcx ) . abi ( ) ,
291279 ty:: Closure ( ..) => ExternAbi :: RustCall ,
292280 ty:: Coroutine ( ..) => ExternAbi :: Rust ,
293- _ => bug ! ( "unexpected body ty: {:?}" , body_ty ) ,
281+ _ => bug ! ( "unexpected body ty: {body_ty :?}" ) ,
294282 } ;
295283
296284 if !layout:: fn_can_unwind ( self . tcx , Some ( def_id) , body_abi) {
0 commit comments