Skip to content

Commit a5fd8d9

Browse files
committed
ignore nested arrays
1 parent 3db2f6d commit a5fd8d9

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
@@ -414,6 +414,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
414414
let mut mplace = None;
415415
let alloc_id = self.ecx.intern_with_temp_alloc(ty, |ecx, dest| {
416416
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+
}
417421
let field_dest = ecx.project_field(dest, field_index)?;
418422
ecx.copy_op(op, &field_dest)?;
419423
}
@@ -732,7 +736,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
732736
place.projection = self.tcx.mk_place_elems(&projection);
733737
}
734738

735-
trace!(?place);
739+
trace!(after_place = ?place);
736740
}
737741

738742
/// 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>(
12721276
}
12731277

12741278
// 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(..))) {
12761280
return None;
12771281
}
12781282

@@ -1326,14 +1330,37 @@ fn op_to_prop_const<'tcx>(
13261330

13271331
impl<'tcx> VnState<'_, 'tcx> {
13281332
/// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR.
1333+
#[instrument(level = "trace", skip(self, index), ret)]
13291334
fn try_as_constant(&mut self, index: VnIndex) -> Option<ConstOperand<'tcx>> {
13301335
// 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 {
13321339
// If the constant is not deterministic, adding an additional mention of it in MIR will
13331340
// 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+
_ => {}
13371364
}
13381365

13391366
let op = self.evaluated[index].as_ref()?;
@@ -1373,6 +1400,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
13731400
self.simplify_operand(operand, location);
13741401
}
13751402

1403+
#[instrument(level = "trace", skip(self, stmt))]
13761404
fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, location: Location) {
13771405
if let StatementKind::Assign(box (ref mut lhs, ref mut rvalue)) = stmt.kind {
13781406
self.simplify_place_projection(lhs, location);
@@ -1389,6 +1417,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
13891417
debug!(?value);
13901418
let Some(value) = value else { return };
13911419

1420+
debug!(before_rvalue = ?rvalue);
13921421
if let Some(const_) = self.try_as_constant(value) {
13931422
*rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
13941423
} else if let Some(local) = self.try_as_local(value, location)
@@ -1397,6 +1426,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
13971426
*rvalue = Rvalue::Use(Operand::Copy(local.into()));
13981427
self.reused_locals.insert(local);
13991428
}
1429+
debug!(after_rvalue = ?rvalue);
14001430

14011431
return;
14021432
}

0 commit comments

Comments
 (0)