Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 18e6b5a

Browse files
committedSep 18, 2023
Use a ConstValue instead.
1 parent 6d5a46b commit 18e6b5a

21 files changed

+419
-152
lines changed
 

‎compiler/rustc_mir_transform/src/dataflow_const_prop.rs

Lines changed: 137 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,23 @@
33
//! Currently, this pass only propagates scalar values.
44
55
use rustc_const_eval::const_eval::CheckAlignment;
6-
use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable};
6+
use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, PlaceTy, Projectable};
77
use rustc_data_structures::fx::FxHashMap;
88
use rustc_hir::def::DefKind;
9-
use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ConstValue, InterpResult, Scalar};
9+
use rustc_middle::mir::interpret::{
10+
AllocId, ConstAllocation, ConstValue, GlobalAlloc, InterpResult, Scalar,
11+
};
1012
use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
1113
use rustc_middle::mir::*;
12-
use rustc_middle::ty::layout::TyAndLayout;
14+
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
1315
use rustc_middle::ty::{self, Ty, TyCtxt};
1416
use rustc_mir_dataflow::value_analysis::{
1517
Map, PlaceIndex, State, TrackElem, ValueAnalysis, ValueAnalysisWrapper, ValueOrPlace,
1618
};
1719
use rustc_mir_dataflow::{lattice::FlatSet, Analysis, Results, ResultsVisitor};
1820
use rustc_span::def_id::DefId;
1921
use rustc_span::DUMMY_SP;
20-
use rustc_target::abi::{Align, FieldIdx, VariantIdx};
22+
use rustc_target::abi::{Align, FieldIdx, Size, VariantIdx, FIRST_VARIANT};
2123

2224
use crate::MirPass;
2325

@@ -546,110 +548,130 @@ impl<'tcx, 'locals> Collector<'tcx, 'locals> {
546548

547549
fn try_make_constant(
548550
&self,
551+
ecx: &mut InterpCx<'tcx, 'tcx, DummyMachine>,
549552
place: Place<'tcx>,
550553
state: &State<FlatSet<Scalar>>,
551554
map: &Map,
552555
) -> Option<ConstantKind<'tcx>> {
553556
let ty = place.ty(self.local_decls, self.patch.tcx).ty;
554557
let place = map.find(place.as_ref())?;
555-
if let FlatSet::Elem(Scalar::Int(value)) = state.get_idx(place, map) {
556-
Some(ConstantKind::Val(ConstValue::Scalar(value.into()), ty))
558+
let layout = ecx.layout_of(ty).ok()?;
559+
if layout.abi.is_scalar() {
560+
let value = propagatable_scalar(*ecx.tcx, place, state, map)?;
561+
Some(ConstantKind::Val(ConstValue::Scalar(value), ty))
557562
} else {
558-
let valtree = self.try_make_valtree(place, ty, state, map)?;
559-
let constant = ty::Const::new_value(self.patch.tcx, valtree, ty);
560-
Some(ConstantKind::Ty(constant))
563+
let alloc_id = ecx
564+
.intern_with_temp_alloc(layout, |ecx, dest| {
565+
try_write_constant(ecx, dest, place, ty, state, map)
566+
})
567+
.ok()?;
568+
Some(ConstantKind::Val(ConstValue::Indirect { alloc_id, offset: Size::ZERO }, ty))
561569
}
562570
}
571+
}
563572

564-
fn try_make_valtree(
565-
&self,
566-
place: PlaceIndex,
567-
ty: Ty<'tcx>,
568-
state: &State<FlatSet<Scalar>>,
569-
map: &Map,
570-
) -> Option<ty::ValTree<'tcx>> {
571-
let tcx = self.patch.tcx;
572-
match ty.kind() {
573-
// ZSTs.
574-
ty::FnDef(..) => Some(ty::ValTree::zst()),
575-
576-
// Scalars.
577-
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
578-
if let FlatSet::Elem(Scalar::Int(value)) = state.get_idx(place, map) {
579-
Some(ty::ValTree::Leaf(value))
580-
} else {
581-
None
582-
}
573+
fn propagatable_scalar<'tcx>(
574+
tcx: TyCtxt<'tcx>,
575+
place: PlaceIndex,
576+
state: &State<FlatSet<Scalar>>,
577+
map: &Map,
578+
) -> Option<Scalar> {
579+
if let FlatSet::Elem(value) = state.get_idx(place, map) {
580+
if let Scalar::Ptr(pointer, _) = value {
581+
let (alloc_id, _) = pointer.into_parts();
582+
match tcx.global_alloc(alloc_id) {
583+
// Do not propagate pointers to functions and vtables as they may
584+
// lose identify during codegen, which is a miscompilation.
585+
GlobalAlloc::Function(_) | GlobalAlloc::VTable(..) => return None,
586+
GlobalAlloc::Memory(_) | GlobalAlloc::Static(_) => {}
583587
}
588+
}
589+
Some(value)
590+
} else {
591+
None
592+
}
593+
}
584594

