Skip to content

Commit beec32d

Browse files
committed
ignore nested arrays
1 parent caaa729 commit beec32d

File tree

1 file changed

+36
-6
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+36
-6
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
410410
let mut mplace = None;
411411
let alloc_id = self.ecx.intern_with_temp_alloc(ty, |ecx, dest| {
412412
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+
}
413417
let field_dest = ecx.project_field(dest, field_index)?;
414418
ecx.copy_op(op, &field_dest)?;
415419
}
@@ -722,7 +726,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
722726
place.projection = self.tcx.mk_place_elems(&projection);
723727
}
724728

725-
trace!(?place);
729+
trace!(after_place = ?place);
726730
}
727731

728732
/// 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>(
13811385
}
13821386

13831387
// 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(..))) {
13851389
return None;
13861390
}
13871391

@@ -1452,14 +1456,37 @@ impl<'tcx> VnState<'_, 'tcx> {
14521456
}
14531457

14541458
/// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR.
1459+
#[instrument(level = "trace", skip(self, index), ret)]
14551460
fn try_as_constant(&mut self, index: VnIndex) -> Option<ConstOperand<'tcx>> {
14561461
// 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 {
14581465
// If the constant is not deterministic, adding an additional mention of it in MIR will
14591466
// 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+
_ => {}
14631490
}
14641491

14651492
let op = self.evaluated[index].as_ref()?;
@@ -1499,6 +1526,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
14991526
self.simplify_operand(operand, location);
15001527
}
15011528

1529+
#[instrument(level = "trace", skip(self, stmt))]
15021530
fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, location: Location) {
15031531
if let StatementKind::Assign(box (ref mut lhs, ref mut rvalue)) = stmt.kind {
15041532
self.simplify_place_projection(lhs, location);
@@ -1515,6 +1543,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
15151543
debug!(?value);
15161544
let Some(value) = value else { return };
15171545

1546+
debug!(before_rvalue = ?rvalue);
15181547
if let Some(const_) = self.try_as_constant(value) {
15191548
*rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
15201549
} else if let Some(local) = self.try_as_local(value, location)
@@ -1523,6 +1552,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
15231552
*rvalue = Rvalue::Use(Operand::Copy(local.into()));
15241553
self.reused_locals.insert(local);
15251554
}
1555+
debug!(after_rvalue = ?rvalue);
15261556

15271557
return;
15281558
}

0 commit comments

Comments
 (0)