@@ -410,6 +410,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
410
410
let mut mplace = None ;
411
411
let alloc_id = self . ecx . intern_with_temp_alloc ( ty, |ecx, dest| {
412
412
for ( field_index, op) in fields. iter ( ) . copied ( ) . enumerate ( ) {
413
+ // ignore nested arrays
414
+ if let Either :: Left ( _) = op. as_mplace_or_imm ( ) {
415
+ interpret:: throw_inval!( TooGeneric ) ;
416
+ }
413
417
let field_dest = ecx. project_field ( dest, field_index) ?;
414
418
ecx. copy_op ( op, & field_dest) ?;
415
419
}
@@ -722,7 +726,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
722
726
place. projection = self . tcx . mk_place_elems ( & projection) ;
723
727
}
724
728
725
- trace ! ( ?place) ;
729
+ trace ! ( after_place = ?place) ;
726
730
}
727
731
728
732
/// Represent the *value* which would be read from `place`, and point `place` to a preexisting
@@ -1381,7 +1385,7 @@ fn op_to_prop_const<'tcx>(
1381
1385
}
1382
1386
1383
1387
// Do not synthetize too large constants. Codegen will just memcpy them, which we'd like to avoid.
1384
- if !matches ! ( op. layout. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) ) {
1388
+ if !( op . layout . ty . is_array ( ) || matches ! ( op. layout. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) ) ) {
1385
1389
return None ;
1386
1390
}
1387
1391
@@ -1452,14 +1456,37 @@ impl<'tcx> VnState<'_, 'tcx> {
1452
1456
}
1453
1457
1454
1458
/// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR.
1459
+ #[ instrument( level = "trace" , skip( self , index) , ret) ]
1455
1460
fn try_as_constant ( & mut self , index : VnIndex ) -> Option < ConstOperand < ' tcx > > {
1456
1461
// This was already constant in MIR, do not change it.
1457
- if let Value :: Constant { value, disambiguator : _ } = * self . get ( index)
1462
+ let value = self . get ( index) ;
1463
+ debug ! ( ?index, ?value) ;
1464
+ match value {
1458
1465
// If the constant is not deterministic, adding an additional mention of it in MIR will
1459
1466
// not give the same value as the former mention.
1460
- && value. is_deterministic ( )
1461
- {
1462
- return Some ( ConstOperand { span : DUMMY_SP , user_ty : None , const_ : value } ) ;
1467
+ Value :: Constant { value, disambiguator : _ } if value. is_deterministic ( ) => {
1468
+ return Some ( ConstOperand { span : DUMMY_SP , user_ty : None , const_ : * value } ) ;
1469
+ }
1470
+ // ignore nested arrays
1471
+ Value :: Aggregate ( AggregateTy :: Array , _, fields) => {
1472
+ for f in fields {
1473
+ if let Value :: Constant { value : Const :: Val ( const_, _) , .. } = self . get ( * f)
1474
+ && let ConstValue :: Indirect { .. } = const_ {
1475
+ return None ;
1476
+ }
1477
+ }
1478
+ }
1479
+ // ignore promoted arrays
1480
+ Value :: Projection ( index, ProjectionElem :: Deref ) => {
1481
+ if let Value :: Constant { value : Const :: Val ( const_, ty) , .. } = self . get ( * index)
1482
+ && let ConstValue :: Scalar ( Scalar :: Ptr ( ..) ) = const_
1483
+ && let ty:: Ref ( region, ty, _mutability) = ty. kind ( )
1484
+ && region. is_erased ( )
1485
+ && ty. is_array ( ) {
1486
+ return None ;
1487
+ }
1488
+ }
1489
+ _ => { }
1463
1490
}
1464
1491
1465
1492
let op = self . evaluated [ index] . as_ref ( ) ?;
@@ -1499,6 +1526,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1499
1526
self . simplify_operand ( operand, location) ;
1500
1527
}
1501
1528
1529
+ #[ instrument( level = "trace" , skip( self , stmt) ) ]
1502
1530
fn visit_statement ( & mut self , stmt : & mut Statement < ' tcx > , location : Location ) {
1503
1531
if let StatementKind :: Assign ( box ( ref mut lhs, ref mut rvalue) ) = stmt. kind {
1504
1532
self . simplify_place_projection ( lhs, location) ;
@@ -1515,6 +1543,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1515
1543
debug ! ( ?value) ;
1516
1544
let Some ( value) = value else { return } ;
1517
1545
1546
+ debug ! ( before_rvalue = ?rvalue) ;
1518
1547
if let Some ( const_) = self . try_as_constant ( value) {
1519
1548
* rvalue = Rvalue :: Use ( Operand :: Constant ( Box :: new ( const_) ) ) ;
1520
1549
} else if let Some ( local) = self . try_as_local ( value, location)
@@ -1523,6 +1552,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1523
1552
* rvalue = Rvalue :: Use ( Operand :: Copy ( local. into ( ) ) ) ;
1524
1553
self . reused_locals . insert ( local) ;
1525
1554
}
1555
+ debug ! ( after_rvalue = ?rvalue) ;
1526
1556
1527
1557
return ;
1528
1558
}
0 commit comments