585-
// Unsupported for now.
586-
ty::Array(_, _) => None,
587-
588-
ty::Tuple(elem_tys) => {
589-
let branches = elem_tys
590-
.iter()
591-
.enumerate()
592-
.map(|(i, ty)| {
593-
let field = map.apply(place, TrackElem::Field(FieldIdx::from_usize(i)))?;
594-
self.try_make_valtree(field, ty, state, map)
595-
})
596-
.collect::<Option<Vec<_>>>()?;
597-
Some(ty::ValTree::Branch(tcx.arena.alloc_from_iter(branches.into_iter())))
595+
#[instrument(level = "trace", skip(ecx, state, map))]
596+
fn try_write_constant<'tcx>(
597+
ecx: &mut InterpCx<'_, 'tcx, DummyMachine>,
598+
dest: &PlaceTy<'tcx>,
599+
place: PlaceIndex,
600+
ty: Ty<'tcx>,
601+
state: &State<FlatSet<Scalar>>,
602+
map: &Map,
603+
) -> InterpResult<'tcx> {
604+
let layout = ecx.layout_of(ty)?;
605+
match ty.kind() {
606+
// ZSTs. Nothing to do.
607+
ty::FnDef(..) => {}
608+
609+
// Scalars.
610+
_ if layout.abi.is_scalar() => {
611+
let value = propagatable_scalar(*ecx.tcx, place, state, map).ok_or(err_inval!(ConstPropNonsense))?;
612+
ecx.write_immediate(Immediate::Scalar(value), dest)?;
613+
}
614+
// Those are scalars, must be handled above.
615+
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => bug!(),
616+
617+
ty::Tuple(elem_tys) => {
618+
for (i, elem) in elem_tys.iter().enumerate() {
619+
let field = map.apply(place, TrackElem::Field(FieldIdx::from_usize(i))).ok_or(err_inval!(ConstPropNonsense))?;
620+
let field_dest = ecx.project_field(dest, i)?;
621+
try_write_constant(ecx, &field_dest, field, elem, state, map)?;
598622
}
623+
}
599624

600-
ty::Adt(def, args) => {
601-
if def.is_union() {
602-
return None;
603-
}
625+
ty::Adt(def, args) => {
626+
if def.is_union() {
627+
throw_inval!(ConstPropNonsense)
628+
}
604629

605-
let (variant_idx, variant_def, variant_place) = if def.is_enum() {
606-
let discr = map.apply(place, TrackElem::Discriminant)?;
607-
let FlatSet::Elem(Scalar::Int(discr)) = state.get_idx(discr, map) else {
608-
return None;
609-
};
610-
let discr_bits = discr.assert_bits(discr.size());
611-
let (variant, _) =
612-
def.discriminants(tcx).find(|(_, var)| discr_bits == var.val)?;
613-
let variant_place = map.apply(place, TrackElem::Variant(variant))?;
614-
let variant_int = ty::ValTree::Leaf(variant.as_u32().into());
615-
(Some(variant_int), def.variant(variant), variant_place)
616-
} else {
617-
(None, def.non_enum_variant(), place)
630+
let (variant_idx, variant_def, variant_place, variant_dest) = if def.is_enum() {
631+
let discr = map.apply(place, TrackElem::Discriminant).ok_or(err_inval!(ConstPropNonsense))?;
632+
let FlatSet::Elem(Scalar::Int(discr)) = state.get_idx(discr, map) else {
633+
throw_inval!(ConstPropNonsense)
618634
};
619-
620-
let branches = variant_def
621-
.fields
622-
.iter_enumerated()
623-
.map(|(i, field)| {
624-
let ty = field.ty(tcx, args);
625-
let field = map.apply(variant_place, TrackElem::Field(i))?;
626-
self.try_make_valtree(field, ty, state, map)
627-
})
628-
.collect::<Option<Vec<_>>>()?;
629-
Some(ty::ValTree::Branch(
630-
tcx.arena.alloc_from_iter(variant_idx.into_iter().chain(branches)),
631-
))
635+
let discr_bits = discr.assert_bits(discr.size());
636+
let (variant, _) = def.discriminants(*ecx.tcx).find(|(_, var)| discr_bits == var.val).ok_or(err_inval!(ConstPropNonsense))?;
637+
let variant_place = map.apply(place, TrackElem::Variant(variant)).ok_or(err_inval!(ConstPropNonsense))?;
638+
let variant_dest = ecx.project_downcast(dest, variant)?;
639+
(variant, def.variant(variant), variant_place, variant_dest)
640+
} else {
641+
(FIRST_VARIANT, def.non_enum_variant(), place, dest.clone())
642+
};
643+
644+
for (i, field) in variant_def.fields.iter_enumerated() {
645+
let ty = field.ty(*ecx.tcx, args);
646+
let field = map.apply(variant_place, TrackElem::Field(i)).ok_or(err_inval!(ConstPropNonsense))?;
647+
let field_dest = ecx.project_field(&variant_dest, i.as_usize())?;
648+
try_write_constant(ecx, &field_dest, field, ty, state, map)?;
632649
}
650+
ecx.write_discriminant(variant_idx, dest)?;
651+
}
652+
653+
// Unsupported for now.
654+
ty::Array(_, _)
633655

634-
// Do not attempt to support indirection in constants.
635-
ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) | ty::Str | ty::Slice(_) => None,
636-
637-
ty::Never
638-
| ty::Foreign(..)
639-
| ty::Alias(..)
640-
| ty::Param(_)
641-
| ty::Bound(..)
642-
| ty::Placeholder(..)
643-
| ty::Closure(..)
644-
| ty::Generator(..)
645-
| ty::Dynamic(..) => None,
646-
647-
ty::Error(_)
648-
| ty::Infer(..)
649-
| ty::GeneratorWitness(..)
650-
| ty::GeneratorWitnessMIR(..) => bug!(),
656+
// Do not attempt to support indirection in constants.
657+
| ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) | ty::Str | ty::Slice(_)
658+
659+
| ty::Never
660+
| ty::Foreign(..)
661+
| ty::Alias(..)
662+
| ty::Param(_)
663+
| ty::Bound(..)
664+
| ty::Placeholder(..)
665+
| ty::Closure(..)
666+
| ty::Generator(..)
667+
| ty::Dynamic(..) => throw_inval!(ConstPropNonsense),
668+
669+
ty::Error(_) | ty::Infer(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => {
670+
bug!()
651671
}
652672
}
673+
674+
Ok(())
653675
}
654676

