diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2025-07-05 22:53:19 +0000 |
|---|---|---|
| committer | Josh Stone <jistone@redhat.com> | 2025-07-10 13:30:37 -0700 |
| commit | 091578b73d370eae94e5f3fc999c198eb87b24f5 (patch) | |
| tree | 694464e2ef948c6ce5b5631fad99ab4816870e6b /tests | |
| parent | d53af551254344330472c12bfb17bc1363fc0ec1 (diff) | |
| download | rust-091578b73d370eae94e5f3fc999c198eb87b24f5.tar.gz rust-091578b73d370eae94e5f3fc999c198eb87b24f5.zip | |
Do not unify borrowed locals in CopyProp.
(cherry picked from commit bab9c752e836bb94d87249422d48f8c85b4f41a4)
Diffstat (limited to 'tests')
8 files changed, 358 insertions, 92 deletions
diff --git a/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-abort.diff new file mode 100644 index 00000000000..8c5e6a9e827 --- /dev/null +++ b/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-abort.diff @@ -0,0 +1,101 @@ +- // MIR for `borrow_in_loop` before CopyProp ++ // MIR for `borrow_in_loop` after CopyProp + + fn borrow_in_loop() -> () { + let mut _0: (); + let mut _1: bool; + let _3: bool; + let mut _4: !; + let mut _5: (); + let mut _7: bool; + let mut _9: bool; + let mut _10: bool; + let mut _11: &bool; + let _12: &bool; + let mut _13: bool; + let mut _14: bool; + let mut _15: bool; + let mut _16: !; + scope 1 { + debug c => _1; + let mut _2: &bool; + let mut _17: &bool; + scope 2 { + debug p => _2; + let _6: bool; + scope 3 { + debug a => _6; + let _8: bool; + scope 4 { + debug b => _8; + } + } + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _17 = const borrow_in_loop::promoted[0]; + _2 = &(*_17); +- StorageLive(_4); + goto -> bb1; + } + + bb1: { +- StorageLive(_6); + StorageLive(_7); + _7 = copy (*_2); + _6 = Not(move _7); + StorageDead(_7); +- StorageLive(_8); + StorageLive(_9); + _9 = copy (*_2); + _8 = Not(move _9); + StorageDead(_9); +- StorageLive(_10); +- _10 = copy _6; +- _1 = move _10; +- StorageDead(_10); ++ _1 = copy _6; + StorageLive(_11); + StorageLive(_12); + _12 = &_1; + _11 = &(*_12); + _2 = move _11; + StorageDead(_11); + StorageDead(_12); + StorageLive(_13); +- StorageLive(_14); +- _14 = copy _6; +- StorageLive(_15); +- _15 = copy _8; +- _13 = Ne(move _14, move _15); ++ _13 = Ne(copy _6, copy _8); + switchInt(move _13) -> [0: bb3, otherwise: bb2]; + } + + bb2: { +- StorageDead(_15); +- StorageDead(_14); + _0 = const (); + StorageDead(_13); +- StorageDead(_8); +- StorageDead(_6); +- StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + return; + } + + bb3: { +- StorageDead(_15); +- StorageDead(_14); +- _5 = const (); + StorageDead(_13); +- StorageDead(_8); +- StorageDead(_6); + goto -> bb1; + } + } + diff --git a/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-unwind.diff new file mode 100644 index 00000000000..8c5e6a9e827 --- /dev/null +++ b/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-unwind.diff @@ -0,0 +1,101 @@ +- // MIR for `borrow_in_loop` before CopyProp ++ // MIR for `borrow_in_loop` after CopyProp + + fn borrow_in_loop() -> () { + let mut _0: (); + let mut _1: bool; + let _3: bool; + let mut _4: !; + let mut _5: (); + let mut _7: bool; + let mut _9: bool; + let mut _10: bool; + let mut _11: &bool; + let _12: &bool; + let mut _13: bool; + let mut _14: bool; + let mut _15: bool; + let mut _16: !; + scope 1 { + debug c => _1; + let mut _2: &bool; + let mut _17: &bool; + scope 2 { + debug p => _2; + let _6: bool; + scope 3 { + debug a => _6; + let _8: bool; + scope 4 { + debug b => _8; + } + } + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _17 = const borrow_in_loop::promoted[0]; + _2 = &(*_17); +- StorageLive(_4); + goto -> bb1; + } + + bb1: { +- StorageLive(_6); + StorageLive(_7); + _7 = copy (*_2); + _6 = Not(move _7); + StorageDead(_7); +- StorageLive(_8); + StorageLive(_9); + _9 = copy (*_2); + _8 = Not(move _9); + StorageDead(_9); +- StorageLive(_10); +- _10 = copy _6; +- _1 = move _10; +- StorageDead(_10); ++ _1 = copy _6; + StorageLive(_11); + StorageLive(_12); + _12 = &_1; + _11 = &(*_12); + _2 = move _11; + StorageDead(_11); + StorageDead(_12); + StorageLive(_13); +- StorageLive(_14); +- _14 = copy _6; +- StorageLive(_15); +- _15 = copy _8; +- _13 = Ne(move _14, move _15); ++ _13 = Ne(copy _6, copy _8); + switchInt(move _13) -> [0: bb3, otherwise: bb2]; + } + + bb2: { +- StorageDead(_15); +- StorageDead(_14); + _0 = const (); + StorageDead(_13); +- StorageDead(_8); +- StorageDead(_6); +- StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + return; + } + + bb3: { +- StorageDead(_15); +- StorageDead(_14); +- _5 = const (); + StorageDead(_13); +- StorageDead(_8); +- StorageDead(_6); + goto -> bb1; + } + } + diff --git a/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff index 40e8c06f357..285cd0f6527 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff +++ b/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff @@ -7,14 +7,13 @@ let mut _3: &T; bb0: { -- _2 = copy _1; + _2 = copy _1; _3 = &_1; _0 = opaque::<&T>(copy _3) -> [return: bb1, unwind unreachable]; } bb1: { -- _0 = opaque::<T>(copy _2) -> [return: bb2, unwind unreachable]; -+ _0 = opaque::<T>(copy _1) -> [return: bb2, unwind unreachable]; + _0 = opaque::<T>(copy _2) -> [return: bb2, unwind unreachable]; } bb2: { diff --git a/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff index d09c96c0f2b..f189615ea95 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff +++ b/tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff @@ -7,14 +7,13 @@ let mut _3: &T; bb0: { -- _2 = copy _1; + _2 = copy _1; _3 = &_1; _0 = opaque::<&T>(copy _3) -> [return: bb1, unwind continue]; } bb1: { -- _0 = opaque::<T>(copy _2) -> [return: bb2, unwind continue]; -+ _0 = opaque::<T>(copy _1) -> [return: bb2, unwind continue]; + _0 = opaque::<T>(copy _2) -> [return: bb2, unwind continue]; } bb2: { diff --git a/tests/mir-opt/copy-prop/borrowed_local.rs b/tests/mir-opt/copy-prop/borrowed_local.rs index 8db19fbd377..68cdc57483a 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.rs +++ b/tests/mir-opt/copy-prop/borrowed_local.rs @@ -50,10 +50,11 @@ fn compare_address() -> bool { fn borrowed<T: Copy + Freeze>(x: T) -> bool { // CHECK-LABEL: fn borrowed( // CHECK: bb0: { + // CHECK-NEXT: _2 = copy _1; // CHECK-NEXT: _3 = &_1; // CHECK-NEXT: _0 = opaque::<&T>(copy _3) // CHECK: bb1: { - // CHECK-NEXT: _0 = opaque::<T>(copy _1) + // CHECK-NEXT: _0 = opaque::<T>(copy _2) mir! { { let a = x; @@ -94,11 +95,45 @@ fn non_freeze<T: Copy>(x: T) -> bool { } } +/// We must not unify a borrowed local with another that may be written-to before the borrow is +/// read again. As we have no aliasing model yet, this means forbidding unifying borrowed locals. +fn borrow_in_loop() { + // CHECK-LABEL: fn borrow_in_loop( + // CHECK: debug c => [[c:_.*]]; + // CHECK: debug p => [[p:_.*]]; + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK-NOT: &[[a]] + // CHECK-NOT: &[[b]] + // CHECK: [[a]] = Not({{.*}}); + // CHECK-NOT: &[[a]] + // CHECK-NOT: &[[b]] + // CHECK: [[b]] = Not({{.*}}); + // CHECK-NOT: &[[a]] + // CHECK-NOT: &[[b]] + // CHECK: &[[c]] + // CHECK-NOT: &[[a]] + // CHECK-NOT: &[[b]] + let mut c; + let mut p = &false; + loop { + let a = !*p; + let b = !*p; + c = a; + p = &c; + if a != b { + return; + } + } +} + fn main() { assert!(!compare_address()); non_freeze(5); + borrow_in_loop(); } // EMIT_MIR borrowed_local.compare_address.CopyProp.diff // EMIT_MIR borrowed_local.borrowed.CopyProp.diff // EMIT_MIR borrowed_local.non_freeze.CopyProp.diff +// EMIT_MIR borrowed_local.borrow_in_loop.CopyProp.diff diff --git a/tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff b/tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff index eab06b1ba1e..baa71501047 100644 --- a/tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff +++ b/tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff @@ -16,11 +16,10 @@ _3 = const 'b'; _5 = copy _3; _6 = &_3; -- _4 = copy _5; + _4 = copy _5; (*_1) = copy (*_6); _6 = &_5; -- _7 = dump_var::<char>(copy _4) -> [return: bb1, unwind unreachable]; -+ _7 = dump_var::<char>(copy _5) -> [return: bb1, unwind unreachable]; + _7 = dump_var::<char>(copy _4) -> [return: bb1, unwind unreachable]; } bb1: { diff --git a/tests/mir-opt/copy-prop/write_to_borrowed.rs b/tests/mir-opt/copy-prop/write_to_borrowed.rs index 58809749103..05aa2fba18d 100644 --- a/tests/mir-opt/copy-prop/write_to_borrowed.rs +++ b/tests/mir-opt/copy-prop/write_to_borrowed.rs @@ -27,13 +27,13 @@ fn main() { _5 = _3; // CHECK-NEXT: _6 = &_3; _6 = &_3; - // CHECK-NOT: {{_.*}} = {{_.*}}; + // CHECK-NEXT: _4 = copy _5; _4 = _5; // CHECK-NEXT: (*_1) = copy (*_6); *_1 = *_6; // CHECK-NEXT: _6 = &_5; _6 = &_5; - // CHECK-NEXT: _7 = dump_var::<char>(copy _5) + // CHECK-NEXT: _7 = dump_var::<char>(copy _4) Call(_7 = dump_var(_4), ReturnTo(bb1), UnwindUnreachable()) } bb1 = { Return() } diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir index cbdd194afd3..97036745009 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir @@ -10,18 +10,18 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 let mut _8: &&usize; let _9: &usize; let mut _10: &&usize; - let mut _13: bool; - let mut _14: &&usize; - let _15: &usize; + let mut _15: bool; let mut _16: &&usize; - let mut _19: bool; - let mut _20: &&usize; - let _21: &usize; - let mut _22: &&usize; + let _17: &usize; + let mut _18: &&usize; let mut _23: bool; let mut _24: &&usize; let _25: &usize; let mut _26: &&usize; + let mut _29: bool; + let mut _30: &&usize; + let _31: &usize; + let mut _32: &&usize; scope 1 { debug a => _4; debug b => _5; @@ -30,39 +30,47 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 scope 2 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) { debug self => _8; debug other => _10; + let mut _11: &usize; + let mut _12: &usize; scope 3 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _4; - debug other => _6; - let mut _11: usize; - let mut _12: usize; + debug self => _11; + debug other => _12; + let mut _13: usize; + let mut _14: usize; } } scope 4 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _14; - debug other => _16; + debug self => _16; + debug other => _18; + let mut _19: &usize; + let mut _20: &usize; scope 5 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _7; - debug other => _5; - let mut _17: usize; - let mut _18: usize; + debug self => _19; + debug other => _20; + let mut _21: usize; + let mut _22: usize; } } scope 6 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _20; - debug other => _22; + debug self => _24; + debug other => _26; + let mut _27: &usize; + let mut _28: &usize; scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _6; - debug other => _4; + debug self => _27; + debug other => _28; } } scope 8 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) { - debug self => _24; - debug other => _26; + debug self => _30; + debug other => _32; + let mut _33: &usize; + let mut _34: &usize; scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) { - debug self => _5; - debug other => _7; - let mut _27: usize; - let mut _28: usize; + debug self => _33; + debug other => _34; + let mut _35: usize; + let mut _36: usize; } } } @@ -73,17 +81,23 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 _5 = &((*_3).1: usize); _6 = &((*_3).2: usize); _7 = &((*_3).3: usize); - StorageLive(_13); + StorageLive(_15); StorageLive(_8); _8 = &_4; StorageLive(_10); StorageLive(_9); _9 = copy _6; _10 = &_9; - _11 = copy ((*_3).0: usize); - _12 = copy ((*_3).2: usize); - _13 = Le(copy _11, copy _12); - switchInt(move _13) -> [0: bb1, otherwise: bb2]; + StorageLive(_11); + StorageLive(_12); + _11 = copy _4; + _12 = copy _6; + _13 = copy ((*_3).0: usize); + _14 = copy ((*_3).2: usize); + _15 = Le(copy _13, copy _14); + StorageDead(_12); + StorageDead(_11); + switchInt(move _15) -> [0: bb1, otherwise: bb2]; } bb1: { @@ -97,89 +111,107 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 StorageDead(_9); StorageDead(_10); StorageDead(_8); - StorageLive(_19); - StorageLive(_14); - _14 = &_7; + StorageLive(_23); StorageLive(_16); - StorageLive(_15); - _15 = copy _5; - _16 = &_15; - StorageLive(_17); - _17 = copy ((*_3).3: usize); + _16 = &_7; StorageLive(_18); - _18 = copy ((*_3).1: usize); - _19 = Le(move _17, move _18); - StorageDead(_18); - StorageDead(_17); - switchInt(move _19) -> [0: bb3, otherwise: bb8]; + StorageLive(_17); + _17 = copy _5; + _18 = &_17; + StorageLive(_19); + StorageLive(_20); + _19 = copy _7; + _20 = copy _5; + StorageLive(_21); + _21 = copy ((*_3).3: usize); + StorageLive(_22); + _22 = copy ((*_3).1: usize); + _23 = Le(move _21, move _22); + StorageDead(_22); + StorageDead(_21); + StorageDead(_20); + StorageDead(_19); + switchInt(move _23) -> [0: bb3, otherwise: bb8]; } bb3: { - StorageDead(_15); + StorageDead(_17); + StorageDead(_18); StorageDead(_16); - StorageDead(_14); goto -> bb4; } bb4: { - StorageLive(_23); - StorageLive(_20); - _20 = &_6; - StorageLive(_22); - StorageLive(_21); - _21 = copy _4; - _22 = &_21; - _23 = Le(copy _12, copy _11); - switchInt(move _23) -> [0: bb5, otherwise: bb6]; - } - - bb5: { - StorageDead(_21); - StorageDead(_22); - StorageDead(_20); - _0 = const false; - goto -> bb7; - } - - bb6: { - StorageDead(_21); - StorageDead(_22); - StorageDead(_20); + StorageLive(_29); StorageLive(_24); - _24 = &_5; + _24 = &_6; StorageLive(_26); StorageLive(_25); - _25 = copy _7; + _25 = copy _4; _26 = &_25; StorageLive(_27); - _27 = copy ((*_3).1: usize); StorageLive(_28); - _28 = copy ((*_3).3: usize); - _0 = Le(move _27, move _28); + _27 = copy _6; + _28 = copy _4; + _29 = Le(copy _14, copy _13); StorageDead(_28); StorageDead(_27); + switchInt(move _29) -> [0: bb5, otherwise: bb6]; + } + + bb5: { StorageDead(_25); StorageDead(_26); StorageDead(_24); + _0 = const false; + goto -> bb7; + } + + bb6: { + StorageDead(_25); + StorageDead(_26); + StorageDead(_24); + StorageLive(_30); + _30 = &_5; + StorageLive(_32); + StorageLive(_31); + _31 = copy _7; + _32 = &_31; + StorageLive(_33); + StorageLive(_34); + _33 = copy _5; + _34 = copy _7; + StorageLive(_35); + _35 = copy ((*_3).1: usize); + StorageLive(_36); + _36 = copy ((*_3).3: usize); + _0 = Le(move _35, move _36); + StorageDead(_36); + StorageDead(_35); + StorageDead(_34); + StorageDead(_33); + StorageDead(_31); + StorageDead(_32); + StorageDead(_30); goto -> bb7; } bb7: { - StorageDead(_23); + StorageDead(_29); goto -> bb9; } bb8: { - StorageDead(_15); + StorageDead(_17); + StorageDead(_18); StorageDead(_16); - StorageDead(_14); _0 = const true; goto -> bb9; } bb9: { - StorageDead(_19); - StorageDead(_13); + StorageDead(_23); + StorageDead(_15); return; } } |
