diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 26acd406ed8a9..30d8511153a2b 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -318,6 +318,8 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { // ConstProp will pick up the pieces and replace them by actual constants. StatementKind::Assign(box (place, Rvalue::Use(Operand::Constant(_)))) => { if let Some(final_locals) = self.replacements.place_fragments(place) { + // Put the deaggregated statements *after* the original one. + let location = location.successor_within_block(); for (field, ty, new_local) in final_locals { let rplace = self.tcx.mk_place_field(place, field, ty); let rvalue = Rvalue::Use(Operand::Move(rplace)); diff --git a/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff new file mode 100644 index 0000000000000..9e33215f2b5a6 --- /dev/null +++ b/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff @@ -0,0 +1,46 @@ +- // MIR for `constant` before ScalarReplacementOfAggregates ++ // MIR for `constant` after ScalarReplacementOfAggregates + + fn constant() -> () { + let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:15: +0:15 + let _1: (usize, u8); // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ let _4: usize; // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ let _5: u8; // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 + scope 1 { +- debug y => _1; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 ++ debug y => (usize, u8){ .0 => _4, .1 => _5, }; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 + let _2: usize; // in scope 1 at $DIR/sroa.rs:+3:9: +3:10 + scope 2 { + debug t => _2; // in scope 2 at $DIR/sroa.rs:+3:9: +3:10 + let _3: u8; // in scope 2 at $DIR/sroa.rs:+4:9: +4:10 + scope 3 { + debug u => _3; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 + } + } + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ nop; // scope 0 at $DIR/sroa.rs:+2:9: +2:10 + _1 = const _; // scope 0 at $DIR/sroa.rs:+2:13: +2:14 ++ _4 = move (_1.0: usize); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 ++ _5 = move (_1.1: u8); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 + StorageLive(_2); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 +- _2 = (_1.0: usize); // scope 1 at $DIR/sroa.rs:+3:13: +3:16 ++ _2 = _4; // scope 1 at $DIR/sroa.rs:+3:13: +3:16 + StorageLive(_3); // scope 2 at $DIR/sroa.rs:+4:9: +4:10 +- _3 = (_1.1: u8); // scope 2 at $DIR/sroa.rs:+4:13: +4:16 ++ _3 = _5; // scope 2 at $DIR/sroa.rs:+4:13: +4:16 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:15: +5:2 + StorageDead(_3); // scope 2 at $DIR/sroa.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/sroa.rs:+5:1: +5:2 +- StorageDead(_1); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ nop; // scope 0 at $DIR/sroa.rs:+5:1: +5:2 + return; // scope 0 at $DIR/sroa.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs index 471aac9f9d82d..b69de2e124ec6 100644 --- a/tests/mir-opt/sroa.rs +++ b/tests/mir-opt/sroa.rs @@ -87,6 +87,13 @@ fn ref_copies(x: &Foo) { let u = y.c; } +fn constant() { + const U: (usize, u8) = (5, 9); + let y = U; + let t = y.0; + let u = y.1; +} + fn main() { dropping(); enums(5); @@ -96,6 +103,7 @@ fn main() { escaping(); copies(Foo { a: 5, b: (), c: "a", d: Some(-4) }); ref_copies(&Foo { a: 5, b: (), c: "a", d: Some(-4) }); + constant(); } // EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff @@ -106,3 +114,4 @@ fn main() { // EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff // EMIT_MIR sroa.copies.ScalarReplacementOfAggregates.diff // EMIT_MIR sroa.ref_copies.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.constant.ScalarReplacementOfAggregates.diff