655677
impl<'mir, 'tcx>
@@ -667,8 +689,13 @@ impl<'mir, 'tcx>
667689
) {
668690
match &statement.kind {
669691
StatementKind::Assign(box (_, rvalue)) => {
670-
OperandCollector { state, visitor: self, map: &results.analysis.0.map }
671-
.visit_rvalue(rvalue, location);
692+
OperandCollector {
693+
state,
694+
visitor: self,
695+
ecx: &mut results.analysis.0.ecx,
696+
map: &results.analysis.0.map,
697+
}
698+
.visit_rvalue(rvalue, location);
672699
}
673700
_ => (),
674701
}
@@ -686,7 +713,12 @@ impl<'mir, 'tcx>
686713
// Don't overwrite the assignment if it already uses a constant (to keep the span).
687714
}
688715
StatementKind::Assign(box (place, _)) => {
689-
if let Some(value) = self.try_make_constant(place, state, &results.analysis.0.map) {
716+
if let Some(value) = self.try_make_constant(
717+
&mut results.analysis.0.ecx,
718+
place,
719+
state,
720+
&results.analysis.0.map,
721+
) {
690722
self.patch.assignments.insert(location, value);
691723
}
692724
}
@@ -701,8 +733,13 @@ impl<'mir, 'tcx>
701733
terminator: &'mir Terminator<'tcx>,
702734
location: Location,
703735
) {
704-
OperandCollector { state, visitor: self, map: &results.analysis.0.map }
705-
.visit_terminator(terminator, location);
736+
OperandCollector {
737+
state,
738+
visitor: self,
739+
ecx: &mut results.analysis.0.ecx,
740+
map: &results.analysis.0.map,
741+
}
742+
.visit_terminator(terminator, location);
706743
}
707744
}
708745

@@ -757,6 +794,7 @@ impl<'tcx> MutVisitor<'tcx> for Patch<'tcx> {
757794
struct OperandCollector<'tcx, 'map, 'locals, 'a> {
758795
state: &'a State<FlatSet<Scalar>>,
759796
visitor: &'a mut Collector<'tcx, 'locals>,
797+
ecx: &'map mut InterpCx<'tcx, 'tcx, DummyMachine>,
760798
map: &'map Map,
761799
}
762800

@@ -769,15 +807,17 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
769807
location: Location,
770808
) {
771809
if let PlaceElem::Index(local) = elem
772-
&& let Some(value) = self.visitor.try_make_constant(local.into(), self.state, self.map)
810+
&& let Some(value) = self.visitor.try_make_constant(self.ecx, local.into(), self.state, self.map)
773811
{
774812
self.visitor.patch.before_effect.insert((location, local.into()), value);
775813
}
776814
}
777815

