@@ -414,6 +414,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
414
414
let mut mplace = None ;
415
415
let alloc_id = self . ecx . intern_with_temp_alloc ( ty, |ecx, dest| {
416
416
for ( field_index, op) in fields. iter ( ) . copied ( ) . enumerate ( ) {
417
+ // ignore nested arrays
418
+ if let Either :: Left ( _) = op. as_mplace_or_imm ( ) {
419
+ interpret:: throw_inval!( TooGeneric ) ;
420
+ }
417
421
let field_dest = ecx. project_field ( dest, field_index) ?;
418
422
ecx. copy_op ( op, & field_dest) ?;
419
423
}
@@ -732,7 +736,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
732
736
place. projection = self . tcx . mk_place_elems ( & projection) ;
733
737
}
734
738
735
- trace ! ( ?place) ;
739
+ trace ! ( after_place = ?place) ;
736
740
}
737
741
738
742
/// Represent the *value* which would be read from `place`, and point `place` to a preexisting
@@ -1272,7 +1276,7 @@ fn op_to_prop_const<'tcx>(
1272
1276
}
1273
1277
1274
1278
// Do not synthetize too large constants. Codegen will just memcpy them, which we'd like to avoid.
1275
- if !matches ! ( op. layout. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) ) {
1279
+ if !( op . layout . ty . is_array ( ) || matches ! ( op. layout. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) ) ) {
1276
1280
return None ;
1277
1281
}
1278
1282
@@ -1326,14 +1330,37 @@ fn op_to_prop_const<'tcx>(
1326
1330
1327
1331
impl < ' tcx > VnState < ' _ , ' tcx > {
1328
1332
/// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR.
1333
+ #[ instrument( level = "trace" , skip( self , index) , ret) ]
1329
1334
fn try_as_constant ( & mut self , index : VnIndex ) -> Option < ConstOperand < ' tcx > > {
1330
1335
// This was already constant in MIR, do not change it.
1331
- if let Value :: Constant { value, disambiguator : _ } = * self . get ( index)
1336
+ let value = self . get ( index) ;
1337
+ debug ! ( ?index, ?value) ;
1338
+ match value {
1332
1339
// If the constant is not deterministic, adding an additional mention of it in MIR will
1333
1340
// not give the same value as the former mention.
1334
- && value. is_deterministic ( )
1335
- {
1336
- return Some ( ConstOperand { span : DUMMY_SP , user_ty : None , const_ : value } ) ;
1341
+ Value :: Constant { value, disambiguator : _ } if value. is_deterministic ( ) => {
1342
+ return Some ( ConstOperand { span : DUMMY_SP , user_ty : None , const_ : * value } ) ;
1343
+ }
1344
+ // ignore nested arrays
1345
+ Value :: Aggregate ( AggregateTy :: Array , _, fields) => {
1346
+ for f in fields {
1347
+ if let Value :: Constant { value : Const :: Val ( const_, _) , .. } = self . get ( * f)
1348
+ && let ConstValue :: Indirect { .. } = const_ {
1349
+ return None ;
1350
+ }
1351
+ }
1352
+ }
1353
+ // ignore promoted arrays
1354
+ Value :: Projection ( index, ProjectionElem :: Deref ) => {
1355
+ if let Value :: Constant { value : Const :: Val ( const_, ty) , .. } = self . get ( * index)
1356
+ && let ConstValue :: Scalar ( Scalar :: Ptr ( ..) ) = const_
1357
+ && let ty:: Ref ( region, ty, _mutability) = ty. kind ( )
1358
+ && region. is_erased ( )
1359
+ && ty. is_array ( ) {
1360
+ return None ;
1361
+ }
1362
+ }
1363
+ _ => { }
1337
1364
}
1338
1365
1339
1366
let op = self . evaluated [ index] . as_ref ( ) ?;
@@ -1373,6 +1400,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1373
1400
self . simplify_operand ( operand, location) ;
1374
1401
}
1375
1402
1403
+ #[ instrument( level = "trace" , skip( self , stmt) ) ]
1376
1404
fn visit_statement ( & mut self , stmt : & mut Statement < ' tcx > , location : Location ) {
1377
1405
if let StatementKind :: Assign ( box ( ref mut lhs, ref mut rvalue) ) = stmt. kind {
1378
1406
self . simplify_place_projection ( lhs, location) ;
@@ -1389,6 +1417,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1389
1417
debug ! ( ?value) ;
1390
1418
let Some ( value) = value else { return } ;
1391
1419
1420
+ debug ! ( before_rvalue = ?rvalue) ;
1392
1421
if let Some ( const_) = self . try_as_constant ( value) {
1393
1422
* rvalue = Rvalue :: Use ( Operand :: Constant ( Box :: new ( const_) ) ) ;
1394
1423
} else if let Some ( local) = self . try_as_local ( value, location)
@@ -1397,6 +1426,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1397
1426
* rvalue = Rvalue :: Use ( Operand :: Copy ( local. into ( ) ) ) ;
1398
1427
self . reused_locals . insert ( local) ;
1399
1428
}
1429
+ debug ! ( after_rvalue = ?rvalue) ;
1400
1430
1401
1431
return ;
1402
1432
}
0 commit comments