778816
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
779817
if let Some(place) = operand.place() {
780-
if let Some(value) = self.visitor.try_make_constant(place, self.state, self.map) {
818+
if let Some(value) =
819+
self.visitor.try_make_constant(self.ecx, place, self.state, self.map)
820+
{
781821
self.visitor.patch.before_effect.insert((location, place), value);
782822
} else if !place.projection.is_empty() {
783823
// Try to propagate into `Index` projections.
@@ -802,8 +842,9 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm
802842
}
803843

804844
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
805-
unimplemented!()
845+
false
806846
}
847+
807848
fn alignment_check_failed(
808849
_ecx: &InterpCx<'mir, 'tcx, Self>,
809850
_has: Align,

‎tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
let _10: std::option::Option<u16>;
4343
scope 7 {
4444
- debug o => _10;
45-
+ debug o => const Option::<u16>::Some(99);
45+
+ debug o => const Option::<u16>::Some(99_u16);
4646
let _17: u32;
4747
let _18: u32;
4848
scope 8 {
@@ -82,7 +82,7 @@
8282
_15 = const false;
8383
_16 = const 123_u32;
8484
StorageLive(_10);
85-
_10 = const Option::<u16>::Some(99);
85+
_10 = const Option::<u16>::Some(99_u16);
8686
_17 = const 32_u32;
8787
_18 = const 32_u32;
8888
StorageLive(_11);
@@ -98,3 +98,7 @@
9898
}
9999
}
100100

101+
alloc10 (size: 4, align: 2) {
102+
01 00 63 00 │ ..c.
103+
}
104+

‎tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
- _6 = CheckedAdd(_4, _5);
4444
- assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> [success: bb1, unwind unreachable];
4545
+ _5 = const 2_i32;
46-
+ _6 = const (3, false);
46+
+ _6 = const (3_i32, false);
4747
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> [success: bb1, unwind unreachable];
4848
}
4949

@@ -76,5 +76,13 @@
7676
StorageDead(_1);
7777
return;
7878
}
79+
+ }
80+
+
81+
+ alloc5 (size: 8, align: 4) {
82+
+ 00 00 00 80 01 __ __ __ │ .....░░░
83+
+ }
84+
+
85+
+ alloc4 (size: 8, align: 4) {
86+
+ 03 00 00 00 00 __ __ __ │ .....░░░
7987
}
8088

‎tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
- _6 = CheckedAdd(_4, _5);
4444
- assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> [success: bb1, unwind continue];
4545
+ _5 = const 2_i32;
46-
+ _6 = const (3, false);
46+
+ _6 = const (3_i32, false);
4747
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> [success: bb1, unwind continue];
4848
}
4949

@@ -76,5 +76,13 @@
7676
StorageDead(_1);
7777
return;
7878
}
79+
+ }
80+
+
81+
+ alloc5 (size: 8, align: 4) {
82+
+ 00 00 00 80 01 __ __ __ │ .....░░░
83+
+ }
84+
+
85+
+ alloc4 (size: 8, align: 4) {
86+
+ 03 00 00 00 00 __ __ __ │ .....░░░
7987
}
8088

‎tests/mir-opt/dataflow-const-prop/checked.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
21
// unit-test: DataflowConstProp
32
// compile-flags: -Coverflow-checks=on
3+
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
44

55
// EMIT_MIR checked.main.DataflowConstProp.diff
66
#[allow(arithmetic_overflow)]

‎tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
bb0: {
2525
StorageLive(_1);
2626
- _1 = E::V1(const 0_i32);
27-
+ _1 = const E::V1(0);
27+
+ _1 = const E::V1(0_i32);
2828
StorageLive(_2);
2929
- _3 = discriminant(_1);
3030
- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2];
@@ -60,5 +60,9 @@
6060
StorageDead(_1);
6161
return;
6262
}
63+
+ }
64+
+
65+
+ alloc19 (size: 8, align: 4) {
66+
+ 00 00 00 00 00 00 00 00 │ ........
6367
}
6468

‎tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
bb0: {
2525
StorageLive(_1);
2626
- _1 = E::V1(const 0_i32);
27-
+ _1 = const E::V1(0);
27+
+ _1 = const E::V1(0_i32);
2828
StorageLive(_2);
2929
- _3 = discriminant(_1);
3030
- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2];
@@ -60,5 +60,9 @@
6060
StorageDead(_1);
6161
return;
6262
}
63+
+ }
64+
+
65+
+ alloc19 (size: 8, align: 4) {
66+
+ 00 00 00 00 00 00 00 00 │ ........
6367
}
6468

‎tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
StorageLive(_2);
4646
_2 = const {alloc1: &E};
4747
- _1 = (*_2);
48-
+ _1 = const E::V1(0);
48+
+ _1 = const E::V1(0_i32);
4949
StorageDead(_2);
5050
StorageLive(_3);
5151
- _4 = discriminant(_1);
@@ -80,7 +80,8 @@
8080
StorageLive(_7);
8181
StorageLive(_8);
8282
_8 = const {alloc2: &&E};
83-
_7 = (*_8);
83+
- _7 = (*_8);
84+
+ _7 = const {alloc14: &E};
8485
StorageDead(_8);
8586
StorageLive(_9);
8687
_10 = discriminant((*_7));
@@ -113,12 +114,18 @@
113114
}
114115
}
115116

116-
alloc2 (static: RC, size: 4, align: 4) {
117-
╾─alloc14─╼ │ ╾──╼
117+
- alloc2 (static: RC, size: 4, align: 4) {
118+
- ╾─alloc14─╼ │ ╾──╼
119+
+ alloc20 (size: 8, align: 4) {
120+
+ 00 00 00 00 00 00 00 00 │ ........
118121
}
119122

120123
alloc14 (size: 8, align: 4) {
121124
01 00 00 00 04 00 00 00 │ ........
125+
+ }
126+
+
127+
+ alloc2 (static: RC, size: 4, align: 4) {
128+
+ ╾─alloc14─╼ │ ╾──╼
122129
}
123130

124131
alloc1 (static: statics::C, size: 8, align: 4) {

‎tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
StorageLive(_2);
4646
_2 = const {alloc1: &E};
4747
- _1 = (*_2);
48-
+ _1 = const E::V1(0);
48+
+ _1 = const E::V1(0_i32);
4949
StorageDead(_2);
5050
StorageLive(_3);
5151
- _4 = discriminant(_1);
@@ -80,7 +80,8 @@
8080
StorageLive(_7);
8181
StorageLive(_8);
8282
_8 = const {alloc2: &&E};
83-
_7 = (*_8);
83+
- _7 = (*_8);
84+
+ _7 = const {alloc14: &E};
8485
StorageDead(_8);
8586
StorageLive(_9);
8687
_10 = discriminant((*_7));
@@ -113,12 +114,18 @@
113114
}
114115
}
115116

116-
alloc2 (static: RC, size: 8, align: 8) {
117-
╾───────alloc14───────╼ │ ╾──────╼
117+
- alloc2 (static: RC, size: 8, align: 8) {
118+
- ╾───────alloc14───────╼ │ ╾──────╼
119+
+ alloc20 (size: 8, align: 4) {
120+
+ 00 00 00 00 00 00 00 00 │ ........
118121
}
119122

120123
alloc14 (size: 8, align: 4) {
121124
01 00 00 00 04 00 00 00 │ ........
125+
+ }
126+
+
127+
+ alloc2 (static: RC, size: 8, align: 8) {
128+
+ ╾───────alloc14───────╼ │ ╾──────╼
122129
}
123130

124131
alloc1 (static: statics::C, size: 8, align: 4) {

‎tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
_3 = const 1_u8;
2323
- _4 = CheckedAdd(_2, _3);
2424
- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable];
25-
+ _4 = const (0, true);
25+
+ _4 = const (0_u8, true);
2626
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind unreachable];
2727
}
2828

@@ -35,5 +35,9 @@
3535
_0 = const ();
3636
return;
3737
}
38+
+ }
39+
+
40+
+ alloc2 (size: 2, align: 1) {
41+
+ 00 01 │ ..
3842
}
3943

‎tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
_3 = const 1_u8;
2323
- _4 = CheckedAdd(_2, _3);
2424
- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
25-
+ _4 = const (0, true);
25+
+ _4 = const (0_u8, true);
2626
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind continue];
2727
}
2828

@@ -35,5 +35,9 @@
3535
_0 = const ();
3636
return;
3737
}
38+
+ }
39+
+
40+
+ alloc2 (size: 2, align: 1) {
41+
+ 00 01 │ ..
3842
}
3943

‎tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717

1818
bb0: {
1919
StorageLive(_1);
20-
- _1 = I32(const 0_i32);
21-
+ _1 = const I32(0);
20+
_1 = I32(const 0_i32);
2221
StorageLive(_2);
2322
StorageLive(_3);
2423
StorageLive(_4);
@@ -32,7 +31,7 @@
3231
StorageDead(_5);
3332
StorageDead(_4);
3433
- _2 = I32(move _3);
35-
+ _2 = const I32(0);
34+
+ _2 = I32(const 0_i32);
3635
StorageDead(_3);
3736
_0 = const ();
3837
StorageDead(_2);

‎tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@
3030
StorageLive(_3);
3131
StorageLive(_4);
3232
_14 = const _;
33-
_4 = _14;
34-
_3 = _4;
35-
_2 = move _3 as &[u32] (PointerCoercion(Unsize));
33+
- _4 = _14;
34+
- _3 = _4;
35+
- _2 = move _3 as &[u32] (PointerCoercion(Unsize));
36+
+ _4 = const {alloc3: &[u32; 3]};
37+
+ _3 = const {alloc3: &[u32; 3]};
38+
+ _2 = const {alloc3: &[u32; 3]} as &[u32] (PointerCoercion(Unsize));
3639
StorageDead(_3);
3740
StorageLive(_6);
3841
_6 = const 1_usize;
@@ -73,5 +76,9 @@
7376
StorageDead(_1);
7477
return;
7578
}
79+
+ }
80+
+
81+
+ alloc3 (size: 12, align: 4) {
82+
+ 01 00 00 00 02 00 00 00 03 00 00 00 │ ............
7683
}
7784

‎tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@
3030
StorageLive(_3);
3131
StorageLive(_4);
3232
_14 = const _;
33-
_4 = _14;
34-
_3 = _4;
35-
_2 = move _3 as &[u32] (PointerCoercion(Unsize));
33+
- _4 = _14;
34+
- _3 = _4;
35+
- _2 = move _3 as &[u32] (PointerCoercion(Unsize));
36+
+ _4 = const {alloc3: &[u32; 3]};
37+
+ _3 = const {alloc3: &[u32; 3]};
38+
+ _2 = const {alloc3: &[u32; 3]} as &[u32] (PointerCoercion(Unsize));
3639
StorageDead(_3);
3740
StorageLive(_6);
3841
_6 = const 1_usize;
@@ -73,5 +76,9 @@
7376
StorageDead(_1);
7477
return;
7578
}
79+
+ }
80+
+
81+
+ alloc3 (size: 12, align: 4) {
82+
+ 01 00 00 00 02 00 00 00 03 00 00 00 │ ............
7683
}
7784

‎tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@
3030
StorageLive(_3);
3131
StorageLive(_4);
3232
_14 = const _;
33-
_4 = _14;
34-
_3 = _4;
35-
_2 = move _3 as &[u32] (PointerCoercion(Unsize));
33+
- _4 = _14;
34+
- _3 = _4;
35+
- _2 = move _3 as &[u32] (PointerCoercion(Unsize));
36+
+ _4 = const {alloc3: &[u32; 3]};
37+
+ _3 = const {alloc3: &[u32; 3]};
38+
+ _2 = const {alloc3: &[u32; 3]} as &[u32] (PointerCoercion(Unsize));
3639
StorageDead(_3);
3740
StorageLive(_6);
3841
_6 = const 1_usize;
@@ -73,5 +76,9 @@
7376
StorageDead(_1);
7477
return;
7578
}
79+
+ }
80+
+
81+
+ alloc3 (size: 12, align: 4) {
82+
+ 01 00 00 00 02 00 00 00 03 00 00 00 │ ............
7683
}
7784

‎tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@
3030
StorageLive(_3);
3131
StorageLive(_4);
3232
_14 = const _;
33-
_4 = _14;
34-
_3 = _4;
35-
_2 = move _3 as &[u32] (PointerCoercion(Unsize));
33+
- _4 = _14;
34+
- _3 = _4;
35+
- _2 = move _3 as &[u32] (PointerCoercion(Unsize));
36+
+ _4 = const {alloc3: &[u32; 3]};
37+
+ _3 = const {alloc3: &[u32; 3]};
38+
+ _2 = const {alloc3: &[u32; 3]} as &[u32] (PointerCoercion(Unsize));
3639
StorageDead(_3);
3740
StorageLive(_6);
3841
_6 = const 1_usize;
@@ -73,5 +76,9 @@
7376
StorageDead(_1);
7477
return;
7578
}
79+
+ }
80+
+
81+
+ alloc3 (size: 12, align: 4) {
82+
+ 01 00 00 00 02 00 00 00 03 00 00 00 │ ............
7683
}
7784

‎tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656

5757
bb0: {
5858
StorageLive(_1);
59-
- _1 = S(const 1_i32);
60-
+ _1 = const S(1);
59+
_1 = S(const 1_i32);
6160
StorageLive(_2);
6261
StorageLive(_3);
6362
- _3 = (_1.0: i32);
@@ -94,22 +93,27 @@
9493
StorageDead(_11);
9594
StorageLive(_16);
9695
_16 = const {alloc1: &&BigStruct};
97-
_22 = deref_copy (*_16);
96+
- _22 = deref_copy (*_16);
97+
+ _22 = const {alloc15: &BigStruct};
9898
StorageLive(_12);
99-
_23 = deref_copy (*_16);
99+
- _23 = deref_copy (*_16);
100100
- _12 = ((*_23).0: S);
101+
+ _23 = const {alloc15: &BigStruct};
101102
+ _12 = const S(1_i32);
102103
StorageLive(_13);
103-
_24 = deref_copy (*_16);
104+
- _24 = deref_copy (*_16);
104105
- _13 = ((*_24).1: u8);
106+
+ _24 = const {alloc15: &BigStruct};
105107
+ _13 = const 5_u8;
106108
StorageLive(_14);
107-
_25 = deref_copy (*_16);
109+
- _25 = deref_copy (*_16);
108110
- _14 = ((*_25).2: f32);
111+
+ _25 = const {alloc15: &BigStruct};
109112
+ _14 = const 7f32;
110113
StorageLive(_15);
111-
_26 = deref_copy (*_16);
114+
- _26 = deref_copy (*_16);
112115
- _15 = ((*_26).3: S);
116+
+ _26 = const {alloc15: &BigStruct};
113117
+ _15 = const S(13_i32);
114118
StorageDead(_16);
115119
StorageLive(_17);
@@ -126,7 +130,7 @@
126130
- _21 = _15;
127131
- _17 = BigStruct(move _18, move _19, move _20, move _21);
128132
+ _21 = const S(13_i32);
129-
+ _17 = const BigStruct(S(1), 5, 7f32, S(13));
133+
+ _17 = const BigStruct(S(1_i32), 5_u8, 7f32, S(13_i32));
130134
StorageDead(_21);
131135
StorageDead(_20);
132136
StorageDead(_19);
@@ -148,11 +152,17 @@
148152
}
149153
}
150154

151-
alloc1 (static: STAT, size: 4, align: 4) {
152-
╾─alloc15─╼ │ ╾──╼
155+
- alloc1 (static: STAT, size: 4, align: 4) {
156+
- ╾─alloc15─╼ │ ╾──╼
157+
+ alloc17 (size: 16, align: 4) {
158+
+ 01 00 00 00 00 00 e0 40 0d 00 00 00 05 __ __ __ │ .......@.....░░░
153159
}
154160

155161
alloc15 (size: 16, align: 4) {
156162
01 00 00 00 00 00 e0 40 0d 00 00 00 05 __ __ __ │ .......@.....░░░
163+
+ }
164+
+
165+
+ alloc1 (static: STAT, size: 4, align: 4) {
166+
+ ╾─alloc15─╼ │ ╾──╼
157167
}
158168

‎tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656

5757
bb0: {
5858
StorageLive(_1);
59-
- _1 = S(const 1_i32);
60-
+ _1 = const S(1);
59+
_1 = S(const 1_i32);
6160
StorageLive(_2);
6261
StorageLive(_3);
6362
- _3 = (_1.0: i32);
@@ -94,22 +93,27 @@
9493
StorageDead(_11);
9594
StorageLive(_16);
9695
_16 = const {alloc1: &&BigStruct};
97-
_22 = deref_copy (*_16);
96+
- _22 = deref_copy (*_16);
97+
+ _22 = const {alloc15: &BigStruct};
9898
StorageLive(_12);
99-
_23 = deref_copy (*_16);
99+
- _23 = deref_copy (*_16);
100100
- _12 = ((*_23).0: S);
101+
+ _23 = const {alloc15: &BigStruct};
101102
+ _12 = const S(1_i32);
102103
StorageLive(_13);
103-
_24 = deref_copy (*_16);
104+
- _24 = deref_copy (*_16);
104105
- _13 = ((*_24).1: u8);
106+
+ _24 = const {alloc15: &BigStruct};
105107
+ _13 = const 5_u8;
106108
StorageLive(_14);
107-
_25 = deref_copy (*_16);
109+
- _25 = deref_copy (*_16);
108110
- _14 = ((*_25).2: f32);
111+
+ _25 = const {alloc15: &BigStruct};
109112
+ _14 = const 7f32;
110113
StorageLive(_15);
111-
_26 = deref_copy (*_16);
114+
- _26 = deref_copy (*_16);
112115
- _15 = ((*_26).3: S);
116+
+ _26 = const {alloc15: &BigStruct};
113117
+ _15 = const S(13_i32);
114118
StorageDead(_16);
115119
StorageLive(_17);
@@ -126,7 +130,7 @@
126130
- _21 = _15;
127131
- _17 = BigStruct(move _18, move _19, move _20, move _21);
128132
+ _21 = const S(13_i32);
129-
+ _17 = const BigStruct(S(1), 5, 7f32, S(13));
133+
+ _17 = const BigStruct(S(1_i32), 5_u8, 7f32, S(13_i32));
130134
StorageDead(_21);
131135
StorageDead(_20);
132136
StorageDead(_19);
@@ -148,11 +152,17 @@
148152
}
149153
}
150154

151-
alloc1 (static: STAT, size: 8, align: 8) {
152-
╾───────alloc15───────╼ │ ╾──────╼
155+
- alloc1 (static: STAT, size: 8, align: 8) {
156+
- ╾───────alloc15───────╼ │ ╾──────╼
157+
+ alloc17 (size: 16, align: 4) {
158+
+ 01 00 00 00 00 00 e0 40 0d 00 00 00 05 __ __ __ │ .......@.....░░░
153159
}
154160

155161
alloc15 (size: 16, align: 4) {
156162
01 00 00 00 00 00 e0 40 0d 00 00 00 05 __ __ __ │ .......@.....░░░
163+
+ }
164+
+
165+
+ alloc1 (static: STAT, size: 8, align: 8) {
166+
+ ╾───────alloc15───────╼ │ ╾──────╼
157167
}
158168

‎tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff renamed to ‎tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.32bit.diff

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
bb0: {
3434
StorageLive(_1);
3535
- _1 = (const 1_i32, const 2_i32);
36-
+ _1 = const (1, 2);
36+
+ _1 = const (1_i32, 2_i32);
3737
StorageLive(_2);
3838
StorageLive(_3);
3939
StorageLive(_4);
@@ -50,7 +50,7 @@
5050
+ _2 = const 6_i32;
5151
StorageDead(_3);
5252
- _1 = (const 2_i32, const 3_i32);
53-
+ _1 = const (2, 3);
53+
+ _1 = const (2_i32, 3_i32);
5454
StorageLive(_6);
5555
StorageLive(_7);
5656
StorageLive(_8);
@@ -76,12 +76,12 @@
7676
+ _12 = const 6_i32;
7777
StorageLive(_13);
7878
- _13 = _1;
79-
+ _13 = const (2, 3);
79+
+ _13 = const (2_i32, 3_i32);
8080
StorageLive(_14);
8181
- _14 = _6;
8282
- _11 = (move _12, move _13, move _14);
8383
+ _14 = const 11_i32;
84-
+ _11 = const (6, (2, 3), 11);
84+
+ _11 = const (6_i32, (2_i32, 3_i32), 11_i32);
8585
StorageDead(_14);
8686
StorageDead(_13);
8787
StorageDead(_12);
@@ -92,5 +92,21 @@
9292
StorageDead(_1);
9393
return;
9494
}
95+
+ }
96+
+
97+
+ alloc9 (size: 16, align: 4) {
98+
+ 02 00 00 00 03 00 00 00 06 00 00 00 0b 00 00 00 │ ................
99+
+ }
100+
+
101+
+ alloc7 (size: 8, align: 4) {
102+
+ 02 00 00 00 03 00 00 00 │ ........
103+
+ }
104+
+
105+
+ alloc5 (size: 8, align: 4) {
106+
+ 02 00 00 00 03 00 00 00 │ ........
107+
+ }
108+
+
109+
+ alloc4 (size: 8, align: 4) {
110+
+ 01 00 00 00 02 00 00 00 │ ........
95111
}
96112

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
- // MIR for `main` before DataflowConstProp
2+
+ // MIR for `main` after DataflowConstProp
3+
4+
fn main() -> () {
5+
let mut _0: ();
6+
let mut _1: (i32, i32);
7+
let mut _3: i32;
8+
let mut _4: i32;
9+
let mut _5: i32;
10+
let mut _7: i32;
11+
let mut _8: i32;
12+
let mut _9: i32;
13+
let mut _10: i32;
14+
let mut _12: i32;
15+
let mut _13: (i32, i32);
16+
let mut _14: i32;
17+
scope 1 {
18+
debug a => _1;
19+
let _2: i32;
20+
scope 2 {
21+
debug b => _2;
22+
let _6: i32;
23+
scope 3 {
24+
debug c => _6;
25+
let _11: (i32, (i32, i32), i32);
26+
scope 4 {
27+
debug d => _11;
28+
}
29+
}
30+
}
31+
}
32+
33+
bb0: {
34+
StorageLive(_1);
35+
- _1 = (const 1_i32, const 2_i32);
36+
+ _1 = const (1_i32, 2_i32);
37+
StorageLive(_2);
38+
StorageLive(_3);
39+
StorageLive(_4);
40+
- _4 = (_1.0: i32);
41+
+ _4 = const 1_i32;
42+
StorageLive(_5);
43+
- _5 = (_1.1: i32);
44+
- _3 = Add(move _4, move _5);
45+
+ _5 = const 2_i32;
46+
+ _3 = const 3_i32;
47+
StorageDead(_5);
48+
StorageDead(_4);
49+
- _2 = Add(move _3, const 3_i32);
50+
+ _2 = const 6_i32;
51+
StorageDead(_3);
52+
- _1 = (const 2_i32, const 3_i32);
53+
+ _1 = const (2_i32, 3_i32);
54+
StorageLive(_6);
55+
StorageLive(_7);
56+
StorageLive(_8);
57+
- _8 = (_1.0: i32);
58+
+ _8 = const 2_i32;
59+
StorageLive(_9);
60+
- _9 = (_1.1: i32);
61+
- _7 = Add(move _8, move _9);
62+
+ _9 = const 3_i32;
63+
+ _7 = const 5_i32;
64+
StorageDead(_9);
65+
StorageDead(_8);
66+
StorageLive(_10);
67+
- _10 = _2;
68+
- _6 = Add(move _7, move _10);
69+
+ _10 = const 6_i32;
70+
+ _6 = const 11_i32;
71+
StorageDead(_10);
72+
StorageDead(_7);
73+
StorageLive(_11);
74+
StorageLive(_12);
75+
- _12 = _2;
76+
+ _12 = const 6_i32;
77+
StorageLive(_13);
78+
- _13 = _1;
79+
+ _13 = const (2_i32, 3_i32);
80+
StorageLive(_14);
81+
- _14 = _6;
82+
- _11 = (move _12, move _13, move _14);
83+
+ _14 = const 11_i32;
84+
+ _11 = const (6_i32, (2_i32, 3_i32), 11_i32);
85+
StorageDead(_14);
86+
StorageDead(_13);
87+
StorageDead(_12);
88+
_0 = const ();
89+
StorageDead(_11);
90+
StorageDead(_6);
91+
StorageDead(_2);
92+
StorageDead(_1);
93+
return;
94+
}
95+
+ }
96+
+
97+
+ alloc9 (size: 16, align: 4) {
98+
+ 02 00 00 00 03 00 00 00 06 00 00 00 0b 00 00 00 │ ................
99+
+ }
100+
+
101+
+ alloc7 (size: 8, align: 4) {
102+
+ 02 00 00 00 03 00 00 00 │ ........
103+
+ }
104+
+
105+
+ alloc5 (size: 8, align: 4) {
106+
+ 02 00 00 00 03 00 00 00 │ ........
107+
+ }
108+
+
109+
+ alloc4 (size: 8, align: 4) {
110+
+ 01 00 00 00 02 00 00 00 │ ........
111+
}
112+

‎tests/mir-opt/dataflow-const-prop/tuple.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// unit-test: DataflowConstProp
2+
// EMIT_MIR_FOR_EACH_BIT_WIDTH
23

34
// EMIT_MIR tuple.main.DataflowConstProp.diff
45
fn main() {

0 commit comments

Comments
 (0)
Please sign in to comment.