diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/mir-opt | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/mir-opt')
521 files changed, 23025 insertions, 0 deletions
diff --git a/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff b/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff new file mode 100644 index 000000000..57e298625 --- /dev/null +++ b/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff @@ -0,0 +1,29 @@ +- // MIR for `encode` before SimplifyBranchSame ++ // MIR for `encode` after SimplifyBranchSame + + fn encode(_1: Type) -> Type { + debug v => _1; // in scope 0 at $DIR/76803_regression.rs:+0:15: +0:16 + let mut _0: Type; // return place in scope 0 at $DIR/76803_regression.rs:+0:27: +0:31 + let mut _2: isize; // in scope 0 at $DIR/76803_regression.rs:+2:9: +2:16 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/76803_regression.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/76803_regression.rs:+1:5: +1:12 + } + + bb1: { + _0 = move _1; // scope 0 at $DIR/76803_regression.rs:+3:14: +3:15 + goto -> bb3; // scope 0 at $DIR/76803_regression.rs:+3:14: +3:15 + } + + bb2: { + Deinit(_0); // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27 + discriminant(_0) = 1; // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27 + goto -> bb3; // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27 + } + + bb3: { + return; // scope 0 at $DIR/76803_regression.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/76803_regression.rs b/src/test/mir-opt/76803_regression.rs new file mode 100644 index 000000000..05dc3c978 --- /dev/null +++ b/src/test/mir-opt/76803_regression.rs @@ -0,0 +1,19 @@ +// compile-flags: -Z mir-opt-level=1 +// EMIT_MIR 76803_regression.encode.SimplifyBranchSame.diff + +#[derive(Debug, Eq, PartialEq)] +pub enum Type { + A, + B, +} + +pub fn encode(v: Type) -> Type { + match v { + Type::A => Type::B, + _ => v, + } +} + +fn main() { + assert_eq!(Type::B, encode(Type::A)); +} diff --git a/src/test/mir-opt/README.md b/src/test/mir-opt/README.md new file mode 100644 index 000000000..a0550466c --- /dev/null +++ b/src/test/mir-opt/README.md @@ -0,0 +1,39 @@ +This folder contains tests for MIR optimizations. + +The `mir-opt` test format emits MIR to extra files that you can automatically update by specifying +`--bless` on the command line (just like `ui` tests updating `.stderr` files). + +# `--bless`able test format + +By default 32 bit and 64 bit targets use the same dump files, which can be problematic in the +presence of pointers in constants or other bit width dependent things. In that case you can add + +``` +// EMIT_MIR_FOR_EACH_BIT_WIDTH +``` + +to your test, causing separate files to be generated for 32bit and 64bit systems. + +## Emit a diff of the mir for a specific optimization + +This is what you want most often when you want to see how an optimization changes the MIR. + +``` +// EMIT_MIR $file_name_of_some_mir_dump.diff +``` + +## Emit mir after a specific optimization + +Use this if you are just interested in the final state after an optimization. + +``` +// EMIT_MIR $file_name_of_some_mir_dump.after.mir +``` + +## Emit mir before a specific optimization + +This exists mainly for completeness and is rarely useful. + +``` +// EMIT_MIR $file_name_of_some_mir_dump.before.mir +``` diff --git a/src/test/mir-opt/address-of.rs b/src/test/mir-opt/address-of.rs new file mode 100644 index 000000000..c4bea5613 --- /dev/null +++ b/src/test/mir-opt/address-of.rs @@ -0,0 +1,47 @@ +// EMIT_MIR address_of.address_of_reborrow.SimplifyCfg-initial.after.mir + +fn address_of_reborrow() { + let y = &[0; 10]; + let mut z = &mut [0; 10]; + + y as *const _; + y as *const [i32; 10]; + y as *const dyn Send; + y as *const [i32]; + y as *const i32; // This is a cast, not a coercion + + let p: *const _ = y; + let p: *const [i32; 10] = y; + let p: *const dyn Send = y; + let p: *const [i32] = y; + + z as *const _; + z as *const [i32; 10]; + z as *const dyn Send; + z as *const [i32]; + + let p: *const _ = z; + let p: *const [i32; 10] = z; + let p: *const dyn Send = z; + let p: *const [i32] = z; + + z as *mut _; + z as *mut [i32; 10]; + z as *mut dyn Send; + z as *mut [i32]; + + let p: *mut _ = z; + let p: *mut [i32; 10] = z; + let p: *mut dyn Send = z; + let p: *mut [i32] = z; +} + +// The normal borrows here should be preserved +// EMIT_MIR address_of.borrow_and_cast.SimplifyCfg-initial.after.mir +fn borrow_and_cast(mut x: i32) { + let p = &x as *const i32; + let q = &mut x as *const i32; + let r = &mut x as *mut i32; +} + +fn main() {} diff --git a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..d41a66871 --- /dev/null +++ b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -0,0 +1,308 @@ +// MIR for `address_of_reborrow` after SimplifyCfg-initial + +| User Type Annotations +| 0: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:7:5: 7:18, inferred_ty: *const [i32; 10] +| 1: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send +| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10] +| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10] +| 4: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10] +| 5: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10] +| 6: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send +| 7: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send +| 8: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32] +| 9: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32] +| 10: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:18:5: 18:18, inferred_ty: *const [i32; 10] +| 11: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send +| 12: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10] +| 13: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10] +| 14: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10] +| 15: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10] +| 16: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send +| 17: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send +| 18: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32] +| 19: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32] +| 20: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10] +| 21: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send +| 22: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10] +| 23: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10] +| 24: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10] +| 25: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10] +| 26: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send +| 27: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send +| 28: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32] +| 29: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32] +| +fn address_of_reborrow() -> () { + let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:+0:26: +0:26 + let _1: &[i32; 10]; // in scope 0 at $DIR/address-of.rs:+1:9: +1:10 + let _2: [i32; 10]; // in scope 0 at $DIR/address-of.rs:+1:14: +1:21 + let mut _4: [i32; 10]; // in scope 0 at $DIR/address-of.rs:+2:22: +2:29 + let _5: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+4:5: +4:18 + let mut _6: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+4:5: +4:18 + let _7: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+5:5: +5:26 + let _8: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+6:5: +6:25 + let mut _9: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+6:5: +6:25 + let mut _10: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+6:5: +6:6 + let _11: *const [i32]; // in scope 0 at $DIR/address-of.rs:+7:5: +7:22 + let mut _12: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+7:5: +7:6 + let _13: *const i32; // in scope 0 at $DIR/address-of.rs:+8:5: +8:20 + let mut _14: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+8:5: +8:6 + let mut _18: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+12:30: +12:31 + let mut _20: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+13:27: +13:28 + let _21: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+15:5: +15:18 + let mut _22: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+15:5: +15:18 + let _23: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+16:5: +16:26 + let _24: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+17:5: +17:25 + let mut _25: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+17:5: +17:25 + let mut _26: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+17:5: +17:6 + let _27: *const [i32]; // in scope 0 at $DIR/address-of.rs:+18:5: +18:22 + let mut _28: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+18:5: +18:6 + let mut _32: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+22:30: +22:31 + let mut _34: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+23:27: +23:28 + let _35: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+25:5: +25:16 + let mut _36: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+25:5: +25:16 + let _37: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+26:5: +26:24 + let _38: *mut dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+27:5: +27:23 + let mut _39: *mut dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+27:5: +27:23 + let mut _40: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+27:5: +27:6 + let _41: *mut [i32]; // in scope 0 at $DIR/address-of.rs:+28:5: +28:20 + let mut _42: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+28:5: +28:6 + let mut _46: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+32:28: +32:29 + let mut _48: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+33:25: +33:26 + scope 1 { + debug y => _1; // in scope 1 at $DIR/address-of.rs:+1:9: +1:10 + let mut _3: &mut [i32; 10]; // in scope 1 at $DIR/address-of.rs:+2:9: +2:14 + scope 2 { + debug z => _3; // in scope 2 at $DIR/address-of.rs:+2:9: +2:14 + let _15: *const [i32; 10] as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 2 at $DIR/address-of.rs:+10:9: +10:10 + scope 3 { + debug p => _15; // in scope 3 at $DIR/address-of.rs:+10:9: +10:10 + let _16: *const [i32; 10] as UserTypeProjection { base: UserType(4), projs: [] }; // in scope 3 at $DIR/address-of.rs:+11:9: +11:10 + scope 4 { + debug p => _16; // in scope 4 at $DIR/address-of.rs:+11:9: +11:10 + let _17: *const dyn std::marker::Send as UserTypeProjection { base: UserType(6), projs: [] }; // in scope 4 at $DIR/address-of.rs:+12:9: +12:10 + scope 5 { + debug p => _17; // in scope 5 at $DIR/address-of.rs:+12:9: +12:10 + let _19: *const [i32] as UserTypeProjection { base: UserType(8), projs: [] }; // in scope 5 at $DIR/address-of.rs:+13:9: +13:10 + scope 6 { + debug p => _19; // in scope 6 at $DIR/address-of.rs:+13:9: +13:10 + let _29: *const [i32; 10] as UserTypeProjection { base: UserType(12), projs: [] }; // in scope 6 at $DIR/address-of.rs:+20:9: +20:10 + scope 7 { + debug p => _29; // in scope 7 at $DIR/address-of.rs:+20:9: +20:10 + let _30: *const [i32; 10] as UserTypeProjection { base: UserType(14), projs: [] }; // in scope 7 at $DIR/address-of.rs:+21:9: +21:10 + scope 8 { + debug p => _30; // in scope 8 at $DIR/address-of.rs:+21:9: +21:10 + let _31: *const dyn std::marker::Send as UserTypeProjection { base: UserType(16), projs: [] }; // in scope 8 at $DIR/address-of.rs:+22:9: +22:10 + scope 9 { + debug p => _31; // in scope 9 at $DIR/address-of.rs:+22:9: +22:10 + let _33: *const [i32] as UserTypeProjection { base: UserType(18), projs: [] }; // in scope 9 at $DIR/address-of.rs:+23:9: +23:10 + scope 10 { + debug p => _33; // in scope 10 at $DIR/address-of.rs:+23:9: +23:10 + let _43: *mut [i32; 10] as UserTypeProjection { base: UserType(22), projs: [] }; // in scope 10 at $DIR/address-of.rs:+30:9: +30:10 + scope 11 { + debug p => _43; // in scope 11 at $DIR/address-of.rs:+30:9: +30:10 + let _44: *mut [i32; 10] as UserTypeProjection { base: UserType(24), projs: [] }; // in scope 11 at $DIR/address-of.rs:+31:9: +31:10 + scope 12 { + debug p => _44; // in scope 12 at $DIR/address-of.rs:+31:9: +31:10 + let _45: *mut dyn std::marker::Send as UserTypeProjection { base: UserType(26), projs: [] }; // in scope 12 at $DIR/address-of.rs:+32:9: +32:10 + scope 13 { + debug p => _45; // in scope 13 at $DIR/address-of.rs:+32:9: +32:10 + let _47: *mut [i32] as UserTypeProjection { base: UserType(28), projs: [] }; // in scope 13 at $DIR/address-of.rs:+33:9: +33:10 + scope 14 { + debug p => _47; // in scope 14 at $DIR/address-of.rs:+33:9: +33:10 + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/address-of.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/address-of.rs:+1:14: +1:21 + _2 = [const 0_i32; 10]; // scope 0 at $DIR/address-of.rs:+1:14: +1:21 + _1 = &_2; // scope 0 at $DIR/address-of.rs:+1:13: +1:21 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/address-of.rs:+1:9: +1:10 + StorageLive(_3); // scope 1 at $DIR/address-of.rs:+2:9: +2:14 + StorageLive(_4); // scope 1 at $DIR/address-of.rs:+2:22: +2:29 + _4 = [const 0_i32; 10]; // scope 1 at $DIR/address-of.rs:+2:22: +2:29 + _3 = &mut _4; // scope 1 at $DIR/address-of.rs:+2:17: +2:29 + FakeRead(ForLet(None), _3); // scope 1 at $DIR/address-of.rs:+2:9: +2:14 + StorageLive(_5); // scope 2 at $DIR/address-of.rs:+4:5: +4:18 + StorageLive(_6); // scope 2 at $DIR/address-of.rs:+4:5: +4:18 + _6 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+4:5: +4:6 + AscribeUserType(_6, o, UserTypeProjection { base: UserType(0), projs: [] }); // scope 2 at $DIR/address-of.rs:+4:5: +4:18 + _5 = _6; // scope 2 at $DIR/address-of.rs:+4:5: +4:18 + StorageDead(_6); // scope 2 at $DIR/address-of.rs:+4:18: +4:19 + StorageDead(_5); // scope 2 at $DIR/address-of.rs:+4:18: +4:19 + StorageLive(_7); // scope 2 at $DIR/address-of.rs:+5:5: +5:26 + _7 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+5:5: +5:6 + StorageDead(_7); // scope 2 at $DIR/address-of.rs:+5:26: +5:27 + StorageLive(_8); // scope 2 at $DIR/address-of.rs:+6:5: +6:25 + StorageLive(_9); // scope 2 at $DIR/address-of.rs:+6:5: +6:25 + StorageLive(_10); // scope 2 at $DIR/address-of.rs:+6:5: +6:6 + _10 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+6:5: +6:6 + _9 = move _10 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:+6:5: +6:6 + StorageDead(_10); // scope 2 at $DIR/address-of.rs:+6:5: +6:6 + AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/address-of.rs:+6:5: +6:25 + _8 = _9; // scope 2 at $DIR/address-of.rs:+6:5: +6:25 + StorageDead(_9); // scope 2 at $DIR/address-of.rs:+6:25: +6:26 + StorageDead(_8); // scope 2 at $DIR/address-of.rs:+6:25: +6:26 + StorageLive(_11); // scope 2 at $DIR/address-of.rs:+7:5: +7:22 + StorageLive(_12); // scope 2 at $DIR/address-of.rs:+7:5: +7:6 + _12 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+7:5: +7:6 + _11 = move _12 as *const [i32] (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:+7:5: +7:6 + StorageDead(_12); // scope 2 at $DIR/address-of.rs:+7:5: +7:6 + StorageDead(_11); // scope 2 at $DIR/address-of.rs:+7:22: +7:23 + StorageLive(_13); // scope 2 at $DIR/address-of.rs:+8:5: +8:20 + StorageLive(_14); // scope 2 at $DIR/address-of.rs:+8:5: +8:6 + _14 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+8:5: +8:6 + _13 = move _14 as *const i32 (Pointer(ArrayToPointer)); // scope 2 at $DIR/address-of.rs:+8:5: +8:20 + StorageDead(_14); // scope 2 at $DIR/address-of.rs:+8:19: +8:20 + StorageDead(_13); // scope 2 at $DIR/address-of.rs:+8:20: +8:21 + StorageLive(_15); // scope 2 at $DIR/address-of.rs:+10:9: +10:10 + _15 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+10:23: +10:24 + FakeRead(ForLet(None), _15); // scope 2 at $DIR/address-of.rs:+10:9: +10:10 + AscribeUserType(_15, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address-of.rs:+10:12: +10:20 + StorageLive(_16); // scope 3 at $DIR/address-of.rs:+11:9: +11:10 + _16 = &raw const (*_1); // scope 3 at $DIR/address-of.rs:+11:31: +11:32 + FakeRead(ForLet(None), _16); // scope 3 at $DIR/address-of.rs:+11:9: +11:10 + AscribeUserType(_16, o, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address-of.rs:+11:12: +11:28 + StorageLive(_17); // scope 4 at $DIR/address-of.rs:+12:9: +12:10 + StorageLive(_18); // scope 4 at $DIR/address-of.rs:+12:30: +12:31 + _18 = &raw const (*_1); // scope 4 at $DIR/address-of.rs:+12:30: +12:31 + _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 4 at $DIR/address-of.rs:+12:30: +12:31 + StorageDead(_18); // scope 4 at $DIR/address-of.rs:+12:30: +12:31 + FakeRead(ForLet(None), _17); // scope 4 at $DIR/address-of.rs:+12:9: +12:10 + AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address-of.rs:+12:12: +12:27 + StorageLive(_19); // scope 5 at $DIR/address-of.rs:+13:9: +13:10 + StorageLive(_20); // scope 5 at $DIR/address-of.rs:+13:27: +13:28 + _20 = &raw const (*_1); // scope 5 at $DIR/address-of.rs:+13:27: +13:28 + _19 = move _20 as *const [i32] (Pointer(Unsize)); // scope 5 at $DIR/address-of.rs:+13:27: +13:28 + StorageDead(_20); // scope 5 at $DIR/address-of.rs:+13:27: +13:28 + FakeRead(ForLet(None), _19); // scope 5 at $DIR/address-of.rs:+13:9: +13:10 + AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address-of.rs:+13:12: +13:24 + StorageLive(_21); // scope 6 at $DIR/address-of.rs:+15:5: +15:18 + StorageLive(_22); // scope 6 at $DIR/address-of.rs:+15:5: +15:18 + _22 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+15:5: +15:6 + AscribeUserType(_22, o, UserTypeProjection { base: UserType(10), projs: [] }); // scope 6 at $DIR/address-of.rs:+15:5: +15:18 + _21 = _22; // scope 6 at $DIR/address-of.rs:+15:5: +15:18 + StorageDead(_22); // scope 6 at $DIR/address-of.rs:+15:18: +15:19 + StorageDead(_21); // scope 6 at $DIR/address-of.rs:+15:18: +15:19 + StorageLive(_23); // scope 6 at $DIR/address-of.rs:+16:5: +16:26 + _23 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+16:5: +16:6 + StorageDead(_23); // scope 6 at $DIR/address-of.rs:+16:26: +16:27 + StorageLive(_24); // scope 6 at $DIR/address-of.rs:+17:5: +17:25 + StorageLive(_25); // scope 6 at $DIR/address-of.rs:+17:5: +17:25 + StorageLive(_26); // scope 6 at $DIR/address-of.rs:+17:5: +17:6 + _26 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+17:5: +17:6 + _25 = move _26 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:+17:5: +17:6 + StorageDead(_26); // scope 6 at $DIR/address-of.rs:+17:5: +17:6 + AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] }); // scope 6 at $DIR/address-of.rs:+17:5: +17:25 + _24 = _25; // scope 6 at $DIR/address-of.rs:+17:5: +17:25 + StorageDead(_25); // scope 6 at $DIR/address-of.rs:+17:25: +17:26 + StorageDead(_24); // scope 6 at $DIR/address-of.rs:+17:25: +17:26 + StorageLive(_27); // scope 6 at $DIR/address-of.rs:+18:5: +18:22 + StorageLive(_28); // scope 6 at $DIR/address-of.rs:+18:5: +18:6 + _28 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+18:5: +18:6 + _27 = move _28 as *const [i32] (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:+18:5: +18:6 + StorageDead(_28); // scope 6 at $DIR/address-of.rs:+18:5: +18:6 + StorageDead(_27); // scope 6 at $DIR/address-of.rs:+18:22: +18:23 + StorageLive(_29); // scope 6 at $DIR/address-of.rs:+20:9: +20:10 + _29 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+20:23: +20:24 + FakeRead(ForLet(None), _29); // scope 6 at $DIR/address-of.rs:+20:9: +20:10 + AscribeUserType(_29, o, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address-of.rs:+20:12: +20:20 + StorageLive(_30); // scope 7 at $DIR/address-of.rs:+21:9: +21:10 + _30 = &raw const (*_3); // scope 7 at $DIR/address-of.rs:+21:31: +21:32 + FakeRead(ForLet(None), _30); // scope 7 at $DIR/address-of.rs:+21:9: +21:10 + AscribeUserType(_30, o, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address-of.rs:+21:12: +21:28 + StorageLive(_31); // scope 8 at $DIR/address-of.rs:+22:9: +22:10 + StorageLive(_32); // scope 8 at $DIR/address-of.rs:+22:30: +22:31 + _32 = &raw const (*_3); // scope 8 at $DIR/address-of.rs:+22:30: +22:31 + _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 8 at $DIR/address-of.rs:+22:30: +22:31 + StorageDead(_32); // scope 8 at $DIR/address-of.rs:+22:30: +22:31 + FakeRead(ForLet(None), _31); // scope 8 at $DIR/address-of.rs:+22:9: +22:10 + AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address-of.rs:+22:12: +22:27 + StorageLive(_33); // scope 9 at $DIR/address-of.rs:+23:9: +23:10 + StorageLive(_34); // scope 9 at $DIR/address-of.rs:+23:27: +23:28 + _34 = &raw const (*_3); // scope 9 at $DIR/address-of.rs:+23:27: +23:28 + _33 = move _34 as *const [i32] (Pointer(Unsize)); // scope 9 at $DIR/address-of.rs:+23:27: +23:28 + StorageDead(_34); // scope 9 at $DIR/address-of.rs:+23:27: +23:28 + FakeRead(ForLet(None), _33); // scope 9 at $DIR/address-of.rs:+23:9: +23:10 + AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address-of.rs:+23:12: +23:24 + StorageLive(_35); // scope 10 at $DIR/address-of.rs:+25:5: +25:16 + StorageLive(_36); // scope 10 at $DIR/address-of.rs:+25:5: +25:16 + _36 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+25:5: +25:6 + AscribeUserType(_36, o, UserTypeProjection { base: UserType(20), projs: [] }); // scope 10 at $DIR/address-of.rs:+25:5: +25:16 + _35 = _36; // scope 10 at $DIR/address-of.rs:+25:5: +25:16 + StorageDead(_36); // scope 10 at $DIR/address-of.rs:+25:16: +25:17 + StorageDead(_35); // scope 10 at $DIR/address-of.rs:+25:16: +25:17 + StorageLive(_37); // scope 10 at $DIR/address-of.rs:+26:5: +26:24 + _37 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+26:5: +26:6 + StorageDead(_37); // scope 10 at $DIR/address-of.rs:+26:24: +26:25 + StorageLive(_38); // scope 10 at $DIR/address-of.rs:+27:5: +27:23 + StorageLive(_39); // scope 10 at $DIR/address-of.rs:+27:5: +27:23 + StorageLive(_40); // scope 10 at $DIR/address-of.rs:+27:5: +27:6 + _40 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+27:5: +27:6 + _39 = move _40 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:+27:5: +27:6 + StorageDead(_40); // scope 10 at $DIR/address-of.rs:+27:5: +27:6 + AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] }); // scope 10 at $DIR/address-of.rs:+27:5: +27:23 + _38 = _39; // scope 10 at $DIR/address-of.rs:+27:5: +27:23 + StorageDead(_39); // scope 10 at $DIR/address-of.rs:+27:23: +27:24 + StorageDead(_38); // scope 10 at $DIR/address-of.rs:+27:23: +27:24 + StorageLive(_41); // scope 10 at $DIR/address-of.rs:+28:5: +28:20 + StorageLive(_42); // scope 10 at $DIR/address-of.rs:+28:5: +28:6 + _42 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+28:5: +28:6 + _41 = move _42 as *mut [i32] (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:+28:5: +28:6 + StorageDead(_42); // scope 10 at $DIR/address-of.rs:+28:5: +28:6 + StorageDead(_41); // scope 10 at $DIR/address-of.rs:+28:20: +28:21 + StorageLive(_43); // scope 10 at $DIR/address-of.rs:+30:9: +30:10 + _43 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+30:21: +30:22 + FakeRead(ForLet(None), _43); // scope 10 at $DIR/address-of.rs:+30:9: +30:10 + AscribeUserType(_43, o, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address-of.rs:+30:12: +30:18 + StorageLive(_44); // scope 11 at $DIR/address-of.rs:+31:9: +31:10 + _44 = &raw mut (*_3); // scope 11 at $DIR/address-of.rs:+31:29: +31:30 + FakeRead(ForLet(None), _44); // scope 11 at $DIR/address-of.rs:+31:9: +31:10 + AscribeUserType(_44, o, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address-of.rs:+31:12: +31:26 + StorageLive(_45); // scope 12 at $DIR/address-of.rs:+32:9: +32:10 + StorageLive(_46); // scope 12 at $DIR/address-of.rs:+32:28: +32:29 + _46 = &raw mut (*_3); // scope 12 at $DIR/address-of.rs:+32:28: +32:29 + _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 12 at $DIR/address-of.rs:+32:28: +32:29 + StorageDead(_46); // scope 12 at $DIR/address-of.rs:+32:28: +32:29 + FakeRead(ForLet(None), _45); // scope 12 at $DIR/address-of.rs:+32:9: +32:10 + AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address-of.rs:+32:12: +32:25 + StorageLive(_47); // scope 13 at $DIR/address-of.rs:+33:9: +33:10 + StorageLive(_48); // scope 13 at $DIR/address-of.rs:+33:25: +33:26 + _48 = &raw mut (*_3); // scope 13 at $DIR/address-of.rs:+33:25: +33:26 + _47 = move _48 as *mut [i32] (Pointer(Unsize)); // scope 13 at $DIR/address-of.rs:+33:25: +33:26 + StorageDead(_48); // scope 13 at $DIR/address-of.rs:+33:25: +33:26 + FakeRead(ForLet(None), _47); // scope 13 at $DIR/address-of.rs:+33:9: +33:10 + AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address-of.rs:+33:12: +33:22 + _0 = const (); // scope 0 at $DIR/address-of.rs:+0:26: +34:2 + StorageDead(_47); // scope 13 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_45); // scope 12 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_44); // scope 11 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_43); // scope 10 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_33); // scope 9 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_31); // scope 8 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_30); // scope 7 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_29); // scope 6 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_19); // scope 5 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_17); // scope 4 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_16); // scope 3 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_15); // scope 2 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_4); // scope 1 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_3); // scope 1 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_2); // scope 0 at $DIR/address-of.rs:+34:1: +34:2 + StorageDead(_1); // scope 0 at $DIR/address-of.rs:+34:1: +34:2 + return; // scope 0 at $DIR/address-of.rs:+34:2: +34:2 + } +} diff --git a/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..060077b8a --- /dev/null +++ b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir @@ -0,0 +1,47 @@ +// MIR for `borrow_and_cast` after SimplifyCfg-initial + +fn borrow_and_cast(_1: i32) -> () { + debug x => _1; // in scope 0 at $DIR/address-of.rs:+0:20: +0:25 + let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:+0:32: +0:32 + let _2: *const i32; // in scope 0 at $DIR/address-of.rs:+1:9: +1:10 + let _3: &i32; // in scope 0 at $DIR/address-of.rs:+1:13: +1:15 + let _5: &mut i32; // in scope 0 at $DIR/address-of.rs:+2:13: +2:19 + let mut _7: &mut i32; // in scope 0 at $DIR/address-of.rs:+3:13: +3:19 + scope 1 { + debug p => _2; // in scope 1 at $DIR/address-of.rs:+1:9: +1:10 + let _4: *const i32; // in scope 1 at $DIR/address-of.rs:+2:9: +2:10 + scope 2 { + debug q => _4; // in scope 2 at $DIR/address-of.rs:+2:9: +2:10 + let _6: *mut i32; // in scope 2 at $DIR/address-of.rs:+3:9: +3:10 + scope 3 { + debug r => _6; // in scope 3 at $DIR/address-of.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/address-of.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/address-of.rs:+1:13: +1:15 + _3 = &_1; // scope 0 at $DIR/address-of.rs:+1:13: +1:15 + _2 = &raw const (*_3); // scope 0 at $DIR/address-of.rs:+1:13: +1:15 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/address-of.rs:+1:9: +1:10 + StorageDead(_3); // scope 0 at $DIR/address-of.rs:+1:29: +1:30 + StorageLive(_4); // scope 1 at $DIR/address-of.rs:+2:9: +2:10 + StorageLive(_5); // scope 1 at $DIR/address-of.rs:+2:13: +2:19 + _5 = &mut _1; // scope 1 at $DIR/address-of.rs:+2:13: +2:19 + _4 = &raw const (*_5); // scope 1 at $DIR/address-of.rs:+2:13: +2:19 + FakeRead(ForLet(None), _4); // scope 1 at $DIR/address-of.rs:+2:9: +2:10 + StorageDead(_5); // scope 1 at $DIR/address-of.rs:+2:33: +2:34 + StorageLive(_6); // scope 2 at $DIR/address-of.rs:+3:9: +3:10 + StorageLive(_7); // scope 2 at $DIR/address-of.rs:+3:13: +3:19 + _7 = &mut _1; // scope 2 at $DIR/address-of.rs:+3:13: +3:19 + _6 = &raw mut (*_7); // scope 2 at $DIR/address-of.rs:+3:13: +3:19 + FakeRead(ForLet(None), _6); // scope 2 at $DIR/address-of.rs:+3:9: +3:10 + StorageDead(_7); // scope 2 at $DIR/address-of.rs:+3:31: +3:32 + _0 = const (); // scope 0 at $DIR/address-of.rs:+0:32: +4:2 + StorageDead(_6); // scope 2 at $DIR/address-of.rs:+4:1: +4:2 + StorageDead(_4); // scope 1 at $DIR/address-of.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/address-of.rs:+4:1: +4:2 + return; // scope 0 at $DIR/address-of.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/array-index-is-temporary.rs b/src/test/mir-opt/array-index-is-temporary.rs new file mode 100644 index 000000000..0e4c486e4 --- /dev/null +++ b/src/test/mir-opt/array-index-is-temporary.rs @@ -0,0 +1,17 @@ +// Retagging (from Stacked Borrows) relies on the array index being a fresh +// temporary, so that side-effects cannot change it. +// Test that this is indeed the case. + +unsafe fn foo(z: *mut usize) -> u32 { + *z = 2; + 99 +} + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir +fn main() { + let mut x = [42, 43, 44]; + let mut y = 1; + let z: *mut usize = &mut y; + x[y] = unsafe { foo(z) }; +} diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir new file mode 100644 index 000000000..27f883ed3 --- /dev/null +++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir @@ -0,0 +1,64 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11 + let mut _1: [u32; 3]; // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 + let mut _4: &mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 + let mut _5: u32; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29 + let mut _6: *mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 + let _7: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 + let mut _8: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + let mut _9: bool; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + scope 1 { + debug x => _1; // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 + let mut _2: usize; // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 + scope 2 { + debug y => _2; // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 + let _3: *mut usize; // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 + scope 4 { + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 + _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29 + StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 + _2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18 + StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 + StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 + _4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 + _3 = &raw mut (*_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 + StorageDead(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32 + StorageLive(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29 + StorageLive(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 + _6 = _3; // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 + _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27 + // mir::Constant + // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24 + // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27 + StorageLive(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 + _7 = _2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 + _8 = Len(_1); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + _9 = Lt(_7, _8); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + } + + bb2: { + _1[_7] = move _5; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29 + StorageDead(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29 + StorageDead(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30 + _0 = const (); // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2 + StorageDead(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 + return; // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2 + } +} diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir new file mode 100644 index 000000000..27f883ed3 --- /dev/null +++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.64bit.mir @@ -0,0 +1,64 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11 + let mut _1: [u32; 3]; // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 + let mut _4: &mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 + let mut _5: u32; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29 + let mut _6: *mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 + let _7: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 + let mut _8: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + let mut _9: bool; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + scope 1 { + debug x => _1; // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 + let mut _2: usize; // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 + scope 2 { + debug y => _2; // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 + let _3: *mut usize; // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 + scope 4 { + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14 + _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29 + StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14 + _2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18 + StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10 + StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 + _4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 + _3 = &raw mut (*_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31 + StorageDead(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32 + StorageLive(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29 + StorageLive(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 + _6 = _3; // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26 + _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27 + // mir::Constant + // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24 + // + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27 + StorageLive(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 + _7 = _2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8 + _8 = Len(_1); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + _9 = Lt(_7, _8); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9 + } + + bb2: { + _1[_7] = move _5; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29 + StorageDead(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29 + StorageDead(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30 + _0 = const (); // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2 + StorageDead(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2 + return; // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2 + } +} diff --git a/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir b/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir new file mode 100644 index 000000000..2487ef5c2 --- /dev/null +++ b/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir @@ -0,0 +1,24 @@ +// MIR for `main` after AbortUnwindingCalls + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/asm_unwind_panic_abort.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/asm_unwind_panic_abort.rs:+2:9: +2:49 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/asm_unwind_panic_abort.rs:+2:9: +2:49 + _1 = const (); // scope 1 at $DIR/asm_unwind_panic_abort.rs:+2:9: +2:49 + asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb2]; // scope 1 at $DIR/asm_unwind_panic_abort.rs:+2:9: +2:49 + } + + bb1: { + StorageDead(_1); // scope 1 at $DIR/asm_unwind_panic_abort.rs:+2:48: +2:49 + _0 = const (); // scope 1 at $DIR/asm_unwind_panic_abort.rs:+1:5: +3:6 + return; // scope 0 at $DIR/asm_unwind_panic_abort.rs:+4:2: +4:2 + } + + bb2 (cleanup): { + abort; // scope 0 at $DIR/asm_unwind_panic_abort.rs:+0:1: +4:2 + } +} diff --git a/src/test/mir-opt/asm_unwind_panic_abort.rs b/src/test/mir-opt/asm_unwind_panic_abort.rs new file mode 100644 index 000000000..8201d5434 --- /dev/null +++ b/src/test/mir-opt/asm_unwind_panic_abort.rs @@ -0,0 +1,16 @@ +//! Tests that unwinding from an asm block is caught and forced to abort +//! when `-C panic=abort`. + +// min-llvm-version: 13.0.0 +// only-x86_64 +// compile-flags: -C panic=abort +// no-prefer-dynamic + +#![feature(asm_unwind)] + +// EMIT_MIR asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir +fn main() { + unsafe { + std::arch::asm!("", options(may_unwind)); + } +} diff --git a/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..1f099cd5e --- /dev/null +++ b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir @@ -0,0 +1,84 @@ +// MIR for `main` after SimplifyCfg-initial + +| User Type Annotations +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<std::boxed::Box<u32>>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option<std::boxed::Box<u32>> +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<std::boxed::Box<u32>>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option<std::boxed::Box<u32>> +| +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/basic_assignment.rs:+0:11: +0:11 + let _1: bool; // in scope 0 at $DIR/basic_assignment.rs:+1:9: +1:17 + let mut _3: bool; // in scope 0 at $DIR/basic_assignment.rs:+6:16: +6:24 + let mut _6: std::option::Option<std::boxed::Box<u32>>; // in scope 0 at $DIR/basic_assignment.rs:+13:14: +13:20 + scope 1 { + debug nodrop_x => _1; // in scope 1 at $DIR/basic_assignment.rs:+1:9: +1:17 + let _2: bool; // in scope 1 at $DIR/basic_assignment.rs:+2:9: +2:17 + scope 2 { + debug nodrop_y => _2; // in scope 2 at $DIR/basic_assignment.rs:+2:9: +2:17 + let _4: std::option::Option<std::boxed::Box<u32>> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 2 at $DIR/basic_assignment.rs:+8:9: +8:15 + scope 3 { + debug drop_x => _4; // in scope 3 at $DIR/basic_assignment.rs:+8:9: +8:15 + let _5: std::option::Option<std::boxed::Box<u32>>; // in scope 3 at $DIR/basic_assignment.rs:+9:9: +9:15 + scope 4 { + debug drop_y => _5; // in scope 4 at $DIR/basic_assignment.rs:+9:9: +9:15 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/basic_assignment.rs:+1:9: +1:17 + _1 = const false; // scope 0 at $DIR/basic_assignment.rs:+1:20: +1:25 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/basic_assignment.rs:+1:9: +1:17 + StorageLive(_2); // scope 1 at $DIR/basic_assignment.rs:+2:9: +2:17 + StorageLive(_3); // scope 2 at $DIR/basic_assignment.rs:+6:16: +6:24 + _3 = _1; // scope 2 at $DIR/basic_assignment.rs:+6:16: +6:24 + _2 = move _3; // scope 2 at $DIR/basic_assignment.rs:+6:5: +6:24 + StorageDead(_3); // scope 2 at $DIR/basic_assignment.rs:+6:23: +6:24 + StorageLive(_4); // scope 2 at $DIR/basic_assignment.rs:+8:9: +8:15 + _4 = Option::<Box<u32>>::None; // scope 2 at $DIR/basic_assignment.rs:+8:36: +8:40 + FakeRead(ForLet(None), _4); // scope 2 at $DIR/basic_assignment.rs:+8:9: +8:15 + AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/basic_assignment.rs:+8:17: +8:33 + StorageLive(_5); // scope 3 at $DIR/basic_assignment.rs:+9:9: +9:15 + StorageLive(_6); // scope 4 at $DIR/basic_assignment.rs:+13:14: +13:20 + _6 = move _4; // scope 4 at $DIR/basic_assignment.rs:+13:14: +13:20 + replace(_5 <- move _6) -> [return: bb1, unwind: bb5]; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 + } + + bb1: { + drop(_6) -> [return: bb2, unwind: bb6]; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 + } + + bb2: { + StorageDead(_6); // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 + _0 = const (); // scope 0 at $DIR/basic_assignment.rs:+0:11: +14:2 + drop(_5) -> [return: bb3, unwind: bb7]; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb3: { + StorageDead(_5); // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 + drop(_4) -> [return: bb4, unwind: bb8]; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb4: { + StorageDead(_4); // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 + StorageDead(_2); // scope 1 at $DIR/basic_assignment.rs:+14:1: +14:2 + StorageDead(_1); // scope 0 at $DIR/basic_assignment.rs:+14:1: +14:2 + return; // scope 0 at $DIR/basic_assignment.rs:+14:2: +14:2 + } + + bb5 (cleanup): { + drop(_6) -> bb6; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 + } + + bb6 (cleanup): { + drop(_5) -> bb7; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb7 (cleanup): { + drop(_4) -> bb8; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/basic_assignment.rs:+0:1: +14:2 + } +} diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs new file mode 100644 index 000000000..ac350271e --- /dev/null +++ b/src/test/mir-opt/basic_assignment.rs @@ -0,0 +1,24 @@ +// this tests move up progration, which is not yet implemented + +// EMIT_MIR basic_assignment.main.SimplifyCfg-initial.after.mir + +// Check codegen for assignments (`a = b`) where the left-hand-side is +// not yet initialized. Assignments tend to be absent in simple code, +// so subtle breakage in them can leave a quite hard-to-find trail of +// destruction. + +fn main() { + let nodrop_x = false; + let nodrop_y; + + // Since boolean does not require drop, this can be a simple + // assignment: + nodrop_y = nodrop_x; + + let drop_x: Option<Box<u32>> = None; + let drop_y; + + // Since the type of `drop_y` has drop, we generate a `replace` + // terminator: + drop_y = drop_x; +} diff --git a/src/test/mir-opt/bool_compare.opt1.InstCombine.diff b/src/test/mir-opt/bool_compare.opt1.InstCombine.diff new file mode 100644 index 000000000..9c5a9fa9a --- /dev/null +++ b/src/test/mir-opt/bool_compare.opt1.InstCombine.diff @@ -0,0 +1,35 @@ +- // MIR for `opt1` before InstCombine ++ // MIR for `opt1` after InstCombine + + fn opt1(_1: bool) -> u32 { + debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/bool_compare.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + let mut _3: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + StorageLive(_3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:9 +- _2 = Ne(move _3, const true); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 ++ _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + } + + bb1: { + _0 = const 0_u32; // scope 0 at $DIR/bool_compare.rs:+1:20: +1:21 + goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:34 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/bool_compare.rs:+1:31: +1:32 + goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:34 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/bool_compare.rs:+1:33: +1:34 + return; // scope 0 at $DIR/bool_compare.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/bool_compare.opt2.InstCombine.diff b/src/test/mir-opt/bool_compare.opt2.InstCombine.diff new file mode 100644 index 000000000..58c52c4b7 --- /dev/null +++ b/src/test/mir-opt/bool_compare.opt2.InstCombine.diff @@ -0,0 +1,35 @@ +- // MIR for `opt2` before InstCombine ++ // MIR for `opt2` after InstCombine + + fn opt2(_1: bool) -> u32 { + debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/bool_compare.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + let mut _3: bool; // in scope 0 at $DIR/bool_compare.rs:+1:16: +1:17 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + StorageLive(_3); // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17 + _3 = _1; // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17 +- _2 = Ne(const true, move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 ++ _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + } + + bb1: { + _0 = const 0_u32; // scope 0 at $DIR/bool_compare.rs:+1:20: +1:21 + goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:34 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/bool_compare.rs:+1:31: +1:32 + goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:34 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/bool_compare.rs:+1:33: +1:34 + return; // scope 0 at $DIR/bool_compare.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/bool_compare.opt3.InstCombine.diff b/src/test/mir-opt/bool_compare.opt3.InstCombine.diff new file mode 100644 index 000000000..676428c95 --- /dev/null +++ b/src/test/mir-opt/bool_compare.opt3.InstCombine.diff @@ -0,0 +1,35 @@ +- // MIR for `opt3` before InstCombine ++ // MIR for `opt3` after InstCombine + + fn opt3(_1: bool) -> u32 { + debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/bool_compare.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + let mut _3: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + StorageLive(_3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:9 +- _2 = Eq(move _3, const false); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 ++ _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + } + + bb1: { + _0 = const 0_u32; // scope 0 at $DIR/bool_compare.rs:+1:21: +1:22 + goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:35 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/bool_compare.rs:+1:32: +1:33 + goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:35 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/bool_compare.rs:+1:34: +1:35 + return; // scope 0 at $DIR/bool_compare.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/bool_compare.opt4.InstCombine.diff b/src/test/mir-opt/bool_compare.opt4.InstCombine.diff new file mode 100644 index 000000000..addfcd769 --- /dev/null +++ b/src/test/mir-opt/bool_compare.opt4.InstCombine.diff @@ -0,0 +1,35 @@ +- // MIR for `opt4` before InstCombine ++ // MIR for `opt4` after InstCombine + + fn opt4(_1: bool) -> u32 { + debug x => _1; // in scope 0 at $DIR/bool_compare.rs:+0:9: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/bool_compare.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + let mut _3: bool; // in scope 0 at $DIR/bool_compare.rs:+1:17: +1:18 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + StorageLive(_3); // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18 + _3 = _1; // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18 +- _2 = Eq(const false, move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 ++ _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + } + + bb1: { + _0 = const 0_u32; // scope 0 at $DIR/bool_compare.rs:+1:21: +1:22 + goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:35 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/bool_compare.rs:+1:32: +1:33 + goto -> bb3; // scope 0 at $DIR/bool_compare.rs:+1:5: +1:35 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/bool_compare.rs:+1:34: +1:35 + return; // scope 0 at $DIR/bool_compare.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/bool_compare.rs b/src/test/mir-opt/bool_compare.rs new file mode 100644 index 000000000..3ff046325 --- /dev/null +++ b/src/test/mir-opt/bool_compare.rs @@ -0,0 +1,26 @@ +// EMIT_MIR bool_compare.opt1.InstCombine.diff +fn opt1(x: bool) -> u32 { + if x != true { 0 } else { 1 } +} + +// EMIT_MIR bool_compare.opt2.InstCombine.diff +fn opt2(x: bool) -> u32 { + if true != x { 0 } else { 1 } +} + +// EMIT_MIR bool_compare.opt3.InstCombine.diff +fn opt3(x: bool) -> u32 { + if x == false { 0 } else { 1 } +} + +// EMIT_MIR bool_compare.opt4.InstCombine.diff +fn opt4(x: bool) -> u32 { + if false == x { 0 } else { 1 } +} + +fn main() { + opt1(false); + opt2(false); + opt3(false); + opt4(false); +} diff --git a/src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir b/src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir new file mode 100644 index 000000000..49133138d --- /dev/null +++ b/src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir @@ -0,0 +1,80 @@ +// MIR for `main` before ElaborateDrops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/box_expr.rs:+0:11: +0:11 + let _1: std::boxed::Box<S>; // in scope 0 at $DIR/box_expr.rs:+1:9: +1:10 + let mut _2: usize; // in scope 0 at $DIR/box_expr.rs:+1:13: +1:25 + let mut _3: usize; // in scope 0 at $DIR/box_expr.rs:+1:13: +1:25 + let mut _4: *mut u8; // in scope 0 at $DIR/box_expr.rs:+1:13: +1:25 + let mut _5: std::boxed::Box<S>; // in scope 0 at $DIR/box_expr.rs:+1:13: +1:25 + let _6: (); // in scope 0 at $DIR/box_expr.rs:+2:5: +2:12 + let mut _7: std::boxed::Box<S>; // in scope 0 at $DIR/box_expr.rs:+2:10: +2:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/box_expr.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/box_expr.rs:+1:9: +1:10 + _2 = SizeOf(S); // scope 2 at $DIR/box_expr.rs:+1:13: +1:25 + _3 = AlignOf(S); // scope 2 at $DIR/box_expr.rs:+1:13: +1:25 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/box_expr.rs:+1:13: +1:25 + // mir::Constant + // + span: $DIR/box_expr.rs:7:13: 7:25 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/box_expr.rs:+1:13: +1:25 + _5 = ShallowInitBox(move _4, S); // scope 0 at $DIR/box_expr.rs:+1:13: +1:25 + (*_5) = S::new() -> [return: bb2, unwind: bb8]; // scope 0 at $DIR/box_expr.rs:+1:17: +1:25 + // mir::Constant + // + span: $DIR/box_expr.rs:7:17: 7:23 + // + literal: Const { ty: fn() -> S {S::new}, val: Value(<ZST>) } + } + + bb2: { + _1 = move _5; // scope 0 at $DIR/box_expr.rs:+1:13: +1:25 + drop(_5) -> bb3; // scope 0 at $DIR/box_expr.rs:+1:24: +1:25 + } + + bb3: { + StorageDead(_5); // scope 0 at $DIR/box_expr.rs:+1:24: +1:25 + StorageLive(_6); // scope 1 at $DIR/box_expr.rs:+2:5: +2:12 + StorageLive(_7); // scope 1 at $DIR/box_expr.rs:+2:10: +2:11 + _7 = move _1; // scope 1 at $DIR/box_expr.rs:+2:10: +2:11 + _6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6]; // scope 1 at $DIR/box_expr.rs:+2:5: +2:12 + // mir::Constant + // + span: $DIR/box_expr.rs:8:5: 8:9 + // + literal: Const { ty: fn(Box<S>) {std::mem::drop::<Box<S>>}, val: Value(<ZST>) } + } + + bb4: { + StorageDead(_7); // scope 1 at $DIR/box_expr.rs:+2:11: +2:12 + StorageDead(_6); // scope 1 at $DIR/box_expr.rs:+2:12: +2:13 + _0 = const (); // scope 0 at $DIR/box_expr.rs:+0:11: +3:2 + drop(_1) -> bb5; // scope 0 at $DIR/box_expr.rs:+3:1: +3:2 + } + + bb5: { + StorageDead(_1); // scope 0 at $DIR/box_expr.rs:+3:1: +3:2 + return; // scope 0 at $DIR/box_expr.rs:+3:2: +3:2 + } + + bb6 (cleanup): { + drop(_7) -> bb7; // scope 1 at $DIR/box_expr.rs:+2:11: +2:12 + } + + bb7 (cleanup): { + drop(_1) -> bb9; // scope 0 at $DIR/box_expr.rs:+3:1: +3:2 + } + + bb8 (cleanup): { + drop(_5) -> bb9; // scope 0 at $DIR/box_expr.rs:+1:24: +1:25 + } + + bb9 (cleanup): { + resume; // scope 0 at $DIR/box_expr.rs:+0:1: +3:2 + } +} diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs new file mode 100644 index 000000000..a214504f6 --- /dev/null +++ b/src/test/mir-opt/box_expr.rs @@ -0,0 +1,21 @@ +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(box_syntax)] + +// EMIT_MIR box_expr.main.ElaborateDrops.before.mir +fn main() { + let x = box S::new(); + drop(x); +} + +struct S; + +impl S { + fn new() -> Self { S } +} + +impl Drop for S { + fn drop(&mut self) { + println!("splat!"); + } +} diff --git a/src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..73f5655a1 --- /dev/null +++ b/src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,31 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/byte_slice.rs:+0:11: +0:11 + let _1: &[u8; 3]; // in scope 0 at $DIR/byte_slice.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/byte_slice.rs:+1:9: +1:10 + let _2: [u8; 2]; // in scope 1 at $DIR/byte_slice.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/byte_slice.rs:+2:9: +2:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/byte_slice.rs:+1:9: +1:10 + _1 = const b"foo"; // scope 0 at $DIR/byte_slice.rs:+1:13: +1:19 + // mir::Constant + // + span: $DIR/byte_slice.rs:5:13: 5:19 + // + literal: Const { ty: &[u8; 3], val: Value(Scalar(alloc1)) } + StorageLive(_2); // scope 1 at $DIR/byte_slice.rs:+2:9: +2:10 + _2 = [const 5_u8, const 120_u8]; // scope 1 at $DIR/byte_slice.rs:+2:13: +2:24 + _0 = const (); // scope 0 at $DIR/byte_slice.rs:+0:11: +3:2 + StorageDead(_2); // scope 1 at $DIR/byte_slice.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/byte_slice.rs:+3:1: +3:2 + return; // scope 0 at $DIR/byte_slice.rs:+3:2: +3:2 + } +} + +alloc1 (size: 3, align: 1) { + 66 6f 6f │ foo +} diff --git a/src/test/mir-opt/byte_slice.rs b/src/test/mir-opt/byte_slice.rs new file mode 100644 index 000000000..48e9c48c1 --- /dev/null +++ b/src/test/mir-opt/byte_slice.rs @@ -0,0 +1,7 @@ +// compile-flags: -Z mir-opt-level=0 + +// EMIT_MIR byte_slice.main.SimplifyCfg-elaborate-drops.after.mir +fn main() { + let x = b"foo"; + let y = [5u8, b'x']; +} diff --git a/src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff b/src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff new file mode 100644 index 000000000..c73150f94 --- /dev/null +++ b/src/test/mir-opt/combine_array_len.norm2.InstCombine.32bit.diff @@ -0,0 +1,77 @@ +- // MIR for `norm2` before InstCombine ++ // MIR for `norm2` after InstCombine + + fn norm2(_1: [f32; 2]) -> f32 { + debug x => _1; // in scope 0 at $DIR/combine_array_len.rs:+0:10: +0:11 + let mut _0: f32; // return place in scope 0 at $DIR/combine_array_len.rs:+0:26: +0:29 + let _2: f32; // in scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10 + let _3: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 + let mut _4: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + let mut _5: bool; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + let _7: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:15: +2:16 + let mut _8: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17 + let mut _9: bool; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17 + let mut _10: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:8 + let mut _11: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:6 + let mut _12: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:7: +3:8 + let mut _13: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:14 + let mut _14: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:12 + let mut _15: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:13: +3:14 + scope 1 { + debug a => _2; // in scope 1 at $DIR/combine_array_len.rs:+1:9: +1:10 + let _6: f32; // in scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10 + scope 2 { + debug b => _6; // in scope 2 at $DIR/combine_array_len.rs:+2:9: +2:10 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 + _3 = const 0_usize; // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 +- _4 = Len(_1); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 ++ _4 = const 2_usize; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + _5 = Lt(_3, _4); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + } + + bb1: { + _2 = _1[_3]; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + StorageDead(_3); // scope 0 at $DIR/combine_array_len.rs:+1:17: +1:18 + StorageLive(_6); // scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10 + StorageLive(_7); // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16 + _7 = const 1_usize; // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16 +- _8 = Len(_1); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 ++ _8 = const 2_usize; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + _9 = Lt(_7, _8); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + } + + bb2: { + _6 = _1[_7]; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + StorageDead(_7); // scope 1 at $DIR/combine_array_len.rs:+2:17: +2:18 + StorageLive(_10); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8 + StorageLive(_11); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6 + _11 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6 + StorageLive(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + _12 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + _10 = Mul(move _11, move _12); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8 + StorageDead(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + StorageDead(_11); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + StorageLive(_13); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14 + StorageLive(_14); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12 + _14 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12 + StorageLive(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _15 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _13 = Mul(move _14, move _15); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14 + StorageDead(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_14); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _0 = Add(move _10, move _13); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:14 + StorageDead(_13); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_10); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_6); // scope 1 at $DIR/combine_array_len.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/combine_array_len.rs:+4:1: +4:2 + return; // scope 0 at $DIR/combine_array_len.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff b/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff new file mode 100644 index 000000000..c73150f94 --- /dev/null +++ b/src/test/mir-opt/combine_array_len.norm2.InstCombine.64bit.diff @@ -0,0 +1,77 @@ +- // MIR for `norm2` before InstCombine ++ // MIR for `norm2` after InstCombine + + fn norm2(_1: [f32; 2]) -> f32 { + debug x => _1; // in scope 0 at $DIR/combine_array_len.rs:+0:10: +0:11 + let mut _0: f32; // return place in scope 0 at $DIR/combine_array_len.rs:+0:26: +0:29 + let _2: f32; // in scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10 + let _3: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 + let mut _4: usize; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + let mut _5: bool; // in scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + let _7: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:15: +2:16 + let mut _8: usize; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17 + let mut _9: bool; // in scope 0 at $DIR/combine_array_len.rs:+2:13: +2:17 + let mut _10: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:8 + let mut _11: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:5: +3:6 + let mut _12: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:7: +3:8 + let mut _13: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:14 + let mut _14: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:11: +3:12 + let mut _15: f32; // in scope 0 at $DIR/combine_array_len.rs:+3:13: +3:14 + scope 1 { + debug a => _2; // in scope 1 at $DIR/combine_array_len.rs:+1:9: +1:10 + let _6: f32; // in scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10 + scope 2 { + debug b => _6; // in scope 2 at $DIR/combine_array_len.rs:+2:9: +2:10 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/combine_array_len.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 + _3 = const 0_usize; // scope 0 at $DIR/combine_array_len.rs:+1:15: +1:16 +- _4 = Len(_1); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 ++ _4 = const 2_usize; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + _5 = Lt(_3, _4); // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + } + + bb1: { + _2 = _1[_3]; // scope 0 at $DIR/combine_array_len.rs:+1:13: +1:17 + StorageDead(_3); // scope 0 at $DIR/combine_array_len.rs:+1:17: +1:18 + StorageLive(_6); // scope 1 at $DIR/combine_array_len.rs:+2:9: +2:10 + StorageLive(_7); // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16 + _7 = const 1_usize; // scope 1 at $DIR/combine_array_len.rs:+2:15: +2:16 +- _8 = Len(_1); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 ++ _8 = const 2_usize; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + _9 = Lt(_7, _8); // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + } + + bb2: { + _6 = _1[_7]; // scope 1 at $DIR/combine_array_len.rs:+2:13: +2:17 + StorageDead(_7); // scope 1 at $DIR/combine_array_len.rs:+2:17: +2:18 + StorageLive(_10); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8 + StorageLive(_11); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6 + _11 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:6 + StorageLive(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + _12 = _2; // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + _10 = Mul(move _11, move _12); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:8 + StorageDead(_12); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + StorageDead(_11); // scope 2 at $DIR/combine_array_len.rs:+3:7: +3:8 + StorageLive(_13); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14 + StorageLive(_14); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12 + _14 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:12 + StorageLive(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _15 = _6; // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _13 = Mul(move _14, move _15); // scope 2 at $DIR/combine_array_len.rs:+3:11: +3:14 + StorageDead(_15); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_14); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + _0 = Add(move _10, move _13); // scope 2 at $DIR/combine_array_len.rs:+3:5: +3:14 + StorageDead(_13); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_10); // scope 2 at $DIR/combine_array_len.rs:+3:13: +3:14 + StorageDead(_6); // scope 1 at $DIR/combine_array_len.rs:+4:1: +4:2 + StorageDead(_2); // scope 0 at $DIR/combine_array_len.rs:+4:1: +4:2 + return; // scope 0 at $DIR/combine_array_len.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/combine_array_len.rs b/src/test/mir-opt/combine_array_len.rs new file mode 100644 index 000000000..93490c14f --- /dev/null +++ b/src/test/mir-opt/combine_array_len.rs @@ -0,0 +1,12 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR combine_array_len.norm2.InstCombine.diff + +fn norm2(x: [f32; 2]) -> f32 { + let a = x[0]; + let b = x[1]; + a*a + b*b +} + +fn main() { + assert_eq!(norm2([3.0, 4.0]), 5.0*5.0); +} diff --git a/src/test/mir-opt/combine_clone_of_primitives.rs b/src/test/mir-opt/combine_clone_of_primitives.rs new file mode 100644 index 000000000..7cc50a86e --- /dev/null +++ b/src/test/mir-opt/combine_clone_of_primitives.rs @@ -0,0 +1,20 @@ +// unit-test: InstCombine +// ignore-wasm32 compiled with panic=abort by default + +// EMIT_MIR combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff + +#[derive(Clone)] +struct MyThing<T> { + v: T, + i: u64, + a: [f32; 3], +} + +fn main() { + let x = MyThing::<i16> { v: 2, i: 3, a: [0.0; 3] }; + let y = x.clone(); + + assert_eq!(y.v, 2); + assert_eq!(y.i, 3); + assert_eq!(y.a, [0.0; 3]); +} diff --git a/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff new file mode 100644 index 000000000..833d620cc --- /dev/null +++ b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff @@ -0,0 +1,85 @@ +- // MIR for `<impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone` before InstCombine ++ // MIR for `<impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone` after InstCombine + + fn <impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone(_1: &MyThing<T>) -> MyThing<T> { + debug self => _1; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + let mut _0: MyThing<T>; // return place in scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + let mut _2: T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 + let mut _3: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 + let _4: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 + let mut _5: u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 + let mut _6: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 + let _7: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 + let mut _8: [f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 + let mut _9: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 + let _10: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 + StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 + StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 + _4 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 +- _3 = &(*_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 ++ _3 = _4; // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 + _2 = <T as Clone>::clone(move _3) -> bb1; // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:5: +2:9 + // mir::Constant + // + span: $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + // + literal: Const { ty: for<'r> fn(&'r T) -> T {<T as Clone>::clone}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:+2:8: +2:9 + StorageLive(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 + StorageLive(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 + StorageLive(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 + _7 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 +- _6 = &(*_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 +- _5 = <u64 as Clone>::clone(move _6) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 +- // mir::Constant +- // + span: $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- // + literal: Const { ty: for<'r> fn(&'r u64) -> u64 {<u64 as Clone>::clone}, val: Value(<ZST>) } ++ _6 = _7; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 ++ _5 = (*_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 ++ goto -> bb2; // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:5: +3:11 + } + + bb2: { + StorageDead(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:+3:10: +3:11 + StorageLive(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 + StorageLive(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 + StorageLive(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 + _10 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 +- _9 = &(*_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 +- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 +- // mir::Constant +- // + span: $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- // + literal: Const { ty: for<'r> fn(&'r [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value(<ZST>) } ++ _9 = _10; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 ++ _8 = (*_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 ++ goto -> bb3; // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:5: +4:16 + } + + bb3: { + StorageDead(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:+4:15: +4:16 + Deinit(_0); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + (_0.0: T) = move _2; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + (_0.1: u64) = move _5; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + (_0.2: [f32; 3]) = move _8; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + StorageDead(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + StorageDead(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + return; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:15: +0:15 + } + + bb4 (cleanup): { + drop(_2) -> bb5; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:14: +0:15 + } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/combine_clone_of_primitives.rs:+0:10: +0:15 + } + } + diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs new file mode 100644 index 000000000..a0d4e9b2c --- /dev/null +++ b/src/test/mir-opt/const-promotion-extern-static.rs @@ -0,0 +1,18 @@ +// ignore-endian-big +extern "C" { + static X: i32; +} +static Y: i32 = 42; + +// EMIT_MIR const_promotion_extern_static.BAR.PromoteTemps.diff +// EMIT_MIR const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir +static mut BAR: *const &i32 = [&Y].as_ptr(); + +// EMIT_MIR const_promotion_extern_static.FOO.PromoteTemps.diff +// EMIT_MIR const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir +static mut FOO: *const &i32 = [unsafe { &X }].as_ptr(); + +// EMIT_MIR const_promotion_extern_static.BOP.mir_map.0.mir +static BOP: &i32 = &13; + +fn main() {} diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir new file mode 100644 index 000000000..da5a64cac --- /dev/null +++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir @@ -0,0 +1,62 @@ +// MIR for `main` after ConstProp + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_allocation.rs:+0:11: +0:11 + let _1: &[(std::option::Option<i32>, &[&str])]; // in scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + let mut _2: &&[(std::option::Option<i32>, &[&str])]; // in scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + _2 = const {alloc1: &&[(Option<i32>, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/const_allocation.rs:8:5: 8:8 + // + literal: Const { ty: &&[(Option<i32>, &[&str])], val: Value(Scalar(alloc1)) } + _1 = (*_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9 + StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9 + nop; // scope 0 at $DIR/const_allocation.rs:+0:11: +2:2 + return; // scope 0 at $DIR/const_allocation.rs:+2:2: +2:2 + } +} + +alloc1 (static: FOO, size: 8, align: 4) { + ╾─alloc18─╼ 03 00 00 00 │ ╾──╼.... +} + +alloc18 (size: 48, align: 4) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc5──╼ 00 00 00 00 │ ....░░░░╾──╼.... + 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc9──╼ 02 00 00 00 │ ....░░░░╾──╼.... + 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc14─╼ 03 00 00 00 │ ....*...╾──╼.... +} + +alloc5 (size: 0, align: 4) {} + +alloc9 (size: 16, align: 4) { + ╾─alloc8──╼ 03 00 00 00 ╾─alloc10─╼ 03 00 00 00 │ ╾──╼....╾──╼.... +} + +alloc8 (size: 3, align: 1) { + 66 6f 6f │ foo +} + +alloc10 (size: 3, align: 1) { + 62 61 72 │ bar +} + +alloc14 (size: 24, align: 4) { + 0x00 │ ╾─alloc13─╼ 03 00 00 00 ╾─alloc15─╼ 03 00 00 00 │ ╾──╼....╾──╼.... + 0x10 │ ╾─alloc16─╼ 04 00 00 00 │ ╾──╼.... +} + +alloc13 (size: 3, align: 1) { + 6d 65 68 │ meh +} + +alloc15 (size: 3, align: 1) { + 6d 6f 70 │ mop +} + +alloc16 (size: 4, align: 1) { + 6d c3 b6 70 │ m..p +} diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir new file mode 100644 index 000000000..febd99068 --- /dev/null +++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir @@ -0,0 +1,66 @@ +// MIR for `main` after ConstProp + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_allocation.rs:+0:11: +0:11 + let _1: &[(std::option::Option<i32>, &[&str])]; // in scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + let mut _2: &&[(std::option::Option<i32>, &[&str])]; // in scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + _2 = const {alloc1: &&[(Option<i32>, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/const_allocation.rs:8:5: 8:8 + // + literal: Const { ty: &&[(Option<i32>, &[&str])], val: Value(Scalar(alloc1)) } + _1 = (*_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 + StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9 + StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9 + nop; // scope 0 at $DIR/const_allocation.rs:+0:11: +2:2 + return; // scope 0 at $DIR/const_allocation.rs:+2:2: +2:2 + } +} + +alloc1 (static: FOO, size: 16, align: 8) { + ╾───────alloc18───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ +} + +alloc18 (size: 72, align: 8) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc5────────╼ │ ....░░░░╾──────╼ + 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░ + 0x20 │ ╾───────alloc9────────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc14───────╼ │ ....*...╾──────╼ + 0x40 │ 03 00 00 00 00 00 00 00 │ ........ +} + +alloc5 (size: 0, align: 8) {} + +alloc9 (size: 32, align: 8) { + 0x00 │ ╾───────alloc8────────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x10 │ ╾───────alloc10───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ +} + +alloc8 (size: 3, align: 1) { + 66 6f 6f │ foo +} + +alloc10 (size: 3, align: 1) { + 62 61 72 │ bar +} + +alloc14 (size: 48, align: 8) { + 0x00 │ ╾───────alloc13───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x10 │ ╾───────alloc15───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x20 │ ╾───────alloc16───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ +} + +alloc13 (size: 3, align: 1) { + 6d 65 68 │ meh +} + +alloc15 (size: 3, align: 1) { + 6d 6f 70 │ mop +} + +alloc16 (size: 4, align: 1) { + 6d c3 b6 70 │ m..p +} diff --git a/src/test/mir-opt/const_allocation.rs b/src/test/mir-opt/const_allocation.rs new file mode 100644 index 000000000..b0fcb86fc --- /dev/null +++ b/src/test/mir-opt/const_allocation.rs @@ -0,0 +1,9 @@ +// ignore-endian-big +// EMIT_MIR_FOR_EACH_BIT_WIDTH +static FOO: &[(Option<i32>, &[&str])] = + &[(None, &[]), (None, &["foo", "bar"]), (Some(42), &["meh", "mop", "möp"])]; + +// EMIT_MIR const_allocation.main.ConstProp.after.mir +fn main() { + FOO; +} diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir new file mode 100644 index 000000000..389641f20 --- /dev/null +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir @@ -0,0 +1,61 @@ +// MIR for `main` after ConstProp + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_allocation2.rs:+0:11: +0:11 + let _1: &[(std::option::Option<i32>, &[&u8])]; // in scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + let mut _2: &&[(std::option::Option<i32>, &[&u8])]; // in scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + _2 = const {alloc1: &&[(Option<i32>, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/const_allocation2.rs:5:5: 5:8 + // + literal: Const { ty: &&[(Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) } + _1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9 + StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9 + nop; // scope 0 at $DIR/const_allocation2.rs:+0:11: +2:2 + return; // scope 0 at $DIR/const_allocation2.rs:+2:2: +2:2 + } +} + +alloc1 (static: FOO, size: 8, align: 4) { + ╾─alloc22─╼ 03 00 00 00 │ ╾──╼.... +} + +alloc22 (size: 48, align: 4) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc9──╼ 00 00 00 00 │ ....░░░░╾──╼.... + 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc14─╼ 02 00 00 00 │ ....░░░░╾──╼.... + 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc20─╼ 03 00 00 00 │ ....*...╾──╼.... +} + +alloc9 (size: 0, align: 4) {} + +alloc14 (size: 8, align: 4) { + ╾─alloc12─╼ ╾─alloc13─╼ │ ╾──╼╾──╼ +} + +alloc12 (size: 1, align: 1) { + 05 │ . +} + +alloc13 (size: 1, align: 1) { + 06 │ . +} + +alloc20 (size: 12, align: 4) { + ╾─a17+0x3─╼ ╾─alloc18─╼ ╾─a19+0x2─╼ │ ╾──╼╾──╼╾──╼ +} + +alloc17 (size: 4, align: 1) { + 2a 45 15 6f │ *E.o +} + +alloc18 (size: 1, align: 1) { + 2a │ * +} + +alloc19 (size: 4, align: 1) { + 2a 45 15 6f │ *E.o +} diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir new file mode 100644 index 000000000..ce3848e92 --- /dev/null +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir @@ -0,0 +1,64 @@ +// MIR for `main` after ConstProp + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_allocation2.rs:+0:11: +0:11 + let _1: &[(std::option::Option<i32>, &[&u8])]; // in scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + let mut _2: &&[(std::option::Option<i32>, &[&u8])]; // in scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + _2 = const {alloc1: &&[(Option<i32>, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/const_allocation2.rs:5:5: 5:8 + // + literal: Const { ty: &&[(Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) } + _1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 + StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9 + StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9 + nop; // scope 0 at $DIR/const_allocation2.rs:+0:11: +2:2 + return; // scope 0 at $DIR/const_allocation2.rs:+2:2: +2:2 + } +} + +alloc1 (static: FOO, size: 16, align: 8) { + ╾───────alloc22───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ +} + +alloc22 (size: 72, align: 8) { + 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc9────────╼ │ ....░░░░╾──────╼ + 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░ + 0x20 │ ╾───────alloc14───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc20───────╼ │ ....*...╾──────╼ + 0x40 │ 03 00 00 00 00 00 00 00 │ ........ +} + +alloc9 (size: 0, align: 8) {} + +alloc14 (size: 16, align: 8) { + ╾───────alloc12───────╼ ╾───────alloc13───────╼ │ ╾──────╼╾──────╼ +} + +alloc12 (size: 1, align: 1) { + 05 │ . +} + +alloc13 (size: 1, align: 1) { + 06 │ . +} + +alloc20 (size: 24, align: 8) { + 0x00 │ ╾─────alloc17+0x3─────╼ ╾───────alloc18───────╼ │ ╾──────╼╾──────╼ + 0x10 │ ╾─────alloc19+0x2─────╼ │ ╾──────╼ +} + +alloc17 (size: 4, align: 1) { + 2a 45 15 6f │ *E.o +} + +alloc18 (size: 1, align: 1) { + 2a │ * +} + +alloc19 (size: 4, align: 1) { + 2a 45 15 6f │ *E.o +} diff --git a/src/test/mir-opt/const_allocation2.rs b/src/test/mir-opt/const_allocation2.rs new file mode 100644 index 000000000..30afedffb --- /dev/null +++ b/src/test/mir-opt/const_allocation2.rs @@ -0,0 +1,11 @@ +// ignore-endian-big +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR const_allocation2.main.ConstProp.after.mir +fn main() { + FOO; +} + +const BAR: [u8; 4] = [42, 69, 21, 111]; + +static FOO: &[(Option<i32>, &[&u8])] = + &[(None, &[]), (None, &[&5, &6]), (Some(42), &[&BAR[3], &42, &BAR[2]])]; diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir new file mode 100644 index 000000000..b72519159 --- /dev/null +++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir @@ -0,0 +1,55 @@ +// MIR for `main` after ConstProp + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_allocation3.rs:+0:11: +0:11 + let _1: &Packed; // in scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + let mut _2: &&Packed; // in scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + _2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/const_allocation3.rs:5:5: 5:8 + // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) } + _1 = (*_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + StorageDead(_2); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9 + StorageDead(_1); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9 + nop; // scope 0 at $DIR/const_allocation3.rs:+0:11: +2:2 + return; // scope 0 at $DIR/const_allocation3.rs:+2:2: +2:2 + } +} + +alloc1 (static: FOO, size: 4, align: 4) { + ╾─alloc11─╼ │ ╾──╼ +} + +alloc11 (size: 168, align: 1) { + 0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................ + 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc6──╼ │ ............╾──╼ + 0x20 │ 01 ef cd ab 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾─alloc8──╼ 00 00 │ ..........╾──╼.. + 0x90 │ ╾─a9+0x63─╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............ + 0xa0 │ 00 00 00 00 00 00 00 00 │ ........ +} + +alloc6 (size: 4, align: 4) { + 2a 00 00 00 │ *... +} + +alloc8 (fn: main) + +alloc9 (size: 100, align: 1) { + 0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x60 │ 00 00 00 00 │ .... +} diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir new file mode 100644 index 000000000..6bd047c7d --- /dev/null +++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir @@ -0,0 +1,56 @@ +// MIR for `main` after ConstProp + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_allocation3.rs:+0:11: +0:11 + let _1: &Packed; // in scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + let mut _2: &&Packed; // in scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + _2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/const_allocation3.rs:5:5: 5:8 + // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) } + _1 = (*_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 + StorageDead(_2); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9 + StorageDead(_1); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9 + nop; // scope 0 at $DIR/const_allocation3.rs:+0:11: +2:2 + return; // scope 0 at $DIR/const_allocation3.rs:+2:2: +2:2 + } +} + +alloc1 (static: FOO, size: 8, align: 8) { + ╾───────alloc11───────╼ │ ╾──────╼ +} + +alloc11 (size: 180, align: 1) { + 0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................ + 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾──alloc6── │ ............╾─── + 0x20 │ ──────────╼ 01 ef cd ab 00 00 00 00 00 00 00 00 │ ───╼............ + 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x80 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ╾──── │ ..............╾─ + 0x90 │ ─────alloc8─────╼ 00 00 ╾─────alloc9+0x63─────╼ │ ─────╼..╾──────╼ + 0xa0 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0xb0 │ 00 00 00 00 │ .... +} + +alloc6 (size: 4, align: 4) { + 2a 00 00 00 │ *... +} + +alloc8 (fn: main) + +alloc9 (size: 100, align: 1) { + 0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + 0x60 │ 00 00 00 00 │ .... +} diff --git a/src/test/mir-opt/const_allocation3.rs b/src/test/mir-opt/const_allocation3.rs new file mode 100644 index 000000000..ddeb32ab9 --- /dev/null +++ b/src/test/mir-opt/const_allocation3.rs @@ -0,0 +1,29 @@ +// ignore-endian-big +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR const_allocation3.main.ConstProp.after.mir +fn main() { + FOO; +} + +#[repr(packed)] +struct Packed { + a: [u8; 28], + b: &'static i32, + c: u32, + d: [u8; 102], + e: fn(), + f: u16, + g: &'static u8, + h: [u8; 20], +} + +static FOO: &Packed = &Packed { + a: [0xAB; 28], + b: &42, + c: 0xABCD_EF01, + d: [0; 102], + e: main, + f: 0, + g: &[0; 100][99], + h: [0; 20], +}; diff --git a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff new file mode 100644 index 000000000..a092f3752 --- /dev/null +++ b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -0,0 +1,115 @@ +- // MIR for `main` before ConstDebugInfo ++ // MIR for `main` after ConstDebugInfo + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_debuginfo.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/const_debuginfo.rs:+1:9: +1:10 + let mut _5: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:20 + let mut _6: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:16 + let mut _7: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:19: +4:20 + let mut _8: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:23: +4:24 + let mut _14: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16 + let mut _15: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22 + scope 1 { +- debug x => _1; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 ++ debug x => const 1_u8; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 + let _2: u8; // in scope 1 at $DIR/const_debuginfo.rs:+2:9: +2:10 + scope 2 { +- debug y => _2; // in scope 2 at $DIR/const_debuginfo.rs:+2:9: +2:10 ++ debug y => const 2_u8; // in scope 2 at $DIR/const_debuginfo.rs:+2:9: +2:10 + let _3: u8; // in scope 2 at $DIR/const_debuginfo.rs:+3:9: +3:10 + scope 3 { +- debug z => _3; // in scope 3 at $DIR/const_debuginfo.rs:+3:9: +3:10 ++ debug z => const 3_u8; // in scope 3 at $DIR/const_debuginfo.rs:+3:9: +3:10 + let _4: u8; // in scope 3 at $DIR/const_debuginfo.rs:+4:9: +4:12 + scope 4 { +- debug sum => _4; // in scope 4 at $DIR/const_debuginfo.rs:+4:9: +4:12 ++ debug sum => const 6_u8; // in scope 4 at $DIR/const_debuginfo.rs:+4:9: +4:12 + let _9: &str; // in scope 4 at $DIR/const_debuginfo.rs:+6:9: +6:10 + scope 5 { +- debug s => _9; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 ++ debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 + let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + scope 6 { + debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _11: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + scope 7 { + debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 + let _12: Point; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + scope 8 { + debug p => _12; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _13: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + scope 9 { +- debug a => _13; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 ++ debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 + } + } + } + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_debuginfo.rs:+1:9: +1:10 + _1 = const 1_u8; // scope 0 at $DIR/const_debuginfo.rs:+1:13: +1:16 + StorageLive(_2); // scope 1 at $DIR/const_debuginfo.rs:+2:9: +2:10 + _2 = const 2_u8; // scope 1 at $DIR/const_debuginfo.rs:+2:13: +2:16 + StorageLive(_3); // scope 2 at $DIR/const_debuginfo.rs:+3:9: +3:10 + _3 = const 3_u8; // scope 2 at $DIR/const_debuginfo.rs:+3:13: +3:16 + StorageLive(_4); // scope 3 at $DIR/const_debuginfo.rs:+4:9: +4:12 + StorageLive(_5); // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:20 + StorageLive(_6); // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:16 + _6 = const 1_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:16 + StorageLive(_7); // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20 + _7 = const 2_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20 + _5 = const 3_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:20 + StorageDead(_7); // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20 + StorageDead(_6); // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20 + StorageLive(_8); // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24 + _8 = const 3_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24 + _4 = const 6_u8; // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:24 + StorageDead(_8); // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24 + StorageDead(_5); // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24 + StorageLive(_9); // scope 4 at $DIR/const_debuginfo.rs:+6:9: +6:10 + _9 = const "hello, world!"; // scope 4 at $DIR/const_debuginfo.rs:+6:13: +6:28 + // mir::Constant + // + span: $DIR/const_debuginfo.rs:14:13: 14:28 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + StorageLive(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + Deinit(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + (_10.0: bool) = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + (_10.1: bool) = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + (_10.2: u32) = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + StorageLive(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + Deinit(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + ((_11 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + discriminant(_11) = 1; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + StorageLive(_12); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + Deinit(_12); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + (_12.0: u32) = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + (_12.1: u32) = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + StorageLive(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 + _14 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 + StorageLive(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 + _15 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 + _13 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 + StorageDead(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 + StorageDead(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 + nop; // scope 0 at $DIR/const_debuginfo.rs:+0:11: +14:2 + StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_12); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_11); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_10); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_9); // scope 4 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_4); // scope 3 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_3); // scope 2 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_2); // scope 1 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_1); // scope 0 at $DIR/const_debuginfo.rs:+14:1: +14:2 + return; // scope 0 at $DIR/const_debuginfo.rs:+14:2: +14:2 + } + } + diff --git a/src/test/mir-opt/const_debuginfo.rs b/src/test/mir-opt/const_debuginfo.rs new file mode 100644 index 000000000..a188da385 --- /dev/null +++ b/src/test/mir-opt/const_debuginfo.rs @@ -0,0 +1,24 @@ +// compile-flags: -C overflow-checks=no -Zunsound-mir-opts + +struct Point { + x: u32, + y: u32, +} + +fn main() { + let x = 1u8; + let y = 2u8; + let z = 3u8; + let sum = x + y + z; + + let s = "hello, world!"; + + let f = (true, false, 123u32); + + let o = Some(99u16); + + let p = Point { x: 32, y: 32 }; + let a = p.x + p.y; +} + +// EMIT_MIR const_debuginfo.main.ConstDebugInfo.diff diff --git a/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff b/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff new file mode 100644 index 000000000..fade2d0bc --- /dev/null +++ b/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff @@ -0,0 +1,52 @@ +- // MIR for `issue_77355_opt` before ConstGoto ++ // MIR for `issue_77355_opt` after ConstGoto + + fn issue_77355_opt(_1: Foo) -> u64 { + debug num => _1; // in scope 0 at $DIR/const_goto.rs:+0:20: +0:23 + let mut _0: u64; // return place in scope 0 at $DIR/const_goto.rs:+0:33: +0:36 +- let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- let mut _3: isize; // in scope 0 at $DIR/const_goto.rs:+1:22: +1:28 ++ let mut _2: isize; // in scope 0 at $DIR/const_goto.rs:+1:22: +1:28 + + bb0: { +- StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- _3 = discriminant(_1); // scope 0 at $DIR/const_goto.rs:+1:17: +1:20 +- switchInt(move _3) -> [1_isize: bb2, 2_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ _2 = discriminant(_1); // scope 0 at $DIR/const_goto.rs:+1:17: +1:20 ++ switchInt(move _2) -> [1_isize: bb2, 2_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb1: { +- _2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ _0 = const 42_u64; // scope 0 at $DIR/const_goto.rs:+1:53: +1:55 ++ goto -> bb3; // scope 0 at $DIR/const_goto.rs:+1:5: +1:57 + } + + bb2: { +- _2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb3: { +- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb4: { + _0 = const 23_u64; // scope 0 at $DIR/const_goto.rs:+1:41: +1:43 +- goto -> bb6; // scope 0 at $DIR/const_goto.rs:+1:5: +1:57 ++ goto -> bb3; // scope 0 at $DIR/const_goto.rs:+1:5: +1:57 + } + +- bb5: { +- _0 = const 42_u64; // scope 0 at $DIR/const_goto.rs:+1:53: +1:55 +- goto -> bb6; // scope 0 at $DIR/const_goto.rs:+1:5: +1:57 +- } +- +- bb6: { +- StorageDead(_2); // scope 0 at $DIR/const_goto.rs:+1:56: +1:57 ++ bb3: { + return; // scope 0 at $DIR/const_goto.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_goto.rs b/src/test/mir-opt/const_goto.rs new file mode 100644 index 000000000..939902e70 --- /dev/null +++ b/src/test/mir-opt/const_goto.rs @@ -0,0 +1,16 @@ +pub enum Foo { + A, + B, + C, + D, + E, + F, +} + +// EMIT_MIR const_goto.issue_77355_opt.ConstGoto.diff +fn issue_77355_opt(num: Foo) -> u64 { + if matches!(num, Foo::B | Foo::C) { 23 } else { 42 } +} +fn main() { + issue_77355_opt(Foo::A); +} diff --git a/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff b/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff new file mode 100644 index 000000000..623297aeb --- /dev/null +++ b/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff @@ -0,0 +1,51 @@ +- // MIR for `f` before ConstGoto ++ // MIR for `f` after ConstGoto + + fn f() -> u64 { + let mut _0: u64; // return place in scope 0 at $DIR/const_goto_const_eval_fail.rs:+0:44: +0:47 + let mut _1: bool; // in scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:11: +6:6 + let mut _2: i32; // in scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:15: +2:16 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:11: +6:6 + StorageLive(_2); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:15: +2:16 + _2 = const A; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:15: +2:16 + switchInt(_2) -> [1_i32: bb2, 2_i32: bb2, 3_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:9: +2:16 + } + + bb1: { + _1 = const true; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+4:18: +4:22 + goto -> bb3; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+4:18: +4:22 + } + + bb2: { + _1 = const B; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+3:26: +3:27 +- goto -> bb3; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+3:26: +3:27 ++ switchInt(_1) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6 + } + + bb3: { +- switchInt(_1) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6 +- } +- +- bb4: { + _0 = const 2_u64; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+8:17: +8:18 +- goto -> bb6; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+8:17: +8:18 ++ goto -> bb5; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+8:17: +8:18 + } + +- bb5: { ++ bb4: { + _0 = const 1_u64; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+7:18: +7:19 +- goto -> bb6; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+7:18: +7:19 ++ goto -> bb5; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+7:18: +7:19 + } + +- bb6: { ++ bb5: { + StorageDead(_2); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+10:1: +10:2 + StorageDead(_1); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+10:1: +10:2 + return; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+10:2: +10:2 + } + } + diff --git a/src/test/mir-opt/const_goto_const_eval_fail.rs b/src/test/mir-opt/const_goto_const_eval_fail.rs new file mode 100644 index 000000000..3b85fe6ab --- /dev/null +++ b/src/test/mir-opt/const_goto_const_eval_fail.rs @@ -0,0 +1,16 @@ +#![feature(min_const_generics)] +#![crate_type = "lib"] + +// If const eval fails, then don't crash +// EMIT_MIR const_goto_const_eval_fail.f.ConstGoto.diff +pub fn f<const A: i32, const B: bool>() -> u64 { + match { + match A { + 1 | 2 | 3 => B, + _ => true, + } + } { + false => 1, + true => 2, + } +} diff --git a/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff new file mode 100644 index 000000000..2b09ef786 --- /dev/null +++ b/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff @@ -0,0 +1,103 @@ +- // MIR for `match_nested_if` before ConstGoto ++ // MIR for `match_nested_if` after ConstGoto + + fn match_nested_if() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/const_goto_storage.rs:+0:25: +0:29 + let _1: bool; // in scope 0 at $DIR/const_goto_storage.rs:+1:9: +1:12 +- let mut _2: (); // in scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23 +- let mut _3: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10 +- let mut _4: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76 +- let mut _5: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52 +- let mut _6: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 ++ let mut _2: bool; // in scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 + scope 1 { + debug val => _1; // in scope 1 at $DIR/const_goto_storage.rs:+1:9: +1:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_goto_storage.rs:+1:9: +1:12 +- StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23 +- nop; // scope 0 at $DIR/const_goto_storage.rs:+1:21: +1:23 +- StorageLive(_3); // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10 +- StorageLive(_4); // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76 +- StorageLive(_5); // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52 +- StorageLive(_6); // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 +- _6 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 +- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 ++ StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 ++ _2 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 ++ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 + } + + bb1: { +- _5 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:31: +2:35 +- goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52 +- } +- +- bb2: { +- _5 = const false; // scope 0 at $DIR/const_goto_storage.rs:+2:45: +2:50 +- goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52 +- } +- +- bb3: { +- StorageDead(_6); // scope 0 at $DIR/const_goto_storage.rs:+2:51: +2:52 +- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52 +- } +- +- bb4: { +- _4 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:55: +2:59 +- goto -> bb6; // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76 +- } +- +- bb5: { +- _4 = const false; // scope 0 at $DIR/const_goto_storage.rs:+2:69: +2:74 +- goto -> bb6; // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76 +- } +- +- bb6: { +- StorageDead(_5); // scope 0 at $DIR/const_goto_storage.rs:+2:75: +2:76 +- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76 +- } +- +- bb7: { +- _3 = const true; // scope 0 at $DIR/const_goto_storage.rs:+3:13: +3:17 +- goto -> bb9; // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10 +- } +- +- bb8: { +- _3 = const false; // scope 0 at $DIR/const_goto_storage.rs:+5:13: +5:18 +- goto -> bb9; // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10 +- } +- +- bb9: { +- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10 +- } +- +- bb10: { +- StorageDead(_4); // scope 0 at $DIR/const_goto_storage.rs:+6:9: +6:10 +- StorageDead(_3); // scope 0 at $DIR/const_goto_storage.rs:+6:9: +6:10 ++ StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:+2:51: +2:52 + _1 = const true; // scope 0 at $DIR/const_goto_storage.rs:+8:17: +8:21 +- goto -> bb12; // scope 0 at $DIR/const_goto_storage.rs:+8:17: +8:21 ++ goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:+8:17: +8:21 + } + +- bb11: { +- StorageDead(_4); // scope 0 at $DIR/const_goto_storage.rs:+6:9: +6:10 +- StorageDead(_3); // scope 0 at $DIR/const_goto_storage.rs:+6:9: +6:10 ++ bb2: { ++ StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:+2:51: +2:52 + _1 = const false; // scope 0 at $DIR/const_goto_storage.rs:+10:14: +10:19 +- goto -> bb12; // scope 0 at $DIR/const_goto_storage.rs:+10:14: +10:19 ++ goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:+10:14: +10:19 + } + +- bb12: { +- StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:+11:6: +11:7 ++ bb3: { + _0 = _1; // scope 1 at $DIR/const_goto_storage.rs:+12:5: +12:8 + StorageDead(_1); // scope 0 at $DIR/const_goto_storage.rs:+13:1: +13:2 + return; // scope 0 at $DIR/const_goto_storage.rs:+13:2: +13:2 + } + } + diff --git a/src/test/mir-opt/const_goto_storage.rs b/src/test/mir-opt/const_goto_storage.rs new file mode 100644 index 000000000..4ef68e7e1 --- /dev/null +++ b/src/test/mir-opt/const_goto_storage.rs @@ -0,0 +1,19 @@ +// EMIT_MIR const_goto_storage.match_nested_if.ConstGoto.diff +fn match_nested_if() -> bool { + let val = match () { + () if if if if true { true } else { false } { true } else { false } { + true + } else { + false + } => + { + true + } + _ => false, + }; + val +} + +fn main() { + let _ = match_nested_if(); +} diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..7650769de --- /dev/null +++ b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,23 @@ +// MIR for `BAR::promoted[0]` after SimplifyCfg-elaborate-drops + +promoted[0] in BAR: &[&i32; 1] = { + let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 + let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 + let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 + + bb0: { + _3 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 + // mir::Constant + // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 + // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) } + _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 + _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 + _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + } +} + +alloc1 (static: Y, size: 4, align: 4) { + 2a 00 00 00 │ *... +} diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff new file mode 100644 index 000000000..f58ba56b9 --- /dev/null +++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff @@ -0,0 +1,54 @@ +- // MIR for `BAR` before PromoteTemps ++ // MIR for `BAR` after PromoteTemps + + static mut BAR: *const &i32 = { + let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:17: +0:28 + let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 + let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 + let _5: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 ++ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 +- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 +- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 +- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 +- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 ++ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + // mir::Constant +- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 +- // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) } +- _4 = &(*_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 +- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35 +- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 ++ // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:44 ++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(BAR, [], Some(promoted[0])) } ++ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 +- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:34: +0:35 + StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:34: +0:35 + _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 + // mir::Constant + // + span: $DIR/const-promotion-extern-static.rs:9:36: 9:42 + // + literal: Const { ty: for<'r> fn(&'r [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) } + } + + bb1: { +- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44 +- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44 + StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44 + return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28 + } +- } +- +- alloc1 (static: Y, size: 4, align: 4) { +- 2a 00 00 00 │ *... + } + diff --git a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir b/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir new file mode 100644 index 000000000..deb467977 --- /dev/null +++ b/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir @@ -0,0 +1,17 @@ +// MIR for `BOP` 0 mir_map + +static BOP: &i32 = { + let mut _0: &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:13: +0:17 + let _1: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23 + let _2: i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23 + StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23 + _2 = const 13_i32; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23 + _1 = &_2; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23 + _0 = &(*_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23 + StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:22: +0:23 + return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:17 + } +} diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..71827eab1 --- /dev/null +++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,21 @@ +// MIR for `FOO::promoted[0]` after SimplifyCfg-elaborate-drops + +promoted[0] in FOO: &[&i32; 1] = { + let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 + let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45 + let mut _3: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 + + bb0: { + _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 + // mir::Constant + // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 + // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } + _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:41: +0:43 + _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 + _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + } +} + +alloc3 (extern static: X) diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff new file mode 100644 index 000000000..5300f555f --- /dev/null +++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -0,0 +1,54 @@ +- // MIR for `FOO` before PromoteTemps ++ // MIR for `FOO` after PromoteTemps + + static mut FOO: *const &i32 = { + let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:17: +0:28 + let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 + let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45 + let _5: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 ++ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 +- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 +- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45 +- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 +- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 ++ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + // mir::Constant +- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 +- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } +- _4 = &(*_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:41: +0:43 +- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46 +- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 ++ // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:55 ++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(FOO, [], Some(promoted[0])) } ++ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 +- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:45: +0:46 + StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:45: +0:46 + _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 + // mir::Constant + // + span: $DIR/const-promotion-extern-static.rs:13:47: 13:53 + // + literal: Const { ty: for<'r> fn(&'r [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) } + } + + bb1: { +- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55 +- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55 + StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55 + return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:28 + } + } +- +- alloc3 (extern static: X) + diff --git a/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff new file mode 100644 index 000000000..836443bf4 --- /dev/null +++ b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff @@ -0,0 +1,32 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/aggregate.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/aggregate.rs:+1:9: +1:10 + let mut _2: i32; // in scope 0 at $DIR/aggregate.rs:+1:13: +1:24 + let mut _3: (i32, i32, i32); // in scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + scope 1 { + debug x => _1; // in scope 1 at $DIR/aggregate.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/aggregate.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24 + StorageLive(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + Deinit(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + (_3.0: i32) = const 0_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + (_3.1: i32) = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 + (_3.2: i32) = const 2_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22 +- _2 = (_3.1: i32); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24 +- _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/aggregate.rs:+1:13: +1:28 ++ _2 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:24 ++ _1 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:28 + StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+1:27: +1:28 + StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+1:28: +1:29 + nop; // scope 0 at $DIR/aggregate.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+2:1: +2:2 + return; // scope 0 at $DIR/aggregate.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/aggregate.rs b/src/test/mir-opt/const_prop/aggregate.rs new file mode 100644 index 000000000..7a3b26a73 --- /dev/null +++ b/src/test/mir-opt/const_prop/aggregate.rs @@ -0,0 +1,6 @@ +// compile-flags: -O + +// EMIT_MIR aggregate.main.ConstProp.diff +fn main() { + let x = (0, 1, 2).1 + 0; +} diff --git a/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff new file mode 100644 index 000000000..bb9abdd10 --- /dev/null +++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff @@ -0,0 +1,38 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/array_index.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/array_index.rs:+1:9: +1:10 + let mut _2: [u32; 4]; // in scope 0 at $DIR/array_index.rs:+1:18: +1:30 + let _3: usize; // in scope 0 at $DIR/array_index.rs:+1:31: +1:32 + let mut _4: usize; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33 + let mut _5: bool; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33 + scope 1 { + debug x => _1; // in scope 1 at $DIR/array_index.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/array_index.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:30 + _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30 + StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32 + _3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32 + _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 +- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33 +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 + } + + bb1: { +- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 + StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34 + StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34 + nop; // scope 0 at $DIR/array_index.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2 + return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff new file mode 100644 index 000000000..bb9abdd10 --- /dev/null +++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff @@ -0,0 +1,38 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/array_index.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/array_index.rs:+1:9: +1:10 + let mut _2: [u32; 4]; // in scope 0 at $DIR/array_index.rs:+1:18: +1:30 + let _3: usize; // in scope 0 at $DIR/array_index.rs:+1:31: +1:32 + let mut _4: usize; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33 + let mut _5: bool; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33 + scope 1 { + debug x => _1; // in scope 1 at $DIR/array_index.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/array_index.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:30 + _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30 + StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32 + _3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32 + _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 +- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33 +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 + } + + bb1: { +- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 ++ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33 + StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34 + StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34 + nop; // scope 0 at $DIR/array_index.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2 + return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/array_index.rs b/src/test/mir-opt/const_prop/array_index.rs new file mode 100644 index 000000000..2c5254b5d --- /dev/null +++ b/src/test/mir-opt/const_prop/array_index.rs @@ -0,0 +1,6 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +// EMIT_MIR array_index.main.ConstProp.diff +fn main() { + let x: u32 = [0, 1, 2, 3][2]; +} diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff new file mode 100644 index 000000000..45134a3fd --- /dev/null +++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff @@ -0,0 +1,54 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10 + let mut _3: i32; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 + let mut _4: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + let mut _5: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + let mut _6: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + let mut _7: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + scope 1 { + debug y => _1; // in scope 1 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11 + scope 2 { + debug _z => _2; // in scope 2 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10 + _1 = const 0_i32; // scope 0 at $DIR/bad_op_div_by_zero.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11 + StorageLive(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 +- _3 = _1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 +- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 +- assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 ++ _4 = const true; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + } + + bb1: { +- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 +- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 +- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 +- assert(!move _7, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _5 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _6 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _7 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + } + + bb2: { +- _2 = Div(const 1_i32, move _3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 ++ _2 = Div(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19 + StorageDead(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 + nop; // scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +3:2 + StorageDead(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2 + return; // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs new file mode 100644 index 000000000..6f39209b9 --- /dev/null +++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs @@ -0,0 +1,6 @@ +// EMIT_MIR bad_op_div_by_zero.main.ConstProp.diff +#[allow(unconditional_panic)] +fn main() { + let y = 0; + let _z = 1 / y; +} diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff new file mode 100644 index 000000000..221513042 --- /dev/null +++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff @@ -0,0 +1,54 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10 + let mut _3: i32; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 + let mut _4: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + let mut _5: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + let mut _6: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + let mut _7: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + scope 1 { + debug y => _1; // in scope 1 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11 + scope 2 { + debug _z => _2; // in scope 2 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10 + _1 = const 0_i32; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11 + StorageLive(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 +- _3 = _1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 +- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 ++ _4 = const true; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + } + + bb1: { +- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 +- assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _5 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _6 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _7 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + } + + bb2: { +- _2 = Rem(const 1_i32, move _3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 ++ _2 = Rem(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + StorageDead(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 + nop; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +3:2 + StorageDead(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2 + return; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs new file mode 100644 index 000000000..cc16a4a5a --- /dev/null +++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs @@ -0,0 +1,6 @@ +// EMIT_MIR bad_op_mod_by_zero.main.ConstProp.diff +#[allow(unconditional_panic)] +fn main() { + let y = 0; + let _z = 1 % y; +} diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff new file mode 100644 index 000000000..553488838 --- /dev/null +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff @@ -0,0 +1,56 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+0:11: +0:11 + let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35 + let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + scope 1 { + debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + scope 2 { + let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + scope 3 { + debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + // mir::Constant + // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 + // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } + _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35 + StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + } + + bb1: { + _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + nop; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 + StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 + return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff new file mode 100644 index 000000000..553488838 --- /dev/null +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff @@ -0,0 +1,56 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+0:11: +0:11 + let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35 + let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + scope 1 { + debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + scope 2 { + let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + scope 3 { + debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + // mir::Constant + // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 + // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } + _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35 + StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + } + + bb1: { + _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + nop; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 + StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 + return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs new file mode 100644 index 000000000..cf22b06d5 --- /dev/null +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs @@ -0,0 +1,9 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR bad_op_unsafe_oob_for_slices.main.ConstProp.diff +#[allow(unconditional_panic)] +fn main() { + let a: *const [_] = &[1, 2, 3]; + unsafe { + let _b = (*a)[3]; + } +} diff --git a/src/test/mir-opt/const_prop/boolean_identities.rs b/src/test/mir-opt/const_prop/boolean_identities.rs new file mode 100644 index 000000000..57164e3e7 --- /dev/null +++ b/src/test/mir-opt/const_prop/boolean_identities.rs @@ -0,0 +1,10 @@ +// compile-flags: -O -Zmir-opt-level=4 + +// EMIT_MIR boolean_identities.test.ConstProp.diff +pub fn test(x: bool, y: bool) -> bool { + (y | true) & (x & false) +} + +fn main() { + test(true, false); +} diff --git a/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff b/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff new file mode 100644 index 000000000..0de800917 --- /dev/null +++ b/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff @@ -0,0 +1,33 @@ +- // MIR for `test` before ConstProp ++ // MIR for `test` after ConstProp + + fn test(_1: bool, _2: bool) -> bool { + debug x => _1; // in scope 0 at $DIR/boolean_identities.rs:+0:13: +0:14 + debug y => _2; // in scope 0 at $DIR/boolean_identities.rs:+0:22: +0:23 + let mut _0: bool; // return place in scope 0 at $DIR/boolean_identities.rs:+0:34: +0:38 + let mut _3: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15 + let mut _4: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7 + let mut _5: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29 + let mut _6: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15 + StorageLive(_4); // scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7 + _4 = _2; // scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7 +- _3 = BitOr(move _4, const true); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15 ++ _3 = const true; // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15 + StorageDead(_4); // scope 0 at $DIR/boolean_identities.rs:+1:14: +1:15 + StorageLive(_5); // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29 + StorageLive(_6); // scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20 + _6 = _1; // scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20 +- _5 = BitAnd(move _6, const false); // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29 ++ _5 = const false; // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29 + StorageDead(_6); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29 +- _0 = BitAnd(move _3, move _5); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:29 ++ _0 = const false; // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:29 + StorageDead(_5); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29 + StorageDead(_3); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29 + return; // scope 0 at $DIR/boolean_identities.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff new file mode 100644 index 000000000..f2d4bee1b --- /dev/null +++ b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff @@ -0,0 +1,67 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/boxes.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/boxes.rs:+1:9: +1:10 + let mut _2: i32; // in scope 0 at $DIR/boxes.rs:+1:13: +1:22 + let mut _3: std::boxed::Box<i32>; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + let mut _4: usize; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + let mut _5: usize; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + let mut _6: *mut u8; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + let mut _8: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + let mut _9: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + let mut _10: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + let mut _11: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22 + scope 1 { + debug x => _1; // in scope 1 at $DIR/boxes.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/boxes.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/boxes.rs:+1:13: +1:22 + StorageLive(_3); // scope 0 at $DIR/boxes.rs:+1:14: +1:22 +- _4 = SizeOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +1:22 +- _5 = AlignOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +1:22 +- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22 ++ _4 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +1:22 ++ _5 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +1:22 ++ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22 + // mir::Constant + // + span: $DIR/boxes.rs:12:14: 12:22 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_7); // scope 0 at $DIR/boxes.rs:+1:14: +1:22 + _7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:+1:14: +1:22 + StorageLive(_8); // scope 0 at $DIR/boxes.rs:+1:19: +1:21 + _8 = (((_7.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:19: +1:21 + (*_8) = const 42_i32; // scope 0 at $DIR/boxes.rs:+1:19: +1:21 + StorageDead(_8); // scope 0 at $DIR/boxes.rs:+1:14: +1:22 + _3 = move _7; // scope 0 at $DIR/boxes.rs:+1:14: +1:22 + StorageDead(_7); // scope 0 at $DIR/boxes.rs:+1:21: +1:22 + StorageLive(_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22 + _9 = (((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:22 + _2 = (*_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22 + StorageDead(_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:26 + _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:26 + StorageDead(_2); // scope 0 at $DIR/boxes.rs:+1:25: +1:26 + drop(_3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/boxes.rs:+1:26: +1:27 + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/boxes.rs:+1:26: +1:27 + nop; // scope 0 at $DIR/boxes.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/boxes.rs:+2:1: +2:2 + return; // scope 0 at $DIR/boxes.rs:+2:2: +2:2 + } + + bb3 (cleanup): { + resume; // scope 0 at $DIR/boxes.rs:+0:1: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/boxes.rs b/src/test/mir-opt/const_prop/boxes.rs new file mode 100644 index 000000000..fea666a44 --- /dev/null +++ b/src/test/mir-opt/const_prop/boxes.rs @@ -0,0 +1,13 @@ +// compile-flags: -O +// ignore-emscripten compiled with panic=abort by default +// ignore-wasm32 +// ignore-wasm64 + +#![feature(box_syntax)] + +// Note: this test verifies that we, in fact, do not const prop `box` + +// EMIT_MIR boxes.main.ConstProp.diff +fn main() { + let x = *(box 42) + 0; +} diff --git a/src/test/mir-opt/const_prop/cast.main.ConstProp.diff b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff new file mode 100644 index 000000000..5698a612f --- /dev/null +++ b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff @@ -0,0 +1,28 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cast.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/cast.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/cast.rs:+1:9: +1:10 + let _2: u8; // in scope 1 at $DIR/cast.rs:+3:9: +3:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/cast.rs:+3:9: +3:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/cast.rs:+1:9: +1:10 +- _1 = const 42_u8 as u32 (Misc); // scope 0 at $DIR/cast.rs:+1:13: +1:24 ++ _1 = const 42_u32; // scope 0 at $DIR/cast.rs:+1:13: +1:24 + StorageLive(_2); // scope 1 at $DIR/cast.rs:+3:9: +3:10 +- _2 = const 42_u32 as u8 (Misc); // scope 1 at $DIR/cast.rs:+3:13: +3:24 ++ _2 = const 42_u8; // scope 1 at $DIR/cast.rs:+3:13: +3:24 + nop; // scope 0 at $DIR/cast.rs:+0:11: +4:2 + StorageDead(_2); // scope 1 at $DIR/cast.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/cast.rs:+4:1: +4:2 + return; // scope 0 at $DIR/cast.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop/cast.rs b/src/test/mir-opt/const_prop/cast.rs new file mode 100644 index 000000000..680cab007 --- /dev/null +++ b/src/test/mir-opt/const_prop/cast.rs @@ -0,0 +1,7 @@ +// EMIT_MIR cast.main.ConstProp.diff + +fn main() { + let x = 42u8 as u32; + + let y = 42u32 as u8; +} diff --git a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff new file mode 100644 index 000000000..5e33d0542 --- /dev/null +++ b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff @@ -0,0 +1,28 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/checked_add.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/checked_add.rs:+1:9: +1:10 + let mut _2: (u32, bool); // in scope 0 at $DIR/checked_add.rs:+1:18: +1:23 + scope 1 { + debug x => _1; // in scope 1 at $DIR/checked_add.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/checked_add.rs:+1:9: +1:10 +- _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 +- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 ++ _2 = const (2_u32, false); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 + } + + bb1: { +- _1 = move (_2.0: u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 ++ _1 = const 2_u32; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23 + nop; // scope 0 at $DIR/checked_add.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/checked_add.rs:+2:1: +2:2 + return; // scope 0 at $DIR/checked_add.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/checked_add.rs b/src/test/mir-opt/const_prop/checked_add.rs new file mode 100644 index 000000000..08d59b6fb --- /dev/null +++ b/src/test/mir-opt/const_prop/checked_add.rs @@ -0,0 +1,6 @@ +// compile-flags: -C overflow-checks=on + +// EMIT_MIR checked_add.main.ConstProp.diff +fn main() { + let x: u32 = 1 + 1; +} diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff new file mode 100644 index 000000000..c21b24591 --- /dev/null +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff @@ -0,0 +1,44 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +0:11 + let _1: usize; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10 + let mut _2: *const i32; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30 + let _3: &i32; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + let _4: (); // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12 + let mut _5: usize; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10 + StorageLive(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30 + StorageLive(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + _3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + // mir::Constant + // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 + // + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) } + _2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:39 + StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:38: +2:39 + StorageDead(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:39: +2:40 + StorageLive(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12 + StorageLive(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11 + _5 = _1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11 + _4 = read(move _5) -> bb1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12 + // mir::Constant + // + span: $DIR/const_prop_fails_gracefully.rs:8:5: 8:9 + // + literal: Const { ty: fn(usize) {read}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:11: +3:12 + StorageDead(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:12: +3:13 + nop; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:1: +4:2 + return; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs new file mode 100644 index 000000000..8bd68527f --- /dev/null +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs @@ -0,0 +1,9 @@ +#[inline(never)] +fn read(_: usize) { } + +// EMIT_MIR const_prop_fails_gracefully.main.ConstProp.diff +fn main() { + const FOO: &i32 = &1; + let x = FOO as *const i32 as usize; + read(x); +} diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control-flow-simplification.rs new file mode 100644 index 000000000..aa4ce19f6 --- /dev/null +++ b/src/test/mir-opt/const_prop/control-flow-simplification.rs @@ -0,0 +1,20 @@ +// compile-flags: -Zmir-opt-level=1 + +trait NeedsDrop:Sized{ + const NEEDS:bool=std::mem::needs_drop::<Self>(); +} + +impl<This> NeedsDrop for This{} + +// EMIT_MIR control_flow_simplification.hello.ConstProp.diff +// EMIT_MIR control_flow_simplification.hello.PreCodegen.before.mir +fn hello<T>(){ + if <bool>::NEEDS { + panic!() + } +} + +pub fn main() { + hello::<()>(); + hello::<Vec<()>>(); +} diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff new file mode 100644 index 000000000..5f4df0d88 --- /dev/null +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff @@ -0,0 +1,34 @@ +- // MIR for `hello` before ConstProp ++ // MIR for `hello` after ConstProp + + fn hello() -> () { + let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14 + let mut _1: bool; // in scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 + let mut _2: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + + bb0: { + StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 +- _1 = const <bool as NeedsDrop>::NEEDS; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 +- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 ++ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 ++ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 + } + + bb1: { + StorageLive(_2); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + _2 = begin_panic::<&str>(const "explicit panic"); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) } + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb2: { + nop; // scope 0 at $DIR/control-flow-simplification.rs:+3:6: +3:6 + StorageDead(_1); // scope 0 at $DIR/control-flow-simplification.rs:+3:5: +3:6 + return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir new file mode 100644 index 000000000..70f979775 --- /dev/null +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir @@ -0,0 +1,9 @@ +// MIR for `hello` before PreCodegen + +fn hello() -> () { + let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14 + + bb0: { + return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff new file mode 100644 index 000000000..5b4ecaa80 --- /dev/null +++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff @@ -0,0 +1,52 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/discriminant.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/discriminant.rs:+1:9: +1:10 + let mut _2: i32; // in scope 0 at $DIR/discriminant.rs:+1:13: +1:64 + let mut _3: std::option::Option<bool>; // in scope 0 at $DIR/discriminant.rs:+1:34: +1:44 + let mut _4: isize; // in scope 0 at $DIR/discriminant.rs:+1:21: +1:31 + scope 1 { + debug x => _1; // in scope 1 at $DIR/discriminant.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/discriminant.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/discriminant.rs:+1:13: +1:64 + StorageLive(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 + Deinit(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 + ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 + discriminant(_3) = 1; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 +- _4 = discriminant(_3); // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 +- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 ++ _4 = const 1_isize; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 ++ switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + } + + bb1: { + switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + } + + bb2: { + _2 = const 42_i32; // scope 2 at $DIR/discriminant.rs:+1:47: +1:49 + goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64 + } + + bb3: { + _2 = const 10_i32; // scope 0 at $DIR/discriminant.rs:+1:59: +1:61 + goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64 + } + + bb4: { + _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:+1:13: +1:68 + StorageDead(_2); // scope 0 at $DIR/discriminant.rs:+1:67: +1:68 + StorageDead(_3); // scope 0 at $DIR/discriminant.rs:+1:68: +1:69 + nop; // scope 0 at $DIR/discriminant.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2 + return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff new file mode 100644 index 000000000..5b4ecaa80 --- /dev/null +++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff @@ -0,0 +1,52 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/discriminant.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/discriminant.rs:+1:9: +1:10 + let mut _2: i32; // in scope 0 at $DIR/discriminant.rs:+1:13: +1:64 + let mut _3: std::option::Option<bool>; // in scope 0 at $DIR/discriminant.rs:+1:34: +1:44 + let mut _4: isize; // in scope 0 at $DIR/discriminant.rs:+1:21: +1:31 + scope 1 { + debug x => _1; // in scope 1 at $DIR/discriminant.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/discriminant.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/discriminant.rs:+1:13: +1:64 + StorageLive(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 + Deinit(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 + ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 + discriminant(_3) = 1; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 +- _4 = discriminant(_3); // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 +- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 ++ _4 = const 1_isize; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 ++ switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + } + + bb1: { + switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + } + + bb2: { + _2 = const 42_i32; // scope 2 at $DIR/discriminant.rs:+1:47: +1:49 + goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64 + } + + bb3: { + _2 = const 10_i32; // scope 0 at $DIR/discriminant.rs:+1:59: +1:61 + goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64 + } + + bb4: { + _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:+1:13: +1:68 + StorageDead(_2); // scope 0 at $DIR/discriminant.rs:+1:67: +1:68 + StorageDead(_3); // scope 0 at $DIR/discriminant.rs:+1:68: +1:69 + nop; // scope 0 at $DIR/discriminant.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2 + return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/discriminant.rs b/src/test/mir-opt/const_prop/discriminant.rs new file mode 100644 index 000000000..67538b3c7 --- /dev/null +++ b/src/test/mir-opt/const_prop/discriminant.rs @@ -0,0 +1,12 @@ +// compile-flags: -O + +// FIXME(wesleywiser): Ideally, we could const-prop away all of this and just be left with +// `let x = 42` but that doesn't work because const-prop doesn't support `Operand::Indirect` +// and `InterpCx::eval_place()` always forces an allocation which creates the `Indirect`. +// Fixing either of those will allow us to const-prop this away. + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR discriminant.main.ConstProp.diff +fn main() { + let x = (if let Some(true) = Some(true) { 42 } else { 10 }) + 0; +} diff --git a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff new file mode 100644 index 000000000..2e1e32545 --- /dev/null +++ b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff @@ -0,0 +1,33 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/indirect.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/indirect.rs:+1:9: +1:10 + let mut _2: u8; // in scope 0 at $DIR/indirect.rs:+1:13: +1:25 + let mut _3: (u8, bool); // in scope 0 at $DIR/indirect.rs:+1:13: +1:29 + scope 1 { + debug x => _1; // in scope 1 at $DIR/indirect.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/indirect.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/indirect.rs:+1:13: +1:25 +- _2 = const 2_u32 as u8 (Misc); // scope 0 at $DIR/indirect.rs:+1:13: +1:25 +- _3 = CheckedAdd(_2, const 1_u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29 +- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29 ++ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:25 ++ _3 = const (3_u8, false); // scope 0 at $DIR/indirect.rs:+1:13: +1:29 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u8, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29 + } + + bb1: { +- _1 = move (_3.0: u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29 ++ _1 = const 3_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:29 + StorageDead(_2); // scope 0 at $DIR/indirect.rs:+1:28: +1:29 + nop; // scope 0 at $DIR/indirect.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/indirect.rs:+2:1: +2:2 + return; // scope 0 at $DIR/indirect.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/indirect.rs b/src/test/mir-opt/const_prop/indirect.rs new file mode 100644 index 000000000..37217ca81 --- /dev/null +++ b/src/test/mir-opt/const_prop/indirect.rs @@ -0,0 +1,6 @@ +// compile-flags: -C overflow-checks=on + +// EMIT_MIR indirect.main.ConstProp.diff +fn main() { + let x = (2u32 as u8) + 1; +} diff --git a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff new file mode 100644 index 000000000..67a4dc3c0 --- /dev/null +++ b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/invalid_constant.rs:+0:11: +0:11 + let _1: char; // in scope 0 at $DIR/invalid_constant.rs:+6:9: +6:22 + let mut _2: main::InvalidChar; // in scope 0 at $DIR/invalid_constant.rs:+6:34: +6:63 + let mut _4: E; // in scope 0 at $DIR/invalid_constant.rs:+13:25: +13:59 + let mut _5: main::InvalidTag; // in scope 0 at $DIR/invalid_constant.rs:+13:34: +13:55 + let mut _7: Empty; // in scope 0 at $DIR/invalid_constant.rs:+20:35: +20:73 + let mut _8: main::NoVariants; // in scope 0 at $DIR/invalid_constant.rs:+20:44: +20:65 + scope 1 { + debug _invalid_char => _1; // in scope 1 at $DIR/invalid_constant.rs:+6:9: +6:22 + let _3: [E; 1]; // in scope 1 at $DIR/invalid_constant.rs:+13:9: +13:21 + scope 3 { + debug _invalid_tag => _3; // in scope 3 at $DIR/invalid_constant.rs:+13:9: +13:21 + let _6: [Empty; 1]; // in scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31 + scope 5 { + debug _enum_without_variants => _6; // in scope 5 at $DIR/invalid_constant.rs:+20:9: +20:31 + let _9: main::Str<"���">; // in scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 + scope 7 { + debug _non_utf8_str => _9; // in scope 7 at $DIR/invalid_constant.rs:+24:9: +24:22 + } + } + scope 6 { + } + } + scope 4 { + } + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/invalid_constant.rs:+6:9: +6:22 + StorageLive(_2); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63 + Deinit(_2); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63 + (_2.0: u32) = const 1114113_u32; // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63 +- _1 = (_2.1: char); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:67 ++ _1 = const {transmute(0x00110001): char}; // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:67 + StorageDead(_2); // scope 0 at $DIR/invalid_constant.rs:+6:69: +6:70 + StorageLive(_3); // scope 1 at $DIR/invalid_constant.rs:+13:9: +13:21 + StorageLive(_4); // scope 1 at $DIR/invalid_constant.rs:+13:25: +13:59 + StorageLive(_5); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55 + Deinit(_5); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55 + (_5.0: u32) = const 4_u32; // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55 +- _4 = (_5.1: E); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:57 +- _3 = [move _4]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60 ++ _4 = const Scalar(0x00000004): E; // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:57 ++ // mir::Constant ++ // + span: $DIR/invalid_constant.rs:28:34: 28:57 ++ // + literal: Const { ty: E, val: Value(Scalar(0x00000004)) } ++ _3 = [const Scalar(0x00000004): E]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60 ++ // mir::Constant ++ // + span: $DIR/invalid_constant.rs:28:24: 28:60 ++ // + literal: Const { ty: E, val: Value(Scalar(0x00000004)) } + StorageDead(_4); // scope 1 at $DIR/invalid_constant.rs:+13:59: +13:60 + StorageDead(_5); // scope 1 at $DIR/invalid_constant.rs:+13:60: +13:61 + StorageLive(_6); // scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31 + StorageLive(_7); // scope 3 at $DIR/invalid_constant.rs:+20:35: +20:73 + StorageLive(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65 + Deinit(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65 + (_8.0: u32) = const 0_u32; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65 + nop; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:71 + nop; // scope 3 at $DIR/invalid_constant.rs:+20:34: +20:74 + StorageDead(_7); // scope 3 at $DIR/invalid_constant.rs:+20:73: +20:74 + StorageDead(_8); // scope 3 at $DIR/invalid_constant.rs:+20:74: +20:75 + StorageLive(_9); // scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 + nop; // scope 0 at $DIR/invalid_constant.rs:+0:11: +27:2 + StorageDead(_9); // scope 5 at $DIR/invalid_constant.rs:+27:1: +27:2 + StorageDead(_6); // scope 3 at $DIR/invalid_constant.rs:+27:1: +27:2 + StorageDead(_3); // scope 1 at $DIR/invalid_constant.rs:+27:1: +27:2 + StorageDead(_1); // scope 0 at $DIR/invalid_constant.rs:+27:1: +27:2 + return; // scope 0 at $DIR/invalid_constant.rs:+27:2: +27:2 + } + } + diff --git a/src/test/mir-opt/const_prop/invalid_constant.rs b/src/test/mir-opt/const_prop/invalid_constant.rs new file mode 100644 index 000000000..0337a7ca8 --- /dev/null +++ b/src/test/mir-opt/const_prop/invalid_constant.rs @@ -0,0 +1,42 @@ +// Verify that we can pretty print invalid constants. + +#![feature(adt_const_params)] +#![feature(inline_const)] +#![allow(incomplete_features)] + +#[derive(Copy, Clone)] +#[repr(u32)] +enum E { A, B, C } + +#[derive(Copy, Clone)] +enum Empty {} + +// EMIT_MIR invalid_constant.main.ConstProp.diff +fn main() { + // An invalid char. + union InvalidChar { + int: u32, + chr: char, + } + let _invalid_char = unsafe { InvalidChar { int: 0x110001 }.chr }; + + // An enum with an invalid tag. Regression test for #93688. + union InvalidTag { + int: u32, + e: E, + } + let _invalid_tag = [unsafe { InvalidTag { int: 4 }.e }]; + + // An enum without variants. Regression test for #94073. + union NoVariants { + int: u32, + empty: Empty, + } + let _enum_without_variants = [unsafe { NoVariants { int: 0 }.empty }]; + + // A non-UTF-8 string slice. Regression test for #75763 and #78520. + struct Str<const S: &'static str>; + let _non_utf8_str: Str::<{ + unsafe { std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) } + }>; +} diff --git a/src/test/mir-opt/const_prop/issue-66971.rs b/src/test/mir-opt/const_prop/issue-66971.rs new file mode 100644 index 000000000..81eccae46 --- /dev/null +++ b/src/test/mir-opt/const_prop/issue-66971.rs @@ -0,0 +1,17 @@ +// compile-flags: -Z mir-opt-level=3 + +// Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected +// outputs below, after ConstProp this is how _2 would look like with the bug: +// +// _2 = (const Scalar(0x00) : (), const 0u8); +// +// Which has the wrong type. + +fn encode(this: ((), u8, u8)) { + assert!(this.2 == 0); +} + +// EMIT_MIR issue_66971.main.ConstProp.diff +fn main() { + encode(((), 0, 0)); +} diff --git a/src/test/mir-opt/const_prop/issue-67019.rs b/src/test/mir-opt/const_prop/issue-67019.rs new file mode 100644 index 000000000..c78b8b971 --- /dev/null +++ b/src/test/mir-opt/const_prop/issue-67019.rs @@ -0,0 +1,12 @@ +// compile-flags: -Z mir-opt-level=3 + +// This used to ICE in const-prop + +fn test(this: ((u8, u8),)) { + assert!((this.0).0 == 1); +} + +// EMIT_MIR issue_67019.main.ConstProp.diff +fn main() { + test(((1, 2),)); +} diff --git a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff new file mode 100644 index 000000000..b3d5980aa --- /dev/null +++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff @@ -0,0 +1,33 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-66971.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue-66971.rs:+1:5: +1:23 + let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 + let mut _3: (); // in scope 0 at $DIR/issue-66971.rs:+1:13: +1:15 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23 + StorageLive(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 + StorageLive(_3); // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15 + nop; // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15 + Deinit(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 + nop; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 + (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 + (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22 + StorageDead(_3); // scope 0 at $DIR/issue-66971.rs:+1:21: +1:22 + _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23 + // mir::Constant + // + span: $DIR/issue-66971.rs:16:5: 16:11 + // + literal: Const { ty: fn(((), u8, u8)) {encode}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/issue-66971.rs:+1:22: +1:23 + StorageDead(_1); // scope 0 at $DIR/issue-66971.rs:+1:23: +1:24 + nop; // scope 0 at $DIR/issue-66971.rs:+0:11: +2:2 + return; // scope 0 at $DIR/issue-66971.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff new file mode 100644 index 000000000..8330b5052 --- /dev/null +++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff @@ -0,0 +1,34 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-67019.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue-67019.rs:+1:5: +1:20 + let mut _2: ((u8, u8),); // in scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 + let mut _3: (u8, u8); // in scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20 + StorageLive(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 + StorageLive(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 + Deinit(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 + (_3.0: u8) = const 1_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 + (_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17 + Deinit(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 +- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 ++ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19 + StorageDead(_3); // scope 0 at $DIR/issue-67019.rs:+1:18: +1:19 + _1 = test(move _2) -> bb1; // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20 + // mir::Constant + // + span: $DIR/issue-67019.rs:11:5: 11:9 + // + literal: Const { ty: fn(((u8, u8),)) {test}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/issue-67019.rs:+1:19: +1:20 + StorageDead(_1); // scope 0 at $DIR/issue-67019.rs:+1:20: +1:21 + nop; // scope 0 at $DIR/issue-67019.rs:+0:11: +2:2 + return; // scope 0 at $DIR/issue-67019.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff new file mode 100644 index 000000000..96de39258 --- /dev/null +++ b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff @@ -0,0 +1,37 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/large_array_index.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/large_array_index.rs:+2:9: +2:10 + let mut _2: [u8; 5000]; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + let _3: usize; // in scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + let mut _4: usize; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + let mut _5: bool; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + scope 1 { + debug x => _1; // in scope 1 at $DIR/large_array_index.rs:+2:9: +2:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:+2:9: +2:10 + StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + } + + bb1: { + _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + nop; // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2 + return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff new file mode 100644 index 000000000..96de39258 --- /dev/null +++ b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff @@ -0,0 +1,37 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/large_array_index.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/large_array_index.rs:+2:9: +2:10 + let mut _2: [u8; 5000]; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + let _3: usize; // in scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + let mut _4: usize; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + let mut _5: bool; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + scope 1 { + debug x => _1; // in scope 1 at $DIR/large_array_index.rs:+2:9: +2:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:+2:9: +2:10 + StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29 + StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31 + _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + } + + bb1: { + _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 + StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 + nop; // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2 + return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/const_prop/large_array_index.rs b/src/test/mir-opt/const_prop/large_array_index.rs new file mode 100644 index 000000000..48d134376 --- /dev/null +++ b/src/test/mir-opt/const_prop/large_array_index.rs @@ -0,0 +1,7 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +// EMIT_MIR large_array_index.main.ConstProp.diff +fn main() { + // check that we don't propagate this, because it's too large + let x: u8 = [0_u8; 5000][2]; +} diff --git a/src/test/mir-opt/const_prop/mult_by_zero.rs b/src/test/mir-opt/const_prop/mult_by_zero.rs new file mode 100644 index 000000000..b0ecdf181 --- /dev/null +++ b/src/test/mir-opt/const_prop/mult_by_zero.rs @@ -0,0 +1,10 @@ +// compile-flags: -O -Zmir-opt-level=4 + +// EMIT_MIR mult_by_zero.test.ConstProp.diff +fn test(x : i32) -> i32 { + x * 0 +} + +fn main() { + test(10); +} diff --git a/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff b/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff new file mode 100644 index 000000000..629c8e601 --- /dev/null +++ b/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff @@ -0,0 +1,18 @@ +- // MIR for `test` before ConstProp ++ // MIR for `test` after ConstProp + + fn test(_1: i32) -> i32 { + debug x => _1; // in scope 0 at $DIR/mult_by_zero.rs:+0:9: +0:10 + let mut _0: i32; // return place in scope 0 at $DIR/mult_by_zero.rs:+0:21: +0:24 + let mut _2: i32; // in scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4 + _2 = _1; // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4 +- _0 = Mul(move _2, const 0_i32); // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8 ++ _0 = const 0_i32; // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8 + StorageDead(_2); // scope 0 at $DIR/mult_by_zero.rs:+1:7: +1:8 + return; // scope 0 at $DIR/mult_by_zero.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff new file mode 100644 index 000000000..3bbd6a87f --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff @@ -0,0 +1,28 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/mutable_variable.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/mutable_variable.rs:+1:9: +1:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/mutable_variable.rs:+1:9: +1:14 + let _2: i32; // in scope 1 at $DIR/mutable_variable.rs:+3:9: +3:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/mutable_variable.rs:+3:9: +3:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/mutable_variable.rs:+1:9: +1:14 + _1 = const 42_i32; // scope 0 at $DIR/mutable_variable.rs:+1:17: +1:19 + _1 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:+2:5: +2:11 + StorageLive(_2); // scope 1 at $DIR/mutable_variable.rs:+3:9: +3:10 +- _2 = _1; // scope 1 at $DIR/mutable_variable.rs:+3:13: +3:14 ++ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:+3:13: +3:14 + nop; // scope 0 at $DIR/mutable_variable.rs:+0:11: +4:2 + StorageDead(_2); // scope 1 at $DIR/mutable_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/mutable_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/mutable_variable.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop/mutable_variable.rs b/src/test/mir-opt/const_prop/mutable_variable.rs new file mode 100644 index 000000000..801e7a9fc --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable.rs @@ -0,0 +1,8 @@ +// compile-flags: -O + +// EMIT_MIR mutable_variable.main.ConstProp.diff +fn main() { + let mut x = 42; + x = 99; + let y = x; +} diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff new file mode 100644 index 000000000..fed6a98b9 --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff @@ -0,0 +1,30 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +0:11 + let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 + let _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 + Deinit(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25 + (_1.0: i32) = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25 + (_1.1: i32) = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25 + (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+2:5: +2:13 + StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 +- _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 ++ _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 + nop; // scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +4:2 + StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 + return; // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs new file mode 100644 index 000000000..e0b4b77ba --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs @@ -0,0 +1,8 @@ +// compile-flags: -O + +// EMIT_MIR mutable_variable_aggregate.main.ConstProp.diff +fn main() { + let mut x = (42, 43); + x.1 = 99; + let y = x; +} diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff new file mode 100644 index 000000000..90eebd8fe --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff @@ -0,0 +1,36 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+0:11: +0:11 + let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14 + let _2: &mut (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 + scope 2 { + debug z => _2; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 + let _3: (i32, i32); // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + scope 3 { + debug y => _3; // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14 + Deinit(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25 + (_1.0: i32) = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25 + (_1.1: i32) = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25 + StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 + _2 = &mut _1; // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:13: +2:19 + ((*_2).1: i32) = const 99_i32; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+3:5: +3:13 + StorageLive(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + _3 = _1; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14 + nop; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+0:11: +5:2 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 + return; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs new file mode 100644 index 000000000..79ac497c7 --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs @@ -0,0 +1,9 @@ +// compile-flags: -O + +// EMIT_MIR mutable_variable_aggregate_mut_ref.main.ConstProp.diff +fn main() { + let mut x = (42, 43); + let z = &mut x; + z.1 = 99; + let y = x; +} diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff new file mode 100644 index 000000000..c678f7b03 --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff @@ -0,0 +1,35 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +0:11 + let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14 + let _2: i32; // in scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14 + _1 = foo() -> bb1; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:29: +1:34 + // mir::Constant + // + span: $DIR/mutable_variable_aggregate_partial_read.rs:5:29: 5:32 + // + literal: Const { ty: fn() -> (i32, i32) {foo}, val: Value(<ZST>) } + } + + bb1: { + (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+2:5: +2:13 + (_1.0: i32) = const 42_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+3:5: +3:13 + StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10 +- _2 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16 ++ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16 + nop; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +5:2 + StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2 + return; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs new file mode 100644 index 000000000..9bb62b897 --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs @@ -0,0 +1,14 @@ +// compile-flags: -O + +// EMIT_MIR mutable_variable_aggregate_partial_read.main.ConstProp.diff +fn main() { + let mut x: (i32, i32) = foo(); + x.1 = 99; + x.0 = 42; + let y = x.1; +} + +#[inline(never)] +fn foo() -> (i32, i32) { + unimplemented!() +} diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff new file mode 100644 index 000000000..4c2ba9a09 --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff @@ -0,0 +1,48 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +0:11 + let mut _1: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14 + let _2: (); // in scope 0 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6 + let mut _3: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + let mut _4: *mut u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + scope 1 { + debug x => _1; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14 + let _5: u32; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 + scope 2 { + } + scope 3 { + debug y => _5; // in scope 3 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14 + _1 = const 42_u32; // scope 0 at $DIR/mutable_variable_no_prop.rs:+1:17: +1:19 + StorageLive(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6 + StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + _4 = const {alloc1: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + // mir::Constant + // + span: $DIR/mutable_variable_no_prop.rs:9:13: 9:19 + // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) } + _3 = (*_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + _1 = move _3; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:18: +3:19 + StorageDead(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:19: +3:20 + nop; // scope 2 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6 + StorageDead(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:+4:5: +4:6 + StorageLive(_5); // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 + _5 = _1; // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:13: +5:14 + nop; // scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +6:2 + StorageDead(_5); // scope 1 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2 + return; // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:2: +6:2 + } + } + + alloc1 (static: STATIC, size: 4, align: 4) { + 2a 00 00 00 │ *... + } + diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs new file mode 100644 index 000000000..4126fb3c6 --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs @@ -0,0 +1,12 @@ +// compile-flags: -O + +static mut STATIC: u32 = 42; + +// EMIT_MIR mutable_variable_no_prop.main.ConstProp.diff +fn main() { + let mut x = 42; + unsafe { + x = STATIC; + } + let y = x; +} diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff new file mode 100644 index 000000000..5328792b3 --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff @@ -0,0 +1,53 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 + let mut _3: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + scope 1 { + debug a => _1; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 + let mut _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + scope 2 { + debug x => _2; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let _4: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + scope 3 { + debug y => _4; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + let _5: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + scope 4 { + debug z => _5; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 + _1 = foo() -> bb1; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:13: +1:18 + // mir::Constant + // + span: $DIR/mutable_variable_unprop_assign.rs:5:13: 5:16 + // + literal: Const { ty: fn() -> i32 {foo}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + Deinit(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + (_2.0: i32) = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + (_2.1: i32) = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + _3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + (_2.1: i32) = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + _4 = (_2.1: i32); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 + StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 + nop; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +6:2 + StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs new file mode 100644 index 000000000..13f1b3f47 --- /dev/null +++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs @@ -0,0 +1,15 @@ +// compile-flags: -O + +// EMIT_MIR mutable_variable_unprop_assign.main.ConstProp.diff +fn main() { + let a = foo(); + let mut x: (i32, i32) = (1, 2); + x.1 = a; + let y = x.1; + let z = x.0; // this could theoretically be allowed, but we can't handle it right now +} + +#[inline(never)] +fn foo() -> i32 { + unimplemented!() +} diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff new file mode 100644 index 000000000..94aadfaf8 --- /dev/null +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff @@ -0,0 +1,68 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 +- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 +- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + } + + bb1: { +- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 +- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + } + + bb2: { +- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 + nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 + StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff new file mode 100644 index 000000000..94aadfaf8 --- /dev/null +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff @@ -0,0 +1,68 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 +- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 +- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + } + + bb1: { +- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 ++ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18 + StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31 + StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 + _6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 +- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + } + + bb2: { +- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 ++ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 + StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 + StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 + nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 + StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir new file mode 100644 index 000000000..75cea8ad2 --- /dev/null +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir @@ -0,0 +1,27 @@ +// MIR for `main` after SimplifyLocals + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir new file mode 100644 index 000000000..75cea8ad2 --- /dev/null +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir @@ -0,0 +1,27 @@ +// MIR for `main` after SimplifyLocals + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.rs b/src/test/mir-opt/const_prop/optimizes_into_variable.rs new file mode 100644 index 000000000..17265b7eb --- /dev/null +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.rs @@ -0,0 +1,15 @@ +// compile-flags: -C overflow-checks=on + +struct Point { + x: u32, + y: u32, +} + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR optimizes_into_variable.main.ConstProp.diff +// EMIT_MIR optimizes_into_variable.main.SimplifyLocals.after.mir +fn main() { + let x = 2 + 2; + let y = [0, 1, 2, 3, 4, 5][3]; + let z = (Point { x: 12, y: 42}).y; +} diff --git a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff new file mode 100644 index 000000000..89f43d751 --- /dev/null +++ b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff @@ -0,0 +1,48 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/read_immutable_static.rs:+0:11: +0:11 + let _1: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:9: +1:10 + let mut _2: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16 + let mut _3: &u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16 + let mut _4: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22 + let mut _5: &u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22 + scope 1 { + debug x => _1; // in scope 1 at $DIR/read_immutable_static.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/read_immutable_static.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16 + StorageLive(_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16 + _3 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16 + // mir::Constant + // + span: $DIR/read_immutable_static.rs:7:13: 7:16 + // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) } +- _2 = (*_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16 ++ _2 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16 + StorageLive(_4); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22 + StorageLive(_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22 + _5 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22 + // mir::Constant + // + span: $DIR/read_immutable_static.rs:7:19: 7:22 + // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) } +- _4 = (*_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22 +- _1 = Add(move _2, move _4); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:22 ++ _4 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22 ++ _1 = const 4_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:22 + StorageDead(_4); // scope 0 at $DIR/read_immutable_static.rs:+1:21: +1:22 + StorageDead(_2); // scope 0 at $DIR/read_immutable_static.rs:+1:21: +1:22 + StorageDead(_5); // scope 0 at $DIR/read_immutable_static.rs:+1:22: +1:23 + StorageDead(_3); // scope 0 at $DIR/read_immutable_static.rs:+1:22: +1:23 + nop; // scope 0 at $DIR/read_immutable_static.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/read_immutable_static.rs:+2:1: +2:2 + return; // scope 0 at $DIR/read_immutable_static.rs:+2:2: +2:2 + } + } + + alloc1 (static: FOO, size: 1, align: 1) { + 02 │ . + } + diff --git a/src/test/mir-opt/const_prop/read_immutable_static.rs b/src/test/mir-opt/const_prop/read_immutable_static.rs new file mode 100644 index 000000000..8a5f12c6f --- /dev/null +++ b/src/test/mir-opt/const_prop/read_immutable_static.rs @@ -0,0 +1,8 @@ +// compile-flags: -O + +static FOO: u8 = 2; + +// EMIT_MIR read_immutable_static.main.ConstProp.diff +fn main() { + let x = FOO + FOO; +} diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff new file mode 100644 index 000000000..c8b09220f --- /dev/null +++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff @@ -0,0 +1,27 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/ref_deref.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 + let mut _2: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + let _3: i32; // in scope 0 at $DIR/ref_deref.rs:+1:8: +1:9 + let mut _4: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 + StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + // mir::Constant + // + span: $DIR/ref_deref.rs:5:6: 5:10 + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + _2 = _4; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 +- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 ++ _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 + StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11 + StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11 + nop; // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2 + return; // scope 0 at $DIR/ref_deref.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff new file mode 100644 index 000000000..d141d2cf8 --- /dev/null +++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff @@ -0,0 +1,30 @@ +- // MIR for `main` before PromoteTemps ++ // MIR for `main` after PromoteTemps + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/ref_deref.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 + let mut _2: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + let _3: i32; // in scope 0 at $DIR/ref_deref.rs:+1:8: +1:9 ++ let mut _4: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 + StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 +- StorageLive(_3); // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9 +- _3 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9 +- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 ++ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 ++ // mir::Constant ++ // + span: $DIR/ref_deref.rs:5:6: 5:10 ++ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } ++ _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 +- StorageDead(_3); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11 + StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11 + StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11 + _0 = const (); // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2 + return; // scope 0 at $DIR/ref_deref.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/ref_deref.rs b/src/test/mir-opt/const_prop/ref_deref.rs new file mode 100644 index 000000000..30ec97663 --- /dev/null +++ b/src/test/mir-opt/const_prop/ref_deref.rs @@ -0,0 +1,6 @@ +// EMIT_MIR ref_deref.main.PromoteTemps.diff +// EMIT_MIR ref_deref.main.ConstProp.diff + +fn main() { + *(&4); +} diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff new file mode 100644 index 000000000..f0c89caea --- /dev/null +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff @@ -0,0 +1,26 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/ref_deref_project.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17 + let mut _2: &i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + let _3: (i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14 + let mut _4: &(i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17 + StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + // mir::Constant + // + span: $DIR/ref_deref_project.rs:5:6: 5:17 + // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) } + _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18 + StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18 + nop; // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2 + return; // scope 0 at $DIR/ref_deref_project.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff new file mode 100644 index 000000000..d25540287 --- /dev/null +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff @@ -0,0 +1,30 @@ +- // MIR for `main` before PromoteTemps ++ // MIR for `main` after PromoteTemps + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/ref_deref_project.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17 + let mut _2: &i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + let _3: (i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14 ++ let mut _4: &(i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17 + StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 +- StorageLive(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14 +- _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14 +- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 ++ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 ++ // mir::Constant ++ // + span: $DIR/ref_deref_project.rs:5:6: 5:17 ++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) } ++ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17 +- StorageDead(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18 + StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18 + StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18 + _0 = const (); // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2 + return; // scope 0 at $DIR/ref_deref_project.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs new file mode 100644 index 000000000..c7cc73651 --- /dev/null +++ b/src/test/mir-opt/const_prop/ref_deref_project.rs @@ -0,0 +1,6 @@ +// EMIT_MIR ref_deref_project.main.PromoteTemps.diff +// EMIT_MIR ref_deref_project.main.ConstProp.diff + +fn main() { + *(&(4, 5).1); // This does not currently propagate (#67862) +} diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff new file mode 100644 index 000000000..237a6f94a --- /dev/null +++ b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff @@ -0,0 +1,29 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +0:11 + let mut _1: *const fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 + let mut _2: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + let mut _3: fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 + StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + StorageLive(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + _3 = main as fn() (Pointer(ReifyFnPointer)); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + // mir::Constant + // + span: $DIR/reify_fn_ptr.rs:4:13: 4:17 + // + literal: Const { ty: fn() {main}, val: Value(<ZST>) } + _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + StorageDead(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26 + _1 = move _2 as *const fn() (PointerFromExposedAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 + StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41 + StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:41: +1:42 + nop; // scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +2:2 + return; // scope 0 at $DIR/reify_fn_ptr.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.rs b/src/test/mir-opt/const_prop/reify_fn_ptr.rs new file mode 100644 index 000000000..bfe2563ad --- /dev/null +++ b/src/test/mir-opt/const_prop/reify_fn_ptr.rs @@ -0,0 +1,5 @@ +// EMIT_MIR reify_fn_ptr.main.ConstProp.diff + +fn main() { + let _ = main as usize as *const fn(); +} diff --git a/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff new file mode 100644 index 000000000..7c4977996 --- /dev/null +++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff @@ -0,0 +1,43 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/repeat.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/repeat.rs:+1:9: +1:10 + let mut _2: u32; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + let mut _3: [u32; 8]; // in scope 0 at $DIR/repeat.rs:+1:18: +1:25 + let _4: usize; // in scope 0 at $DIR/repeat.rs:+1:26: +1:27 + let mut _5: usize; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + let mut _6: bool; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + scope 1 { + debug x => _1; // in scope 1 at $DIR/repeat.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/repeat.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + StorageLive(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:25 + _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25 + StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27 + _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27 + _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + } + + bb1: { +- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:+1:18: +1:32 ++ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:32 + StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32 + StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + nop; // scope 0 at $DIR/repeat.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2 + return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff new file mode 100644 index 000000000..7c4977996 --- /dev/null +++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff @@ -0,0 +1,43 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/repeat.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/repeat.rs:+1:9: +1:10 + let mut _2: u32; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + let mut _3: [u32; 8]; // in scope 0 at $DIR/repeat.rs:+1:18: +1:25 + let _4: usize; // in scope 0 at $DIR/repeat.rs:+1:26: +1:27 + let mut _5: usize; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + let mut _6: bool; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28 + scope 1 { + debug x => _1; // in scope 1 at $DIR/repeat.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/repeat.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + StorageLive(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:25 + _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25 + StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27 + _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27 + _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 + } + + bb1: { +- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 +- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:+1:18: +1:32 ++ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:28 ++ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:32 + StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32 + StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 + nop; // scope 0 at $DIR/repeat.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2 + return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/repeat.rs b/src/test/mir-opt/const_prop/repeat.rs new file mode 100644 index 000000000..36d9b9fc6 --- /dev/null +++ b/src/test/mir-opt/const_prop/repeat.rs @@ -0,0 +1,7 @@ +// compile-flags: -O + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR repeat.main.ConstProp.diff +fn main() { + let x: u32 = [42; 8][2] + 0; +} diff --git a/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff new file mode 100644 index 000000000..5ebd8a520 --- /dev/null +++ b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff @@ -0,0 +1,21 @@ +- // MIR for `add` before ConstProp ++ // MIR for `add` after ConstProp + + fn add() -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16 + let mut _1: (u32, bool); // in scope 0 at $DIR/return_place.rs:+1:5: +1:10 + + bb0: { +- _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:+1:5: +1:10 +- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 ++ _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:+1:5: +1:10 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + } + + bb1: { +- _0 = move (_1.0: u32); // scope 0 at $DIR/return_place.rs:+1:5: +1:10 ++ _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir b/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir new file mode 100644 index 000000000..ececd9942 --- /dev/null +++ b/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir @@ -0,0 +1,10 @@ +// MIR for `add` before PreCodegen + +fn add() -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16 + + bb0: { + _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10 + return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/const_prop/return_place.rs b/src/test/mir-opt/const_prop/return_place.rs new file mode 100644 index 000000000..06a853696 --- /dev/null +++ b/src/test/mir-opt/const_prop/return_place.rs @@ -0,0 +1,11 @@ +// compile-flags: -C overflow-checks=on + +// EMIT_MIR return_place.add.ConstProp.diff +// EMIT_MIR return_place.add.PreCodegen.before.mir +fn add() -> u32 { + 2 + 2 +} + +fn main() { + add(); +} diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff new file mode 100644 index 000000000..5920937e0 --- /dev/null +++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff @@ -0,0 +1,35 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10 + let _2: (); // in scope 0 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 + let mut _3: u32; // in scope 0 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10 + _1 = const 1_u32; // scope 0 at $DIR/scalar_literal_propagation.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 + StorageLive(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 +- _3 = _1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 +- _2 = consume(move _3) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 ++ _3 = const 1_u32; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14 ++ _2 = consume(const 1_u32) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15 + // mir::Constant + // + span: $DIR/scalar_literal_propagation.rs:4:5: 4:12 + // + literal: Const { ty: fn(u32) {consume}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:14: +2:15 + StorageDead(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:15: +2:16 + nop; // scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +3:2 + StorageDead(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+3:1: +3:2 + return; // scope 0 at $DIR/scalar_literal_propagation.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation.rs b/src/test/mir-opt/const_prop/scalar_literal_propagation.rs new file mode 100644 index 000000000..8724e4d57 --- /dev/null +++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.rs @@ -0,0 +1,8 @@ +// EMIT_MIR scalar_literal_propagation.main.ConstProp.diff +fn main() { + let x = 1; + consume(x); +} + +#[inline(never)] +fn consume(_: u32) { } diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff new file mode 100644 index 000000000..0ebfbca21 --- /dev/null +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff @@ -0,0 +1,53 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/slice_len.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _2: &[u32]; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:30 + let mut _3: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let _4: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let _5: [u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:7: +1:19 + let _6: usize; // in scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30 + StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + // mir::Constant + // + span: $DIR/slice_len.rs:5:6: 5:19 + // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } + _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageLive(_10); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _10 = _3; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19 + StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageDead(_10); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + } + + bb1: { +- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageDead(_6); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_4); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_2); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_1); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + nop; // scope 0 at $DIR/slice_len.rs:+0:11: +2:2 + return; // scope 0 at $DIR/slice_len.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff new file mode 100644 index 000000000..0ebfbca21 --- /dev/null +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff @@ -0,0 +1,53 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/slice_len.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _2: &[u32]; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:30 + let mut _3: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let _4: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let _5: [u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:7: +1:19 + let _6: usize; // in scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30 + StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + // mir::Constant + // + span: $DIR/slice_len.rs:5:6: 5:19 + // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } + _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageLive(_10); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _10 = _3; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19 + StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32 + _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageDead(_10); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + } + + bb1: { +- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 ++ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33 + StorageDead(_6); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_4); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_2); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + StorageDead(_1); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34 + nop; // scope 0 at $DIR/slice_len.rs:+0:11: +2:2 + return; // scope 0 at $DIR/slice_len.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/const_prop/slice_len.rs b/src/test/mir-opt/const_prop/slice_len.rs new file mode 100644 index 000000000..fa9eafa8b --- /dev/null +++ b/src/test/mir-opt/const_prop/slice_len.rs @@ -0,0 +1,6 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +// EMIT_MIR slice_len.main.ConstProp.diff +fn main() { + (&[1u32, 2, 3] as &[u32])[1]; +} diff --git a/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff new file mode 100644 index 000000000..9d7c2784d --- /dev/null +++ b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff @@ -0,0 +1,34 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/switch_int.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/switch_int.rs:+1:11: +1:12 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 + _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 +- switchInt(_1) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 ++ switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 + } + + bb1: { + _0 = foo(const -1_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21 + // mir::Constant + // + span: $DIR/switch_int.rs:9:14: 9:17 + // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } + } + + bb2: { + _0 = foo(const 0_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20 + // mir::Constant + // + span: $DIR/switch_int.rs:8:14: 8:17 + // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_1); // scope 0 at $DIR/switch_int.rs:+5:1: +5:2 + return; // scope 0 at $DIR/switch_int.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff b/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff new file mode 100644 index 000000000..74f9eafe4 --- /dev/null +++ b/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff @@ -0,0 +1,34 @@ +- // MIR for `main` before SimplifyConstCondition-after-const-prop ++ // MIR for `main` after SimplifyConstCondition-after-const-prop + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/switch_int.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/switch_int.rs:+1:11: +1:12 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 + _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 +- switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 ++ goto -> bb2; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 + } + + bb1: { + _0 = foo(const -1_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21 + // mir::Constant + // + span: $DIR/switch_int.rs:9:14: 9:17 + // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } + } + + bb2: { + _0 = foo(const 0_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20 + // mir::Constant + // + span: $DIR/switch_int.rs:8:14: 8:17 + // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_1); // scope 0 at $DIR/switch_int.rs:+5:1: +5:2 + return; // scope 0 at $DIR/switch_int.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/const_prop/switch_int.rs b/src/test/mir-opt/const_prop/switch_int.rs new file mode 100644 index 000000000..d7319eca1 --- /dev/null +++ b/src/test/mir-opt/const_prop/switch_int.rs @@ -0,0 +1,11 @@ +#[inline(never)] +fn foo(_: i32) { } + +// EMIT_MIR switch_int.main.ConstProp.diff +// EMIT_MIR switch_int.main.SimplifyConstCondition-after-const-prop.diff +fn main() { + match 1 { + 1 => foo(0), + _ => foo(-1), + } +} diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff new file mode 100644 index 000000000..a0603c60d --- /dev/null +++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff @@ -0,0 +1,36 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +0:11 + let _1: (u32, u32); // in scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10 + let _2: (); // in scope 0 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 + let mut _3: (u32, u32); // in scope 0 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10 + Deinit(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19 + (_1.0: u32) = const 1_u32; // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19 + (_1.1: u32) = const 2_u32; // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19 + StorageLive(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 + StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 +- _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 ++ _3 = const (1_u32, 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14 + _2 = consume(move _3) -> bb1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15 + // mir::Constant + // + span: $DIR/tuple_literal_propagation.rs:5:5: 5:12 + // + literal: Const { ty: fn((u32, u32)) {consume}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:14: +3:15 + StorageDead(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:15: +3:16 + nop; // scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+4:1: +4:2 + return; // scope 0 at $DIR/tuple_literal_propagation.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.rs b/src/test/mir-opt/const_prop/tuple_literal_propagation.rs new file mode 100644 index 000000000..e644baec4 --- /dev/null +++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.rs @@ -0,0 +1,9 @@ +// EMIT_MIR tuple_literal_propagation.main.ConstProp.diff +fn main() { + let x = (1, 2); + + consume(x); +} + +#[inline(never)] +fn consume(_: (u32, u32)) { } diff --git a/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff new file mode 100644 index 000000000..459da2e33 --- /dev/null +++ b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff @@ -0,0 +1,42 @@ +- // MIR for `bar` before ConstProp ++ // MIR for `bar` after ConstProp + + fn bar() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +0:10 + let mut _1: (i32,); // in scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 + let _2: (); // in scope 0 at $DIR/const_prop_miscompile.rs:+2:5: +4:6 + let mut _3: *mut i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + let mut _5: i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+5:13: +5:20 + scope 1 { + debug v => _1; // in scope 1 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 + let _4: bool; // in scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 + scope 2 { + } + scope 3 { + debug y => _4; // in scope 3 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 + Deinit(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 + (_1.0: i32) = const 1_i32; // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 + StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +4:6 + StorageLive(_3); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + _3 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + (*_3) = const 5_i32; // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26 + StorageDead(_3); // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27 + nop; // scope 2 at $DIR/const_prop_miscompile.rs:+2:5: +4:6 + StorageDead(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+4:5: +4:6 + StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 + StorageLive(_5); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20 + _5 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18 + _4 = Eq(move _5, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25 + StorageDead(_5); // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25 + nop; // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +6:2 + StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+6:1: +6:2 + return; // scope 0 at $DIR/const_prop_miscompile.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff new file mode 100644 index 000000000..e8bd98cf8 --- /dev/null +++ b/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff @@ -0,0 +1,36 @@ +- // MIR for `foo` before ConstProp ++ // MIR for `foo` after ConstProp + + fn foo() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +0:10 + let mut _1: (i32,); // in scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 + let mut _2: &mut i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+2:6: +2:14 + let mut _4: i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+3:13: +3:20 + scope 1 { + debug u => _1; // in scope 1 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 + let _3: bool; // in scope 1 at $DIR/const_prop_miscompile.rs:+3:9: +3:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 + Deinit(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 + (_1.0: i32) = const 1_i32; // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 + StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14 + _2 = &mut (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14 + (*_2) = const 5_i32; // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +2:18 + StorageDead(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:18: +2:19 + StorageLive(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+3:9: +3:10 + StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+3:13: +3:20 + _4 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+3:15: +3:18 + _3 = Eq(move _4, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+3:13: +3:25 + StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+3:24: +3:25 + nop; // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +4:2 + StorageDead(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+4:1: +4:2 + return; // scope 0 at $DIR/const_prop_miscompile.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/const_prop_miscompile.rs b/src/test/mir-opt/const_prop_miscompile.rs new file mode 100644 index 000000000..bc54556b3 --- /dev/null +++ b/src/test/mir-opt/const_prop_miscompile.rs @@ -0,0 +1,22 @@ +#![feature(raw_ref_op)] + +// EMIT_MIR const_prop_miscompile.foo.ConstProp.diff +fn foo() { + let mut u = (1,); + *&mut u.0 = 5; + let y = { u.0 } == 5; +} + +// EMIT_MIR const_prop_miscompile.bar.ConstProp.diff +fn bar() { + let mut v = (1,); + unsafe { + *&raw mut v.0 = 5; + } + let y = { v.0 } == 5; +} + +fn main() { + foo(); + bar(); +} diff --git a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot new file mode 100644 index 000000000..c00eae96e --- /dev/null +++ b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot @@ -0,0 +1,6 @@ +digraph Cov_0_4 { + graph [fontname="Courier, monospace"]; + node [fontname="Courier, monospace"]; + edge [fontname="Courier, monospace"]; + bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br/> 19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2<br/> 20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>]; +} diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot new file mode 100644 index 000000000..ca0eb7e84 --- /dev/null +++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot @@ -0,0 +1,13 @@ +digraph Cov_0_3 { + graph [fontname="Courier, monospace"]; + node [fontname="Courier, monospace"]; + edge [fontname="Courier, monospace"]; + bcb3__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb3</td></tr><tr><td align="left" balign="left">Counter(bcb3) at 13:10-13:10<br/> 13:10-13:10: @5[0]: Coverage::Counter(2) for $DIR/coverage_graphviz.rs:13:10 - 13:11</td></tr><tr><td align="left" balign="left">bb5: Goto</td></tr></table>>]; + bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb1:(bcb0 + bcb3) - bcb3) at 12:13-12:18<br/> 12:13-12:18: @4[0]: Coverage::Expression(4294967293) = 4294967294 + 0 for $DIR/coverage_graphviz.rs:15:1 - 15:2<br/>Expression(bcb2:(bcb1:(bcb0 + bcb3) - bcb3) + 0) at 15:2-15:2<br/> 15:2-15:2: @4.Return: return</td></tr><tr><td align="left" balign="left">bb4: Return</td></tr></table>>]; + bcb1__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb1</td></tr><tr><td align="left" balign="left">Expression(bcb0 + bcb3) at 10:5-11:17<br/> 11:12-11:17: @2.Call: _2 = bar() -> [return: bb3, unwind: bb6]</td></tr><tr><td align="left" balign="left">bb1: FalseUnwind<br/>bb2: Call</td></tr><tr><td align="left" balign="left">bb3: SwitchInt</td></tr></table>>]; + bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 9:1-9:11<br/> </td></tr><tr><td align="left" balign="left">bb0: Goto</td></tr></table>>]; + bcb3__Cov_0_3 -> bcb1__Cov_0_3 [label=<>]; + bcb1__Cov_0_3 -> bcb3__Cov_0_3 [label=<false>]; + bcb1__Cov_0_3 -> bcb2__Cov_0_3 [label=<otherwise>]; + bcb0__Cov_0_3 -> bcb1__Cov_0_3 [label=<>]; +} diff --git a/src/test/mir-opt/coverage_graphviz.rs b/src/test/mir-opt/coverage_graphviz.rs new file mode 100644 index 000000000..09403bb3a --- /dev/null +++ b/src/test/mir-opt/coverage_graphviz.rs @@ -0,0 +1,20 @@ +// Test that `-C instrument-coverage` with `-Z dump-mir-graphviz` generates a graphviz (.dot file) +// rendering of the `BasicCoverageBlock` coverage control flow graph, with counters and +// expressions. + +// needs-profiler-support +// compile-flags: -C instrument-coverage -Z dump-mir-graphviz +// EMIT_MIR coverage_graphviz.main.InstrumentCoverage.0.dot +// EMIT_MIR coverage_graphviz.bar.InstrumentCoverage.0.dot +fn main() { + loop { + if bar() { + break; + } + } +} + +#[inline(never)] +fn bar() -> bool { + true +} diff --git a/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff new file mode 100644 index 000000000..58dd788b6 --- /dev/null +++ b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff @@ -0,0 +1,75 @@ +- // MIR for `cycle` before DeadStoreElimination ++ // MIR for `cycle` after DeadStoreElimination + + fn cycle(_1: i32, _2: i32, _3: i32) -> () { + debug x => _1; // in scope 0 at $DIR/cycle.rs:+0:10: +0:15 + debug y => _2; // in scope 0 at $DIR/cycle.rs:+0:22: +0:27 + debug z => _3; // in scope 0 at $DIR/cycle.rs:+0:34: +0:39 + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:46: +0:46 + let mut _4: (); // in scope 0 at $DIR/cycle.rs:+0:1: +9:2 + let mut _5: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17 + let _6: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17 + let mut _7: i32; // in scope 0 at $DIR/cycle.rs:+5:13: +5:14 + let mut _8: i32; // in scope 0 at $DIR/cycle.rs:+6:13: +6:14 + let mut _9: i32; // in scope 0 at $DIR/cycle.rs:+7:13: +7:17 + let mut _10: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6 + let _11: (); // in scope 0 at $DIR/cycle.rs:+3:5: +8:6 + let mut _12: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6 + scope 1 { + debug temp => _6; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17 + } + + bb0: { + goto -> bb1; // scope 0 at $DIR/cycle.rs:+3:5: +8:6 + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/cycle.rs:+3:11: +3:17 + _5 = cond() -> bb2; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 + // mir::Constant + // + span: $DIR/cycle.rs:12:11: 12:15 + // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) } + } + + bb2: { + switchInt(move _5) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 + } + + bb3: { + StorageLive(_6); // scope 0 at $DIR/cycle.rs:+4:13: +4:17 +- _6 = _3; // scope 0 at $DIR/cycle.rs:+4:20: +4:21 ++ nop; // scope 0 at $DIR/cycle.rs:+4:20: +4:21 + StorageLive(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14 +- _7 = _2; // scope 1 at $DIR/cycle.rs:+5:13: +5:14 +- _3 = move _7; // scope 1 at $DIR/cycle.rs:+5:9: +5:14 ++ nop; // scope 1 at $DIR/cycle.rs:+5:13: +5:14 ++ nop; // scope 1 at $DIR/cycle.rs:+5:9: +5:14 + StorageDead(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14 + StorageLive(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14 +- _8 = _1; // scope 1 at $DIR/cycle.rs:+6:13: +6:14 +- _2 = move _8; // scope 1 at $DIR/cycle.rs:+6:9: +6:14 ++ nop; // scope 1 at $DIR/cycle.rs:+6:13: +6:14 ++ nop; // scope 1 at $DIR/cycle.rs:+6:9: +6:14 + StorageDead(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14 + StorageLive(_9); // scope 1 at $DIR/cycle.rs:+7:13: +7:17 +- _9 = _6; // scope 1 at $DIR/cycle.rs:+7:13: +7:17 +- _1 = move _9; // scope 1 at $DIR/cycle.rs:+7:9: +7:17 ++ nop; // scope 1 at $DIR/cycle.rs:+7:13: +7:17 ++ nop; // scope 1 at $DIR/cycle.rs:+7:9: +7:17 + StorageDead(_9); // scope 1 at $DIR/cycle.rs:+7:16: +7:17 +- _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6 ++ nop; // scope 0 at $DIR/cycle.rs:+3:18: +8:6 + StorageDead(_6); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + goto -> bb1; // scope 0 at $DIR/cycle.rs:+3:5: +8:6 + } + + bb4: { + StorageLive(_11); // scope 0 at $DIR/cycle.rs:+3:5: +8:6 + _0 = const (); // scope 0 at $DIR/cycle.rs:+3:5: +8:6 + StorageDead(_11); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + return; // scope 0 at $DIR/cycle.rs:+9:2: +9:2 + } + } + diff --git a/src/test/mir-opt/dead-store-elimination/cycle.rs b/src/test/mir-opt/dead-store-elimination/cycle.rs new file mode 100644 index 000000000..b35ce0bcb --- /dev/null +++ b/src/test/mir-opt/dead-store-elimination/cycle.rs @@ -0,0 +1,22 @@ +// unit-test: DeadStoreElimination + +#[inline(never)] +fn cond() -> bool { + false +} + +// EMIT_MIR cycle.cycle.DeadStoreElimination.diff +fn cycle(mut x: i32, mut y: i32, mut z: i32) { + // This example is interesting because the non-transitive version of `MaybeLiveLocals` would + // report that *all* of these stores are live. + while cond() { + let temp = z; + z = y; + y = x; + x = temp; + } +} + +fn main() { + cycle(1, 2, 3); +} diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff new file mode 100644 index 000000000..89f1846b4 --- /dev/null +++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff @@ -0,0 +1,35 @@ +- // MIR for `pointer_to_int` before DeadStoreElimination ++ // MIR for `pointer_to_int` after DeadStoreElimination + + fn pointer_to_int(_1: *mut i32) -> () { + debug p => _1; // in scope 0 at $DIR/provenance_soundness.rs:+0:19: +0:20 + let mut _0: (); // return place in scope 0 at $DIR/provenance_soundness.rs:+0:32: +0:32 + let _2: usize; // in scope 0 at $DIR/provenance_soundness.rs:+1:9: +1:11 + let mut _3: *mut i32; // in scope 0 at $DIR/provenance_soundness.rs:+1:14: +1:15 + let mut _5: *mut i32; // in scope 0 at $DIR/provenance_soundness.rs:+2:14: +2:15 + scope 1 { + debug _x => _2; // in scope 1 at $DIR/provenance_soundness.rs:+1:9: +1:11 + let _4: isize; // in scope 1 at $DIR/provenance_soundness.rs:+2:9: +2:11 + scope 2 { + debug _y => _4; // in scope 2 at $DIR/provenance_soundness.rs:+2:9: +2:11 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/provenance_soundness.rs:+1:9: +1:11 + StorageLive(_3); // scope 0 at $DIR/provenance_soundness.rs:+1:14: +1:15 + _3 = _1; // scope 0 at $DIR/provenance_soundness.rs:+1:14: +1:15 + _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/provenance_soundness.rs:+1:14: +1:24 + StorageDead(_3); // scope 0 at $DIR/provenance_soundness.rs:+1:23: +1:24 + StorageLive(_4); // scope 1 at $DIR/provenance_soundness.rs:+2:9: +2:11 + StorageLive(_5); // scope 1 at $DIR/provenance_soundness.rs:+2:14: +2:15 + _5 = _1; // scope 1 at $DIR/provenance_soundness.rs:+2:14: +2:15 + _4 = move _5 as isize (PointerExposeAddress); // scope 1 at $DIR/provenance_soundness.rs:+2:14: +2:24 + StorageDead(_5); // scope 1 at $DIR/provenance_soundness.rs:+2:23: +2:24 + _0 = const (); // scope 0 at $DIR/provenance_soundness.rs:+0:32: +3:2 + StorageDead(_4); // scope 1 at $DIR/provenance_soundness.rs:+3:1: +3:2 + StorageDead(_2); // scope 0 at $DIR/provenance_soundness.rs:+3:1: +3:2 + return; // scope 0 at $DIR/provenance_soundness.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff new file mode 100644 index 000000000..300f0d5dc --- /dev/null +++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff @@ -0,0 +1,14 @@ +- // MIR for `retags` before DeadStoreElimination ++ // MIR for `retags` after DeadStoreElimination + + fn retags(_1: &mut i32) -> () { + debug _r => _1; // in scope 0 at $DIR/provenance_soundness.rs:+0:11: +0:13 + let mut _0: (); // return place in scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:25 + + bb0: { + Retag([fn entry] _1); // scope 0 at $DIR/provenance_soundness.rs:+0:1: +0:27 + _0 = const (); // scope 0 at $DIR/provenance_soundness.rs:+0:25: +0:27 + return; // scope 0 at $DIR/provenance_soundness.rs:+0:27: +0:27 + } + } + diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.rs b/src/test/mir-opt/dead-store-elimination/provenance_soundness.rs new file mode 100644 index 000000000..11314e990 --- /dev/null +++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.rs @@ -0,0 +1,18 @@ +// unit-test: DeadStoreElimination +// compile-flags: -Zmir-emit-retag + +// Test that we don't remove pointer to int casts or retags + +// EMIT_MIR provenance_soundness.pointer_to_int.DeadStoreElimination.diff +fn pointer_to_int(p: *mut i32) { + let _x = p as usize; + let _y = p as isize; +} + +// EMIT_MIR provenance_soundness.retags.DeadStoreElimination.diff +fn retags(_r: &mut i32) {} + +fn main() { + pointer_to_int(&mut 5 as *mut _); + retags(&mut 5); +} diff --git a/src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff b/src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff new file mode 100644 index 000000000..db136485a --- /dev/null +++ b/src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff @@ -0,0 +1,21 @@ +- // MIR for `bar` before Deaggregator ++ // MIR for `bar` after Deaggregator + + fn bar(_1: usize) -> Baz { + debug a => _1; // in scope 0 at $DIR/deaggregator_test.rs:+0:8: +0:9 + let mut _0: Baz; // return place in scope 0 at $DIR/deaggregator_test.rs:+0:21: +0:24 + let mut _2: usize; // in scope 0 at $DIR/deaggregator_test.rs:+1:14: +1:15 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/deaggregator_test.rs:+1:14: +1:15 + _2 = _1; // scope 0 at $DIR/deaggregator_test.rs:+1:14: +1:15 +- _0 = Baz { x: move _2, y: const 0f32, z: const false }; // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35 ++ Deinit(_0); // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35 ++ (_0.0: usize) = move _2; // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35 ++ (_0.1: f32) = const 0f32; // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35 ++ (_0.2: bool) = const false; // scope 0 at $DIR/deaggregator_test.rs:+1:5: +1:35 + StorageDead(_2); // scope 0 at $DIR/deaggregator_test.rs:+1:34: +1:35 + return; // scope 0 at $DIR/deaggregator_test.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/deaggregator_test.rs b/src/test/mir-opt/deaggregator_test.rs new file mode 100644 index 000000000..342e22243 --- /dev/null +++ b/src/test/mir-opt/deaggregator_test.rs @@ -0,0 +1,15 @@ +struct Baz { + x: usize, + y: f32, + z: bool, +} + +// EMIT_MIR deaggregator_test.bar.Deaggregator.diff +fn bar(a: usize) -> Baz { + Baz { x: a, y: 0.0, z: false } +} + +fn main() { + // Make sure the function actually gets instantiated. + bar(0); +} diff --git a/src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff new file mode 100644 index 000000000..f28c2b482 --- /dev/null +++ b/src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff @@ -0,0 +1,20 @@ +- // MIR for `bar` before Deaggregator ++ // MIR for `bar` after Deaggregator + + fn bar(_1: usize) -> Baz { + debug a => _1; // in scope 0 at $DIR/deaggregator_test_enum.rs:+0:8: +0:9 + let mut _0: Baz; // return place in scope 0 at $DIR/deaggregator_test_enum.rs:+0:21: +0:24 + let mut _2: usize; // in scope 0 at $DIR/deaggregator_test_enum.rs:+1:19: +1:20 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/deaggregator_test_enum.rs:+1:19: +1:20 + _2 = _1; // scope 0 at $DIR/deaggregator_test_enum.rs:+1:19: +1:20 +- _0 = Baz::Foo { x: move _2 }; // scope 0 at $DIR/deaggregator_test_enum.rs:+1:5: +1:22 ++ Deinit(_0); // scope 0 at $DIR/deaggregator_test_enum.rs:+1:5: +1:22 ++ ((_0 as Foo).0: usize) = move _2; // scope 0 at $DIR/deaggregator_test_enum.rs:+1:5: +1:22 ++ discriminant(_0) = 1; // scope 0 at $DIR/deaggregator_test_enum.rs:+1:5: +1:22 + StorageDead(_2); // scope 0 at $DIR/deaggregator_test_enum.rs:+1:21: +1:22 + return; // scope 0 at $DIR/deaggregator_test_enum.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/deaggregator_test_enum.rs b/src/test/mir-opt/deaggregator_test_enum.rs new file mode 100644 index 000000000..02b63a1f5 --- /dev/null +++ b/src/test/mir-opt/deaggregator_test_enum.rs @@ -0,0 +1,17 @@ +enum Baz { + Empty, + Foo { x: usize }, +} + +// EMIT_MIR deaggregator_test_enum.bar.Deaggregator.diff +fn bar(a: usize) -> Baz { + Baz::Foo { x: a } +} + +fn main() { + let x = bar(10); + match x { + Baz::Empty => println!("empty"), + Baz::Foo { x } => println!("{}", x), + }; +} diff --git a/src/test/mir-opt/deaggregator_test_enum_2.rs b/src/test/mir-opt/deaggregator_test_enum_2.rs new file mode 100644 index 000000000..489854ff0 --- /dev/null +++ b/src/test/mir-opt/deaggregator_test_enum_2.rs @@ -0,0 +1,20 @@ +// Test that deaggregate fires in more than one basic block + +enum Foo { + A(i32), + B(i32), +} + +// EMIT_MIR deaggregator_test_enum_2.test1.Deaggregator.diff +fn test1(x: bool, y: i32) -> Foo { + if x { + Foo::A(y) + } else { + Foo::B(y) + } +} + +fn main() { + // Make sure the function actually gets instantiated. + test1(false, 0); +} diff --git a/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff new file mode 100644 index 000000000..fb18089e0 --- /dev/null +++ b/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff @@ -0,0 +1,45 @@ +- // MIR for `test1` before Deaggregator ++ // MIR for `test1` after Deaggregator + + fn test1(_1: bool, _2: i32) -> Foo { + debug x => _1; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+0:10: +0:11 + debug y => _2; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+0:19: +0:20 + let mut _0: Foo; // return place in scope 0 at $DIR/deaggregator_test_enum_2.rs:+0:30: +0:33 + let mut _3: bool; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9 + let mut _4: i32; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:16: +2:17 + let mut _5: i32; // in scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:16: +4:17 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9 + switchInt(move _3) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9 + } + + bb1: { + StorageLive(_4); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:16: +2:17 + _4 = _2; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:16: +2:17 +- _0 = Foo::A(move _4); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:9: +2:18 ++ Deinit(_0); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:9: +2:18 ++ ((_0 as A).0: i32) = move _4; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:9: +2:18 ++ discriminant(_0) = 0; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:9: +2:18 + StorageDead(_4); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+2:17: +2:18 + goto -> bb3; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:5: +5:6 + } + + bb2: { + StorageLive(_5); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:16: +4:17 + _5 = _2; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:16: +4:17 +- _0 = Foo::B(move _5); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:9: +4:18 ++ Deinit(_0); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:9: +4:18 ++ ((_0 as B).0: i32) = move _5; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:9: +4:18 ++ discriminant(_0) = 1; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:9: +4:18 + StorageDead(_5); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+4:17: +4:18 + goto -> bb3; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:5: +5:6 + } + + bb3: { + StorageDead(_3); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+5:5: +5:6 + return; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/deaggregator_test_multiple.rs b/src/test/mir-opt/deaggregator_test_multiple.rs new file mode 100644 index 000000000..9730b9aa8 --- /dev/null +++ b/src/test/mir-opt/deaggregator_test_multiple.rs @@ -0,0 +1,16 @@ +// Test that deaggregate fires more than once per block + +enum Foo { + A(i32), + B, +} + +// EMIT_MIR deaggregator_test_multiple.test.Deaggregator.diff +fn test(x: i32) -> [Foo; 2] { + [Foo::A(x), Foo::A(x)] +} + +fn main() { + // Make sure the function actually gets instantiated. + test(0); +} diff --git a/src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff new file mode 100644 index 000000000..cf5da273c --- /dev/null +++ b/src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff @@ -0,0 +1,35 @@ +- // MIR for `test` before Deaggregator ++ // MIR for `test` after Deaggregator + + fn test(_1: i32) -> [Foo; 2] { + debug x => _1; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+0:9: +0:10 + let mut _0: [Foo; 2]; // return place in scope 0 at $DIR/deaggregator_test_multiple.rs:+0:20: +0:28 + let mut _2: Foo; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15 + let mut _3: i32; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+1:13: +1:14 + let mut _4: Foo; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26 + let mut _5: i32; // in scope 0 at $DIR/deaggregator_test_multiple.rs:+1:24: +1:25 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15 + StorageLive(_3); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:13: +1:14 + _3 = _1; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:13: +1:14 +- _2 = Foo::A(move _3); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15 ++ Deinit(_2); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15 ++ ((_2 as A).0: i32) = move _3; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15 ++ discriminant(_2) = 0; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:6: +1:15 + StorageDead(_3); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:14: +1:15 + StorageLive(_4); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26 + StorageLive(_5); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:24: +1:25 + _5 = _1; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:24: +1:25 +- _4 = Foo::A(move _5); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26 ++ Deinit(_4); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26 ++ ((_4 as A).0: i32) = move _5; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26 ++ discriminant(_4) = 0; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:17: +1:26 + StorageDead(_5); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:25: +1:26 + _0 = [move _2, move _4]; // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:5: +1:27 + StorageDead(_4); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:26: +1:27 + StorageDead(_2); // scope 0 at $DIR/deaggregator_test_multiple.rs:+1:26: +1:27 + return; // scope 0 at $DIR/deaggregator_test_multiple.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff new file mode 100644 index 000000000..01864ba24 --- /dev/null +++ b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff @@ -0,0 +1,107 @@ +- // MIR for `is_line_doc_comment_2` before DeduplicateBlocks ++ // MIR for `is_line_doc_comment_2` after DeduplicateBlocks + + fn is_line_doc_comment_2(_1: &str) -> bool { + debug s => _1; // in scope 0 at $DIR/deduplicate_blocks.rs:+0:36: +0:37 + let mut _0: bool; // return place in scope 0 at $DIR/deduplicate_blocks.rs:+0:48: +0:52 + let mut _2: &[u8]; // in scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + let mut _3: &str; // in scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + let mut _4: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + let mut _5: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + let mut _6: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + let mut _7: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + scope 1 (inlined core::str::<impl str>::as_bytes) { // at $DIR/deduplicate_blocks.rs:3:11: 3:23 + debug self => _3; // in scope 1 at $SRC_DIR/core/src/str/mod.rs:LL:COL + let mut _8: &str; // in scope 1 at $SRC_DIR/core/src/str/mod.rs:LL:COL + scope 2 { + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + StorageLive(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + _3 = _1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + StorageLive(_8); // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL + _8 = _3; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL +- _2 = transmute::<&str, &[u8]>(move _8) -> bb14; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL ++ _2 = transmute::<&str, &[u8]>(move _8) -> bb12; // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/str/mod.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&str) -> &[u8] {transmute::<&str, &[u8]>}, val: Value(<ZST>) } + } + + bb1: { + switchInt((*_2)[0 of 4]) -> [47_u8: bb2, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb2: { + switchInt((*_2)[1 of 4]) -> [47_u8: bb3, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb3: { + switchInt((*_2)[2 of 4]) -> [47_u8: bb4, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb4: { +- switchInt((*_2)[3 of 4]) -> [47_u8: bb10, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 ++ switchInt((*_2)[3 of 4]) -> [47_u8: bb9, otherwise: bb5]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb5: { + _4 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + _5 = Ge(move _4, const 3_usize); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + switchInt(move _5) -> [false: bb9, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + } + + bb6: { + switchInt((*_2)[0 of 3]) -> [47_u8: bb7, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb7: { + switchInt((*_2)[1 of 3]) -> [47_u8: bb8, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb8: { +- switchInt((*_2)[2 of 3]) -> [47_u8: bb11, 33_u8: bb12, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 ++ switchInt((*_2)[2 of 3]) -> [47_u8: bb10, 33_u8: bb10, otherwise: bb9]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb9: { +- _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19 +- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19 +- } +- +- bb10: { + _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 +- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 ++ goto -> bb11; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 + } + +- bb11: { +- _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39 +- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39 +- } +- +- bb12: { ++ bb10: { + _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 +- goto -> bb13; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 ++ goto -> bb11; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 + } + +- bb13: { ++ bb11: { + StorageDead(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+7:1: +7:2 + return; // scope 0 at $DIR/deduplicate_blocks.rs:+7:2: +7:2 + } + +- bb14: { ++ bb12: { + StorageDead(_8); // scope 2 at $SRC_DIR/core/src/str/mod.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:22: +1:23 + _6 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + _7 = Ge(move _6, const 4_usize); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + switchInt(move _7) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + } + } + diff --git a/src/test/mir-opt/deduplicate_blocks.rs b/src/test/mir-opt/deduplicate_blocks.rs new file mode 100644 index 000000000..f8f7361dc --- /dev/null +++ b/src/test/mir-opt/deduplicate_blocks.rs @@ -0,0 +1,13 @@ +// EMIT_MIR deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff +pub const fn is_line_doc_comment_2(s: &str) -> bool { + match s.as_bytes() { + [b'/', b'/', b'/', b'/', ..] => false, + [b'/', b'/', b'/', ..] => true, + [b'/', b'/', b'!', ..] => true, + _ => false, + } +} + +fn main() { + is_line_doc_comment_2("asd"); +} diff --git a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff new file mode 100644 index 000000000..de0c03bb7 --- /dev/null +++ b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff @@ -0,0 +1,107 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_complex_case.rs:+0:11: +0:11 + let mut _1: std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _2: &[i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let _3: [i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:18: +1:26 + let mut _4: std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _5: (); // in scope 0 at $DIR/derefer_complex_case.rs:+0:1: +2:2 + let _6: (); // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _7: std::option::Option<&i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _8: &mut std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _9: &mut std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let mut _10: isize; // in scope 0 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + let mut _11: !; // in scope 0 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + let mut _13: i32; // in scope 0 at $DIR/derefer_complex_case.rs:+1:34: +1:37 + let mut _14: &[i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 ++ let mut _15: &i32; // in scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + scope 1 { + debug iter => _4; // in scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + let _12: i32; // in scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 + scope 2 { + debug foo => _12; // in scope 2 at $DIR/derefer_complex_case.rs:+1:10: +1:13 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + StorageLive(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _14 = const main::promoted[0]; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:5:17: 5:26 + // + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) } + _2 = &(*_14); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _1 = <&[i32; 2] as IntoIterator>::into_iter(move _2) -> bb1; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:5:17: 5:26 + // + literal: Const { ty: fn(&[i32; 2]) -> <&[i32; 2] as IntoIterator>::IntoIter {<&[i32; 2] as IntoIterator>::into_iter}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:25: +1:26 + StorageLive(_4); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _4 = move _1; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + } + + bb2: { + StorageLive(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + StorageLive(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + StorageLive(_8); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + StorageLive(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _9 = &mut _4; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _8 = &mut (*_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _7 = <std::slice::Iter<i32> as Iterator>::next(move _8) -> bb3; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:5:17: 5:26 + // + literal: Const { ty: for<'r> fn(&'r mut std::slice::Iter<i32>) -> Option<<std::slice::Iter<i32> as Iterator>::Item> {<std::slice::Iter<i32> as Iterator>::next}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_8); // scope 1 at $DIR/derefer_complex_case.rs:+1:25: +1:26 + _10 = discriminant(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + } + + bb4: { + StorageLive(_12); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 +- _12 = (*((_7 as Some).0: &i32)); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 ++ StorageLive(_15); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 ++ _15 = deref_copy ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 ++ _12 = (*_15); // scope 1 at $DIR/derefer_complex_case.rs:+1:10: +1:13 ++ StorageDead(_15); // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37 + StorageLive(_13); // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37 + _13 = _12; // scope 2 at $DIR/derefer_complex_case.rs:+1:34: +1:37 + _6 = std::mem::drop::<i32>(move _13) -> bb7; // scope 2 at $DIR/derefer_complex_case.rs:+1:29: +1:38 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:5:29: 5:33 + // + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(<ZST>) } + } + + bb5: { + unreachable; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + } + + bb6: { + _0 = const (); // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + StorageDead(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_4); // scope 0 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + return; // scope 0 at $DIR/derefer_complex_case.rs:+2:2: +2:2 + } + + bb7: { + StorageDead(_13); // scope 2 at $DIR/derefer_complex_case.rs:+1:37: +1:38 + StorageDead(_12); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_9); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:+1:39: +1:40 + _5 = const (); // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:+1:5: +1:40 + } + } + diff --git a/src/test/mir-opt/derefer_complex_case.rs b/src/test/mir-opt/derefer_complex_case.rs new file mode 100644 index 000000000..48bec3907 --- /dev/null +++ b/src/test/mir-opt/derefer_complex_case.rs @@ -0,0 +1,6 @@ +// EMIT_MIR derefer_complex_case.main.Derefer.diff +// ignore-wasm32 + +fn main() { + for &foo in &[42, 43] { drop(foo) } +} diff --git a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff new file mode 100644 index 000000000..ce6ffaa56 --- /dev/null +++ b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff @@ -0,0 +1,61 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_inline_test.rs:+0:11: +0:11 + let _1: std::boxed::Box<std::boxed::Box<u32>>; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + let mut _2: usize; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + let mut _3: usize; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + let mut _4: *mut u8; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + let mut _5: std::boxed::Box<std::boxed::Box<u32>>; // in scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + _2 = SizeOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + _3 = AlignOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + // mir::Constant + // + span: $DIR/derefer_inline_test.rs:10:5: 10:12 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + _5 = ShallowInitBox(move _4, std::boxed::Box<u32>); // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + (*_5) = f() -> [return: bb2, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:+1:9: +1:12 + // mir::Constant + // + span: $DIR/derefer_inline_test.rs:10:9: 10:10 + // + literal: Const { ty: fn() -> Box<u32> {f}, val: Value(<ZST>) } + } + + bb2: { + _1 = move _5; // scope 0 at $DIR/derefer_inline_test.rs:+1:5: +1:12 + drop(_5) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:+1:11: +1:12 + } + + bb3: { + StorageDead(_5); // scope 0 at $DIR/derefer_inline_test.rs:+1:11: +1:12 + drop(_1) -> bb4; // scope 0 at $DIR/derefer_inline_test.rs:+1:12: +1:13 + } + + bb4: { + StorageDead(_1); // scope 0 at $DIR/derefer_inline_test.rs:+1:12: +1:13 + _0 = const (); // scope 0 at $DIR/derefer_inline_test.rs:+0:11: +2:2 + return; // scope 0 at $DIR/derefer_inline_test.rs:+2:2: +2:2 + } + + bb5 (cleanup): { + drop(_1) -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:+1:12: +1:13 + } + + bb6 (cleanup): { + drop(_5) -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:+1:11: +1:12 + } + + bb7 (cleanup): { + resume; // scope 0 at $DIR/derefer_inline_test.rs:+0:1: +2:2 + } + } + diff --git a/src/test/mir-opt/derefer_inline_test.rs b/src/test/mir-opt/derefer_inline_test.rs new file mode 100644 index 000000000..191a8cbbe --- /dev/null +++ b/src/test/mir-opt/derefer_inline_test.rs @@ -0,0 +1,11 @@ +// EMIT_MIR derefer_inline_test.main.Derefer.diff +// ignore-wasm32 compiled with panic=abort by default + +#![feature(box_syntax)] +#[inline] +fn f() -> Box<u32> { + box 0 +} +fn main() { + box f(); +} diff --git a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff new file mode 100644 index 000000000..0a56ee5e4 --- /dev/null +++ b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff @@ -0,0 +1,99 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_terminator_test.rs:+0:11: +0:11 + let _1: bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+1:9: +1:10 + let _3: (); // in scope 0 at $DIR/derefer_terminator_test.rs:+3:5: +6:6 + let mut _4: &&&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 + let _5: &&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:17: +3:21 + let _6: &&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:18: +3:21 + let _7: &bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:19: +3:21 ++ let mut _10: &&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 ++ let mut _11: &&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 ++ let mut _12: &bool; // in scope 0 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 + scope 1 { + debug b => _1; // in scope 1 at $DIR/derefer_terminator_test.rs:+1:9: +1:10 + let _2: bool; // in scope 1 at $DIR/derefer_terminator_test.rs:+2:9: +2:10 + scope 2 { + debug d => _2; // in scope 2 at $DIR/derefer_terminator_test.rs:+2:9: +2:10 + let _8: i32; // in scope 2 at $DIR/derefer_terminator_test.rs:+4:22: +4:23 + let _9: i32; // in scope 2 at $DIR/derefer_terminator_test.rs:+7:9: +7:10 + scope 3 { + debug x => _8; // in scope 3 at $DIR/derefer_terminator_test.rs:+4:22: +4:23 + } + scope 4 { + debug y => _9; // in scope 4 at $DIR/derefer_terminator_test.rs:+7:9: +7:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_terminator_test.rs:+1:9: +1:10 + _1 = foo() -> bb1; // scope 0 at $DIR/derefer_terminator_test.rs:+1:13: +1:18 + // mir::Constant + // + span: $DIR/derefer_terminator_test.rs:5:13: 5:16 + // + literal: Const { ty: fn() -> bool {foo}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_2); // scope 1 at $DIR/derefer_terminator_test.rs:+2:9: +2:10 + _2 = foo() -> bb2; // scope 1 at $DIR/derefer_terminator_test.rs:+2:13: +2:18 + // mir::Constant + // + span: $DIR/derefer_terminator_test.rs:6:13: 6:16 + // + literal: Const { ty: fn() -> bool {foo}, val: Value(<ZST>) } + } + + bb2: { + StorageLive(_3); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +6:6 + StorageLive(_4); // scope 2 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 + StorageLive(_5); // scope 2 at $DIR/derefer_terminator_test.rs:+3:17: +3:21 + StorageLive(_6); // scope 2 at $DIR/derefer_terminator_test.rs:+3:18: +3:21 + StorageLive(_7); // scope 2 at $DIR/derefer_terminator_test.rs:+3:19: +3:21 + _7 = &_1; // scope 2 at $DIR/derefer_terminator_test.rs:+3:19: +3:21 + _6 = &_7; // scope 2 at $DIR/derefer_terminator_test.rs:+3:18: +3:21 + _5 = &_6; // scope 2 at $DIR/derefer_terminator_test.rs:+3:17: +3:21 + _4 = &_5; // scope 2 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 +- switchInt((*(*(*(*_4))))) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ StorageLive(_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ _10 = deref_copy (*_4); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ StorageLive(_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ _11 = deref_copy (*_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ StorageDead(_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ StorageLive(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ _12 = deref_copy (*_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ StorageDead(_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ switchInt((*_12)) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 + } + + bb3: { ++ StorageDead(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 + _3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:+5:18: +5:20 + goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:+5:18: +5:20 + } + + bb4: { ++ StorageDead(_12); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 + StorageLive(_8); // scope 2 at $DIR/derefer_terminator_test.rs:+4:22: +4:23 + _8 = const 5_i32; // scope 2 at $DIR/derefer_terminator_test.rs:+4:26: +4:27 + _3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:+4:17: +4:29 + StorageDead(_8); // scope 2 at $DIR/derefer_terminator_test.rs:+4:28: +4:29 + goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:+4:28: +4:29 + } + + bb5: { + StorageDead(_7); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageDead(_6); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageDead(_5); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageDead(_4); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageDead(_3); // scope 2 at $DIR/derefer_terminator_test.rs:+6:5: +6:6 + StorageLive(_9); // scope 2 at $DIR/derefer_terminator_test.rs:+7:9: +7:10 + _9 = const 42_i32; // scope 2 at $DIR/derefer_terminator_test.rs:+7:13: +7:15 + _0 = const (); // scope 0 at $DIR/derefer_terminator_test.rs:+0:11: +8:2 + StorageDead(_9); // scope 2 at $DIR/derefer_terminator_test.rs:+8:1: +8:2 + StorageDead(_2); // scope 1 at $DIR/derefer_terminator_test.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/derefer_terminator_test.rs:+8:1: +8:2 + return; // scope 0 at $DIR/derefer_terminator_test.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/derefer_terminator_test.rs b/src/test/mir-opt/derefer_terminator_test.rs new file mode 100644 index 000000000..787b14ae7 --- /dev/null +++ b/src/test/mir-opt/derefer_terminator_test.rs @@ -0,0 +1,16 @@ +// EMIT_MIR derefer_terminator_test.main.Derefer.diff +// ignore-wasm32 + +fn main() { + let b = foo(); + let d = foo(); + match ****(&&&&b) { + true => {let x = 5;}, + false => {} + } + let y = 42; +} + +fn foo() -> bool { + true +} diff --git a/src/test/mir-opt/derefer_test.main.Derefer.diff b/src/test/mir-opt/derefer_test.main.Derefer.diff new file mode 100644 index 000000000..6c2047e21 --- /dev/null +++ b/src/test/mir-opt/derefer_test.main.Derefer.diff @@ -0,0 +1,54 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_test.rs:+0:11: +0:11 + let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test.rs:+1:9: +1:14 + let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:+2:22: +2:28 ++ let mut _6: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:+2:9: +2:14 ++ let mut _7: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:+2:9: +2:14 + scope 1 { + debug a => _1; // in scope 1 at $DIR/derefer_test.rs:+1:9: +1:14 + let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test.rs:+2:9: +2:14 + scope 2 { + debug b => _2; // in scope 2 at $DIR/derefer_test.rs:+2:9: +2:14 + let _4: &mut i32; // in scope 2 at $DIR/derefer_test.rs:+3:9: +3:10 + scope 3 { + debug x => _4; // in scope 3 at $DIR/derefer_test.rs:+3:9: +3:10 + let _5: &mut i32; // in scope 3 at $DIR/derefer_test.rs:+4:9: +4:10 + scope 4 { + debug y => _5; // in scope 4 at $DIR/derefer_test.rs:+4:9: +4:10 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_test.rs:+1:9: +1:14 + _1 = (const 42_i32, const 43_i32); // scope 0 at $DIR/derefer_test.rs:+1:17: +1:24 + StorageLive(_2); // scope 1 at $DIR/derefer_test.rs:+2:9: +2:14 + StorageLive(_3); // scope 1 at $DIR/derefer_test.rs:+2:22: +2:28 + _3 = &mut _1; // scope 1 at $DIR/derefer_test.rs:+2:22: +2:28 + _2 = (const 99_i32, move _3); // scope 1 at $DIR/derefer_test.rs:+2:17: +2:29 + StorageDead(_3); // scope 1 at $DIR/derefer_test.rs:+2:28: +2:29 + StorageLive(_4); // scope 2 at $DIR/derefer_test.rs:+3:9: +3:10 +- _4 = &mut ((*(_2.1: &mut (i32, i32))).0: i32); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26 ++ StorageLive(_6); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26 ++ _6 = deref_copy (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26 ++ _4 = &mut ((*_6).0: i32); // scope 2 at $DIR/derefer_test.rs:+3:13: +3:26 ++ StorageDead(_6); // scope 3 at $DIR/derefer_test.rs:+4:9: +4:10 + StorageLive(_5); // scope 3 at $DIR/derefer_test.rs:+4:9: +4:10 +- _5 = &mut ((*(_2.1: &mut (i32, i32))).1: i32); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26 ++ StorageLive(_7); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26 ++ _7 = deref_copy (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26 ++ _5 = &mut ((*_7).1: i32); // scope 3 at $DIR/derefer_test.rs:+4:13: +4:26 ++ StorageDead(_7); // scope 0 at $DIR/derefer_test.rs:+0:11: +5:2 + _0 = const (); // scope 0 at $DIR/derefer_test.rs:+0:11: +5:2 + StorageDead(_5); // scope 3 at $DIR/derefer_test.rs:+5:1: +5:2 + StorageDead(_4); // scope 2 at $DIR/derefer_test.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/derefer_test.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/derefer_test.rs:+5:1: +5:2 + return; // scope 0 at $DIR/derefer_test.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/derefer_test.rs b/src/test/mir-opt/derefer_test.rs new file mode 100644 index 000000000..2ebc0d343 --- /dev/null +++ b/src/test/mir-opt/derefer_test.rs @@ -0,0 +1,7 @@ +// EMIT_MIR derefer_test.main.Derefer.diff +fn main() { + let mut a = (42,43); + let mut b = (99, &mut a); + let x = &mut (*b.1).0; + let y = &mut (*b.1).1; +} diff --git a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff new file mode 100644 index 000000000..e2dceecfd --- /dev/null +++ b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff @@ -0,0 +1,92 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_test_multiple.rs:+0:12: +0:12 + let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:+1:9: +1:14 + let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:+2:22: +2:28 + let mut _5: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:+3:22: +3:28 + let mut _7: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:22: +4:28 ++ let mut _10: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 ++ let mut _11: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 ++ let mut _12: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 ++ let mut _13: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 ++ let mut _14: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 ++ let mut _15: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 + scope 1 { + debug a => _1; // in scope 1 at $DIR/derefer_test_multiple.rs:+1:9: +1:14 + let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test_multiple.rs:+2:9: +2:14 + scope 2 { + debug b => _2; // in scope 2 at $DIR/derefer_test_multiple.rs:+2:9: +2:14 + let mut _4: (i32, &mut (i32, &mut (i32, i32))); // in scope 2 at $DIR/derefer_test_multiple.rs:+3:9: +3:14 + scope 3 { + debug c => _4; // in scope 3 at $DIR/derefer_test_multiple.rs:+3:9: +3:14 + let mut _6: (i32, &mut (i32, &mut (i32, &mut (i32, i32)))); // in scope 3 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 + scope 4 { + debug d => _6; // in scope 4 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 + let _8: &mut i32; // in scope 4 at $DIR/derefer_test_multiple.rs:+5:9: +5:10 + scope 5 { + debug x => _8; // in scope 5 at $DIR/derefer_test_multiple.rs:+5:9: +5:10 + let _9: &mut i32; // in scope 5 at $DIR/derefer_test_multiple.rs:+6:9: +6:10 + scope 6 { + debug y => _9; // in scope 6 at $DIR/derefer_test_multiple.rs:+6:9: +6:10 + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_test_multiple.rs:+1:9: +1:14 + _1 = (const 42_i32, const 43_i32); // scope 0 at $DIR/derefer_test_multiple.rs:+1:17: +1:25 + StorageLive(_2); // scope 1 at $DIR/derefer_test_multiple.rs:+2:9: +2:14 + StorageLive(_3); // scope 1 at $DIR/derefer_test_multiple.rs:+2:22: +2:28 + _3 = &mut _1; // scope 1 at $DIR/derefer_test_multiple.rs:+2:22: +2:28 + _2 = (const 99_i32, move _3); // scope 1 at $DIR/derefer_test_multiple.rs:+2:17: +2:29 + StorageDead(_3); // scope 1 at $DIR/derefer_test_multiple.rs:+2:28: +2:29 + StorageLive(_4); // scope 2 at $DIR/derefer_test_multiple.rs:+3:9: +3:14 + StorageLive(_5); // scope 2 at $DIR/derefer_test_multiple.rs:+3:22: +3:28 + _5 = &mut _2; // scope 2 at $DIR/derefer_test_multiple.rs:+3:22: +3:28 + _4 = (const 11_i32, move _5); // scope 2 at $DIR/derefer_test_multiple.rs:+3:17: +3:29 + StorageDead(_5); // scope 2 at $DIR/derefer_test_multiple.rs:+3:28: +3:29 + StorageLive(_6); // scope 3 at $DIR/derefer_test_multiple.rs:+4:9: +4:14 + StorageLive(_7); // scope 3 at $DIR/derefer_test_multiple.rs:+4:22: +4:28 + _7 = &mut _4; // scope 3 at $DIR/derefer_test_multiple.rs:+4:22: +4:28 + _6 = (const 13_i32, move _7); // scope 3 at $DIR/derefer_test_multiple.rs:+4:17: +4:29 + StorageDead(_7); // scope 3 at $DIR/derefer_test_multiple.rs:+4:28: +4:29 + StorageLive(_8); // scope 4 at $DIR/derefer_test_multiple.rs:+5:9: +5:10 +- _8 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ StorageLive(_10); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ _10 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ StorageLive(_11); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ _11 = deref_copy ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ StorageDead(_10); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ StorageLive(_12); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ _12 = deref_copy ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ StorageDead(_11); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ _8 = &mut ((*_12).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:+5:13: +5:30 ++ StorageDead(_12); // scope 5 at $DIR/derefer_test_multiple.rs:+6:9: +6:10 + StorageLive(_9); // scope 5 at $DIR/derefer_test_multiple.rs:+6:9: +6:10 +- _9 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ StorageLive(_13); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ _13 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ StorageLive(_14); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ _14 = deref_copy ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ StorageDead(_13); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ StorageLive(_15); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ _15 = deref_copy ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ StorageDead(_14); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ _9 = &mut ((*_15).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:+6:13: +6:30 ++ StorageDead(_15); // scope 0 at $DIR/derefer_test_multiple.rs:+0:12: +7:2 + _0 = const (); // scope 0 at $DIR/derefer_test_multiple.rs:+0:12: +7:2 + StorageDead(_9); // scope 5 at $DIR/derefer_test_multiple.rs:+7:1: +7:2 + StorageDead(_8); // scope 4 at $DIR/derefer_test_multiple.rs:+7:1: +7:2 + StorageDead(_6); // scope 3 at $DIR/derefer_test_multiple.rs:+7:1: +7:2 + StorageDead(_4); // scope 2 at $DIR/derefer_test_multiple.rs:+7:1: +7:2 + StorageDead(_2); // scope 1 at $DIR/derefer_test_multiple.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/derefer_test_multiple.rs:+7:1: +7:2 + return; // scope 0 at $DIR/derefer_test_multiple.rs:+7:2: +7:2 + } + } + diff --git a/src/test/mir-opt/derefer_test_multiple.rs b/src/test/mir-opt/derefer_test_multiple.rs new file mode 100644 index 000000000..a27363447 --- /dev/null +++ b/src/test/mir-opt/derefer_test_multiple.rs @@ -0,0 +1,9 @@ +// EMIT_MIR derefer_test_multiple.main.Derefer.diff +fn main () { + let mut a = (42, 43); + let mut b = (99, &mut a); + let mut c = (11, &mut b); + let mut d = (13, &mut c); + let x = &mut (*d.1).1.1.1; + let y = &mut (*d.1).1.1.1; +} diff --git a/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff new file mode 100644 index 000000000..8929f2cc7 --- /dev/null +++ b/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff @@ -0,0 +1,65 @@ +- // MIR for `main` before DestinationPropagation ++ // MIR for `main` after DestinationPropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/branch.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/branch.rs:+1:9: +1:10 + let mut _3: bool; // in scope 0 at $DIR/branch.rs:+3:16: +3:22 + let _4: i32; // in scope 0 at $DIR/branch.rs:+6:9: +6:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/branch.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/branch.rs:+3:9: +3:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/branch.rs:+3:9: +3:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/branch.rs:+1:9: +1:10 + _1 = val() -> bb1; // scope 0 at $DIR/branch.rs:+1:13: +1:18 + // mir::Constant + // + span: $DIR/branch.rs:13:13: 13:16 + // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_2); // scope 1 at $DIR/branch.rs:+3:9: +3:10 + StorageLive(_3); // scope 1 at $DIR/branch.rs:+3:16: +3:22 + _3 = cond() -> bb2; // scope 1 at $DIR/branch.rs:+3:16: +3:22 + // mir::Constant + // + span: $DIR/branch.rs:15:16: 15:20 + // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) } + } + + bb2: { + switchInt(move _3) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22 + } + + bb3: { + nop; // scope 1 at $DIR/branch.rs:+4:9: +4:10 + goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6 + } + + bb4: { + StorageLive(_4); // scope 1 at $DIR/branch.rs:+6:9: +6:14 + _4 = val() -> bb5; // scope 1 at $DIR/branch.rs:+6:9: +6:14 + // mir::Constant + // + span: $DIR/branch.rs:18:9: 18:12 + // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_4); // scope 1 at $DIR/branch.rs:+6:14: +6:15 + nop; // scope 1 at $DIR/branch.rs:+7:9: +7:10 + goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6 + } + + bb6: { + StorageDead(_3); // scope 1 at $DIR/branch.rs:+8:5: +8:6 + nop; // scope 0 at $DIR/branch.rs:+0:11: +9:2 + StorageDead(_2); // scope 1 at $DIR/branch.rs:+9:1: +9:2 + StorageDead(_1); // scope 0 at $DIR/branch.rs:+9:1: +9:2 + return; // scope 0 at $DIR/branch.rs:+9:2: +9:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/branch.rs b/src/test/mir-opt/dest-prop/branch.rs new file mode 100644 index 000000000..fffcf82b3 --- /dev/null +++ b/src/test/mir-opt/dest-prop/branch.rs @@ -0,0 +1,21 @@ +//! Tests that assignment in both branches of an `if` are eliminated. +// compile-flags: -Zunsound-mir-opts +fn val() -> i32 { + 1 +} + +fn cond() -> bool { + true +} + +// EMIT_MIR branch.main.DestinationPropagation.diff +fn main() { + let x = val(); + + let y = if cond() { + x + } else { + val(); + x + }; +} diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff new file mode 100644 index 000000000..f28bc72df --- /dev/null +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff @@ -0,0 +1,26 @@ +- // MIR for `arg_src` before DestinationPropagation ++ // MIR for `arg_src` after DestinationPropagation + + fn arg_src(_1: i32) -> i32 { + debug x => const 123_i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0:17 + let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30 + let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 + scope 1 { +- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 ++ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 ++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 + nop; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12 +- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 ++ nop; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff new file mode 100644 index 000000000..a8a7e9ab6 --- /dev/null +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff @@ -0,0 +1,28 @@ +- // MIR for `bar` before DestinationPropagation ++ // MIR for `bar` after DestinationPropagation + + fn bar(_1: u8) -> () { + debug x => const 5_u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19 + let _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 + let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 + StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 + _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 + _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13 + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:16:5: 16:10 + // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13 + StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 + nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10 + nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff new file mode 100644 index 000000000..ce9be4c27 --- /dev/null +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff @@ -0,0 +1,18 @@ +- // MIR for `baz` before DestinationPropagation ++ // MIR for `baz` after DestinationPropagation + + fn baz(_1: i32) -> () { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:20: +0:20 + let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10 + StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:20: +3:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff new file mode 100644 index 000000000..d7a0b950f --- /dev/null +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff @@ -0,0 +1,28 @@ +- // MIR for `foo` before DestinationPropagation ++ // MIR for `foo` after DestinationPropagation + + fn foo(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19 + let mut _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 + _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16 + _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17 + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:11:9: 11:14 + // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17 + nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17 + StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17 + nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.rs b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs new file mode 100644 index 000000000..a5fb0f640 --- /dev/null +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs @@ -0,0 +1,39 @@ +// Check that DestinationPropagation does not propagate an assignment to a function argument +// (doing so can break usages of the original argument value) +// compile-flags: -Zunsound-mir-opts +fn dummy(x: u8) -> u8 { + x +} + +// EMIT_MIR copy_propagation_arg.foo.DestinationPropagation.diff +fn foo(mut x: u8) { + // calling `dummy` to make a use of `x` that copyprop cannot eliminate + x = dummy(x); // this will assign a local to `x` +} + +// EMIT_MIR copy_propagation_arg.bar.DestinationPropagation.diff +fn bar(mut x: u8) { + dummy(x); + x = 5; +} + +// EMIT_MIR copy_propagation_arg.baz.DestinationPropagation.diff +fn baz(mut x: i32) { + // self-assignment to a function argument should be eliminated + x = x; +} + +// EMIT_MIR copy_propagation_arg.arg_src.DestinationPropagation.diff +fn arg_src(mut x: i32) -> i32 { + let y = x; + x = 123; // Don't propagate this assignment to `y` + y +} + +fn main() { + // Make sure the function actually gets instantiated. + foo(0); + bar(0); + baz(0); + arg_src(0); +} diff --git a/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff new file mode 100644 index 000000000..8eeb0d354 --- /dev/null +++ b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff @@ -0,0 +1,53 @@ +- // MIR for `main` before DestinationPropagation ++ // MIR for `main` after DestinationPropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/cycle.rs:+1:9: +1:14 + let mut _4: i32; // in scope 0 at $DIR/cycle.rs:+4:9: +4:10 + let _5: (); // in scope 0 at $DIR/cycle.rs:+6:5: +6:12 + let mut _6: i32; // in scope 0 at $DIR/cycle.rs:+6:10: +6:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14 + let _2: i32; // in scope 1 at $DIR/cycle.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10 + let _3: i32; // in scope 2 at $DIR/cycle.rs:+3:9: +3:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10 + scope 4 (inlined std::mem::drop::<i32>) { // at $DIR/cycle.rs:14:5: 14:12 + debug _x => _6; // in scope 4 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:14 + _1 = val() -> bb1; // scope 0 at $DIR/cycle.rs:+1:17: +1:22 + // mir::Constant + // + span: $DIR/cycle.rs:9:17: 9:20 + // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_2); // scope 1 at $DIR/cycle.rs:+2:9: +2:10 + nop; // scope 1 at $DIR/cycle.rs:+2:13: +2:14 + StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10 + nop; // scope 2 at $DIR/cycle.rs:+3:13: +3:14 + StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10 + nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10 + nop; // scope 3 at $DIR/cycle.rs:+4:5: +4:10 + StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10 + StorageLive(_5); // scope 3 at $DIR/cycle.rs:+6:5: +6:12 + StorageLive(_6); // scope 3 at $DIR/cycle.rs:+6:10: +6:11 + nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11 + StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12 + StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13 + StorageDead(_3); // scope 2 at $DIR/cycle.rs:+7:1: +7:2 + StorageDead(_2); // scope 1 at $DIR/cycle.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/cycle.rs:+7:1: +7:2 + return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/cycle.rs b/src/test/mir-opt/dest-prop/cycle.rs new file mode 100644 index 000000000..c9187d408 --- /dev/null +++ b/src/test/mir-opt/dest-prop/cycle.rs @@ -0,0 +1,15 @@ +//! Tests that cyclic assignments don't hang DestinationPropagation, and result in reasonable code. +// compile-flags: -Zunsound-mir-opts +fn val() -> i32 { + 1 +} + +// EMIT_MIR cycle.main.DestinationPropagation.diff +fn main() { + let mut x = val(); + let y = x; + let z = y; + x = z; + + drop(x); +} diff --git a/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff new file mode 100644 index 000000000..a20a172af --- /dev/null +++ b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff @@ -0,0 +1,39 @@ +- // MIR for `nrvo` before DestinationPropagation ++ // MIR for `nrvo` after DestinationPropagation + + fn nrvo(_1: for<'r> fn(&'r mut [u8; 1024])) -> [u8; 1024] { + debug init => _1; // in scope 0 at $DIR/simple.rs:+0:9: +0:13 + let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/simple.rs:+0:39: +0:49 + let mut _2: [u8; 1024]; // in scope 0 at $DIR/simple.rs:+1:9: +1:16 + let _3: (); // in scope 0 at $DIR/simple.rs:+2:5: +2:19 + let mut _4: for<'r> fn(&'r mut [u8; 1024]); // in scope 0 at $DIR/simple.rs:+2:5: +2:9 + let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/simple.rs:+2:10: +2:18 + let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/simple.rs:+2:10: +2:18 + scope 1 { + debug buf => _2; // in scope 1 at $DIR/simple.rs:+1:9: +1:16 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simple.rs:+1:9: +1:16 + _2 = [const 0_u8; 1024]; // scope 0 at $DIR/simple.rs:+1:19: +1:28 + StorageLive(_3); // scope 1 at $DIR/simple.rs:+2:5: +2:19 + StorageLive(_4); // scope 1 at $DIR/simple.rs:+2:5: +2:9 + _4 = _1; // scope 1 at $DIR/simple.rs:+2:5: +2:9 + StorageLive(_5); // scope 1 at $DIR/simple.rs:+2:10: +2:18 + StorageLive(_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18 + _6 = &mut _2; // scope 1 at $DIR/simple.rs:+2:10: +2:18 + _5 = &mut (*_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18 + _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/simple.rs:+2:5: +2:19 + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/simple.rs:+2:18: +2:19 + StorageDead(_4); // scope 1 at $DIR/simple.rs:+2:18: +2:19 + StorageDead(_6); // scope 1 at $DIR/simple.rs:+2:19: +2:20 + StorageDead(_3); // scope 1 at $DIR/simple.rs:+2:19: +2:20 + _0 = _2; // scope 1 at $DIR/simple.rs:+3:5: +3:8 + StorageDead(_2); // scope 0 at $DIR/simple.rs:+4:1: +4:2 + return; // scope 0 at $DIR/simple.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/simple.rs b/src/test/mir-opt/dest-prop/simple.rs new file mode 100644 index 000000000..3627d479a --- /dev/null +++ b/src/test/mir-opt/dest-prop/simple.rs @@ -0,0 +1,14 @@ +//! Copy of `nrvo-simple.rs`, to ensure that full dest-prop handles it too. +// compile-flags: -Zunsound-mir-opts +// EMIT_MIR simple.nrvo.DestinationPropagation.diff +fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { + let mut buf = [0; 1024]; + init(&mut buf); + buf +} + +fn main() { + let _ = nrvo(|buf| { + buf[4] = 4; + }); +} diff --git a/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff new file mode 100644 index 000000000..accdb0085 --- /dev/null +++ b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff @@ -0,0 +1,41 @@ +- // MIR for `main` before DestinationPropagation ++ // MIR for `main` after DestinationPropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/union.rs:+0:11: +0:11 + let _1: main::Un; // in scope 0 at $DIR/union.rs:+5:9: +5:11 + let mut _2: u32; // in scope 0 at $DIR/union.rs:+5:23: +5:28 + let _3: (); // in scope 0 at $DIR/union.rs:+7:5: +7:27 + let mut _4: u32; // in scope 0 at $DIR/union.rs:+7:10: +7:26 + scope 1 { + debug un => _1; // in scope 1 at $DIR/union.rs:+5:9: +5:11 + scope 2 { + } + scope 3 (inlined std::mem::drop::<u32>) { // at $DIR/union.rs:15:5: 15:27 + debug _x => _4; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/union.rs:+5:9: +5:11 + StorageLive(_2); // scope 0 at $DIR/union.rs:+5:23: +5:28 + _2 = val() -> bb1; // scope 0 at $DIR/union.rs:+5:23: +5:28 + // mir::Constant + // + span: $DIR/union.rs:13:23: 13:26 + // + literal: Const { ty: fn() -> u32 {val}, val: Value(<ZST>) } + } + + bb1: { + nop; // scope 0 at $DIR/union.rs:+5:14: +5:30 + nop; // scope 0 at $DIR/union.rs:+5:14: +5:30 + StorageDead(_2); // scope 0 at $DIR/union.rs:+5:29: +5:30 + StorageLive(_3); // scope 1 at $DIR/union.rs:+7:5: +7:27 + StorageLive(_4); // scope 1 at $DIR/union.rs:+7:10: +7:26 + nop; // scope 2 at $DIR/union.rs:+7:19: +7:24 + StorageDead(_4); // scope 1 at $DIR/union.rs:+7:26: +7:27 + StorageDead(_3); // scope 1 at $DIR/union.rs:+7:27: +7:28 + StorageDead(_1); // scope 0 at $DIR/union.rs:+8:1: +8:2 + return; // scope 0 at $DIR/union.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/union.rs b/src/test/mir-opt/dest-prop/union.rs new file mode 100644 index 000000000..68c834dfb --- /dev/null +++ b/src/test/mir-opt/dest-prop/union.rs @@ -0,0 +1,16 @@ +//! Tests that we can propogate into places that are projections into unions +// compile-flags: -Zunsound-mir-opts +fn val() -> u32 { + 1 +} + +// EMIT_MIR union.main.DestinationPropagation.diff +fn main() { + union Un { + us: u32, + } + + let un = Un { us: val() }; + + drop(unsafe { un.us }); +} diff --git a/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..89d8106ae --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff @@ -0,0 +1,78 @@ +- // MIR for `opt1` before EarlyOtherwiseBranch ++ // MIR for `opt1` after EarlyOtherwiseBranch + + fn opt1(_1: Option<u32>, _2: Option<u32>) -> u32 { + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:9: +0:10 + debug y => _2; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:25: +0:26 + let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch.rs:+0:44: +0:47 + let mut _3: (std::option::Option<u32>, std::option::Option<u32>); // in scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + let mut _5: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + let mut _6: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:19: +2:26 + let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:10: +2:17 + let _8: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + let _9: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 ++ let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ let mut _11: bool; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + scope 1 { + debug a => _8; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + debug b => _9; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + _4 = _1; // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + _5 = _2; // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + Deinit(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + (_3.0: std::option::Option<u32>) = move _4; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + (_3.1: std::option::Option<u32>) = move _5; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 + _7 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 +- switchInt(move _7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ _10 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ _11 = Ne(_7, move _10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(move _11) -> [false: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + + bb1: { ++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15 + _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15 +- goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15 ++ goto -> bb3; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15 + } + + bb2: { +- _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 +- switchInt(move _6) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- } +- +- bb3: { + StorageLive(_8); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + _8 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + _9 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + StorageDead(_8); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 +- goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 ++ goto -> bb3; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + } + +- bb4: { ++ bb3: { + StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+5:1: +5:2 + return; // scope 0 at $DIR/early_otherwise_branch.rs:+5:2: +5:2 ++ } ++ ++ bb4: { ++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(_7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..1a9efa930 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff @@ -0,0 +1,92 @@ +- // MIR for `opt2` before EarlyOtherwiseBranch ++ // MIR for `opt2` after EarlyOtherwiseBranch + + fn opt2(_1: Option<u32>, _2: Option<u32>) -> u32 { + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:9: +0:10 + debug y => _2; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:25: +0:26 + let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch.rs:+0:44: +0:47 + let mut _3: (std::option::Option<u32>, std::option::Option<u32>); // in scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + let mut _5: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + let mut _6: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+3:16: +3:20 + let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:19: +2:26 + let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:10: +2:17 + let _9: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + let _10: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 ++ let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ let mut _12: bool; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + scope 1 { + debug a => _9; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + debug b => _10; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + _4 = _1; // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + _5 = _2; // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + Deinit(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + (_3.0: std::option::Option<u32>) = move _4; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + (_3.1: std::option::Option<u32>) = move _5; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 + _8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 +- switchInt(move _8) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ _11 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ _12 = Ne(_8, move _11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(move _12) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + + bb1: { +- _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 +- switchInt(move _6) -> [0_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- } +- +- bb2: { ++ StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch.rs:+4:14: +4:15 + _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch.rs:+4:14: +4:15 +- goto -> bb6; // scope 0 at $DIR/early_otherwise_branch.rs:+4:14: +4:15 ++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+4:14: +4:15 + } + +- bb3: { +- _7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 +- switchInt(move _7) -> [1_isize: bb4, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- } +- +- bb4: { ++ bb2: { + StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 +- goto -> bb6; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 ++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + } + +- bb5: { ++ bb3: { + _0 = const 0_u32; // scope 0 at $DIR/early_otherwise_branch.rs:+3:25: +3:26 +- goto -> bb6; // scope 0 at $DIR/early_otherwise_branch.rs:+3:25: +3:26 ++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+3:25: +3:26 + } + +- bb6: { ++ bb4: { + StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+6:1: +6:2 + return; // scope 0 at $DIR/early_otherwise_branch.rs:+6:2: +6:2 ++ } ++ ++ bb5: { ++ StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(_8) -> [0_isize: bb3, 1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..309a72ae5 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff @@ -0,0 +1,78 @@ +- // MIR for `opt3` before EarlyOtherwiseBranch ++ // MIR for `opt3` after EarlyOtherwiseBranch + + fn opt3(_1: Option<u32>, _2: Option<bool>) -> u32 { + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:9: +0:10 + debug y => _2; // in scope 0 at $DIR/early_otherwise_branch.rs:+0:25: +0:26 + let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch.rs:+0:45: +0:48 + let mut _3: (std::option::Option<u32>, std::option::Option<bool>); // in scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + let mut _5: std::option::Option<bool>; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + let mut _6: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:19: +2:26 + let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:10: +2:17 + let _8: u32; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + let _9: bool; // in scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 ++ let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ let mut _11: bool; // in scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + scope 1 { + debug a => _8; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + debug b => _9; // in scope 1 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + _4 = _1; // scope 0 at $DIR/early_otherwise_branch.rs:+1:12: +1:13 + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + _5 = _2; // scope 0 at $DIR/early_otherwise_branch.rs:+1:15: +1:16 + Deinit(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + (_3.0: std::option::Option<u32>) = move _4; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + (_3.1: std::option::Option<bool>) = move _5; // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 + _7 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 +- switchInt(move _7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ _10 = discriminant((_3.1: std::option::Option<bool>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ _11 = Ne(_7, move _10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(move _11) -> [false: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + + bb1: { ++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15 + _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15 +- goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15 ++ goto -> bb3; // scope 0 at $DIR/early_otherwise_branch.rs:+3:14: +3:15 + } + + bb2: { +- _6 = discriminant((_3.1: std::option::Option<bool>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 +- switchInt(move _6) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- } +- +- bb3: { + StorageLive(_8); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + _8 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch.rs:+2:15: +2:16 + StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + _9 = (((_3.1: std::option::Option<bool>) as Some).0: bool); // scope 0 at $DIR/early_otherwise_branch.rs:+2:24: +2:25 + _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + StorageDead(_8); // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 +- goto -> bb4; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 ++ goto -> bb3; // scope 0 at $DIR/early_otherwise_branch.rs:+2:31: +2:32 + } + +- bb4: { ++ bb3: { + StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:+5:1: +5:2 + return; // scope 0 at $DIR/early_otherwise_branch.rs:+5:2: +5:2 ++ } ++ ++ bb4: { ++ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(_7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch.rs b/src/test/mir-opt/early_otherwise_branch.rs new file mode 100644 index 000000000..7be9fbd03 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch.rs @@ -0,0 +1,32 @@ +// unit-test: EarlyOtherwiseBranch +// EMIT_MIR early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff +fn opt1(x: Option<u32>, y: Option<u32>) -> u32 { + match (x, y) { + (Some(a), Some(b)) => 0, + _ => 1, + } +} + +// EMIT_MIR early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff +fn opt2(x: Option<u32>, y: Option<u32>) -> u32 { + match (x, y) { + (Some(a), Some(b)) => 0, + (None, None) => 0, + _ => 1, + } +} + +// optimize despite different types +// EMIT_MIR early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff +fn opt3(x: Option<u32>, y: Option<bool>) -> u32 { + match (x, y) { + (Some(a), Some(b)) => 0, + _ => 1, + } +} + +fn main() { + opt1(None, Some(0)); + opt2(None, Some(0)); + opt3(None, Some(false)); +} diff --git a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..9574f32f7 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff @@ -0,0 +1,100 @@ +- // MIR for `opt1` before EarlyOtherwiseBranch ++ // MIR for `opt1` after EarlyOtherwiseBranch + + fn opt1(_1: Option<u32>, _2: Option<u32>, _3: Option<u32>) -> u32 { + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+0:9: +0:10 + debug y => _2; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+0:25: +0:26 + debug z => _3; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+0:41: +0:42 + let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+0:60: +0:63 + let mut _4: (std::option::Option<u32>, std::option::Option<u32>, std::option::Option<u32>); // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 + let mut _5: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:12: +1:13 + let mut _6: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:15: +1:16 + let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:18: +1:19 + let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:28: +2:35 + let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:19: +2:26 + let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:10: +2:17 + let _11: u32; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:15: +2:16 + let _12: u32; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:24: +2:25 + let _13: u32; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:33: +2:34 ++ let mut _14: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ let mut _15: bool; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ let mut _16: isize; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ let mut _17: bool; // in scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + scope 1 { + debug a => _11; // in scope 1 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:15: +2:16 + debug b => _12; // in scope 1 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:24: +2:25 + debug c => _13; // in scope 1 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:33: +2:34 + } + + bb0: { + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:12: +1:13 + _5 = _1; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:12: +1:13 + StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:15: +1:16 + _6 = _2; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:15: +1:16 + StorageLive(_7); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:18: +1:19 + _7 = _3; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:18: +1:19 + Deinit(_4); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 + (_4.0: std::option::Option<u32>) = move _5; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 + (_4.1: std::option::Option<u32>) = move _6; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 + (_4.2: std::option::Option<u32>) = move _7; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 + StorageDead(_7); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:19: +1:20 + StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:19: +1:20 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:19: +1:20 + _10 = discriminant((_4.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 +- switchInt(move _10) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ StorageLive(_14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ _14 = discriminant((_4.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ StorageLive(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ _15 = Ne(_10, move _14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ StorageDead(_14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ switchInt(move _15) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + } + + bb1: { ++ StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15 ++ StorageDead(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15 + _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15 +- goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15 ++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+3:14: +3:15 + } + + bb2: { +- _9 = discriminant((_4.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 +- switchInt(move _9) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 +- } +- +- bb3: { + _8 = discriminant((_4.2: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 +- switchInt(move _8) -> [1_isize: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ switchInt(move _8) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + } + +- bb4: { ++ bb3: { + StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:15: +2:16 + _11 = (((_4.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:15: +2:16 + StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:24: +2:25 + _12 = (((_4.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:24: +2:25 + StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:33: +2:34 + _13 = (((_4.2: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:33: +2:34 + _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41 + StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41 + StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41 + StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41 +- goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41 ++ goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+2:40: +2:41 + } + +- bb5: { ++ bb4: { + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+5:1: +5:2 + return; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+5:2: +5:2 ++ } ++ ++ bb5: { ++ StorageDead(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ switchInt(_10) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs new file mode 100644 index 000000000..76055e133 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs @@ -0,0 +1,13 @@ +// unit-test: EarlyOtherwiseBranch + +// EMIT_MIR early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff +fn opt1(x: Option<u32>, y: Option<u32>, z: Option<u32>) -> u32 { + match (x, y, z) { + (Some(a), Some(b), Some(c)) => 0, + _ => 1, + } +} + +fn main() { + opt1(None, Some(0), None); +} diff --git a/src/test/mir-opt/early_otherwise_branch_68867.rs b/src/test/mir-opt/early_otherwise_branch_68867.rs new file mode 100644 index 000000000..ca298e921 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_68867.rs @@ -0,0 +1,32 @@ +// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts + +// example from #68867 +type CSSFloat = f32; + +pub enum ViewportPercentageLength { + Vw(CSSFloat), + Vh(CSSFloat), + Vmin(CSSFloat), + Vmax(CSSFloat), +} + +// EMIT_MIR early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff +// EMIT_MIR early_otherwise_branch_68867.try_sum EarlyOtherwiseBranch.before SimplifyConstCondition-final.after +#[no_mangle] +pub extern "C" fn try_sum( + x: &ViewportPercentageLength, + other: &ViewportPercentageLength, +) -> Result<ViewportPercentageLength, ()> { + use self::ViewportPercentageLength::*; + Ok(match (x, other) { + (&Vw(one), &Vw(other)) => Vw(one + other), + (&Vh(one), &Vh(other)) => Vh(one + other), + (&Vmin(one), &Vmin(other)) => Vmin(one + other), + (&Vmax(one), &Vmax(other)) => Vmax(one + other), + _ => return Err(()), + }) +} + +fn main() { + try_sum(&ViewportPercentageLength::Vw(1.0), &ViewportPercentageLength::Vw(2.0)); +} diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff new file mode 100644 index 000000000..4e6852ad7 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff @@ -0,0 +1,344 @@ +- // MIR for `try_sum` before EarlyOtherwiseBranch ++ // MIR for `try_sum` after SimplifyConstCondition-final + + fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> Result<ViewportPercentageLength, ()> { + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+1:5: +1:6 + debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+2:5: +2:10 + let mut _0: std::result::Result<ViewportPercentageLength, ()>; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:+3:6: +3:42 + let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6 + let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16 + let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23 + let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:21: +6:30 + let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:21: +7:30 + let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:23: +8:34 + let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:23: +9:34 + let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:11: +6:18 + let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 + let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41 + let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49 + let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 + let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41 + let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49 + let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 + let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47 + let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55 + let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 + let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47 + let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55 + let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:14: +10:28 + let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27 + let mut _34: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _35: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _36: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _37: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _38: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _39: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _40: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _41: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _42: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _43: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _44: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _45: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _46: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + scope 1 { +- debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 +- debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 ++ debug one => _15; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 ++ debug other => _16; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + } + scope 2 { +- debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 +- debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 ++ debug one => _20; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 ++ debug other => _21; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + } + scope 3 { +- debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 +- debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 ++ debug one => _25; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 ++ debug other => _26; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + } + scope 4 { +- debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 +- debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 ++ debug one => _30; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 ++ debug other => _31; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + } + + bb0: { +- StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6 +- StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 +- StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16 +- _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16 ++ (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16 + StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23 + _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23 + Deinit(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 +- (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24 +- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24 + StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb1: { + StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb2: { + StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27 + Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28 + discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28 + StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28 +- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7 +- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2 + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2 + } + + bb3: { + StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb4: { + StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb5: { + StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb6: { +- StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + _39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 +- _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 ++ _15 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 +- StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + _40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 +- _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 ++ _16 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 +- StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 +- StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41 +- _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41 +- StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49 +- _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49 +- _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 +- StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49 +- StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49 +- Deinit(_3); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 +- ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 +- discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 +- StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 +- StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 +- StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49 ++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 + } + + bb7: { +- StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + _41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 +- _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 ++ _20 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 +- StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + _42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 +- _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 ++ _21 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 +- StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 +- StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41 +- _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41 +- StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49 +- _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49 +- _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 +- StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49 +- StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49 +- Deinit(_3); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 +- ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 +- discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 +- StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 +- StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 +- StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49 ++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 + } + + bb8: { +- StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + _43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 +- _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 ++ _25 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 +- StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + _44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 +- _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 ++ _26 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 +- StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 +- StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47 +- _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47 +- StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55 +- _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55 +- _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 +- StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55 +- StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55 +- Deinit(_3); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 +- ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 +- discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 +- StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 +- StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 +- StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55 ++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 + } + + bb9: { +- StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + _45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 +- _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 ++ _30 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 +- StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + _46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 +- _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 ++ _31 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 +- StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 +- StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47 +- _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47 +- StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55 +- _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55 +- _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 +- StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55 +- StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55 +- Deinit(_3); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 +- ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 +- discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 +- StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 +- StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 +- StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55 ++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 + } + + bb10: { + Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7 +- ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7 + discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7 +- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7 +- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2 + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..2519f79f8 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -0,0 +1,253 @@ +- // MIR for `try_sum` before EarlyOtherwiseBranch ++ // MIR for `try_sum` after EarlyOtherwiseBranch + + fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> Result<ViewportPercentageLength, ()> { + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+1:5: +1:6 + debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+2:5: +2:10 + let mut _0: std::result::Result<ViewportPercentageLength, ()>; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:+3:6: +3:42 + let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6 + let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16 + let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23 + let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:21: +6:30 + let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:21: +7:30 + let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:23: +8:34 + let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:23: +9:34 + let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:11: +6:18 + let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 + let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41 + let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49 + let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 + let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41 + let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49 + let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 + let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47 + let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55 + let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 + let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47 + let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55 + let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:14: +10:28 + let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27 + let mut _34: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _35: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _36: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _37: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _38: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _39: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _40: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _41: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _42: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _43: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _44: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _45: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + let mut _46: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + scope 1 { + debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + } + scope 2 { + debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + } + scope 3 { + debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + } + scope 4 { + debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6 + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16 + _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16 + StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23 + _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23 + Deinit(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24 + StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb1: { + StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb2: { + StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27 + Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28 + discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28 + StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28 + StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2 + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2 + } + + bb3: { + StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb4: { + StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb5: { + StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 + StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb6: { + StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + _39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17 + StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + _40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29 + StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 + StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 + StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41 + _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41 + StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49 + _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49 + _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49 + StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49 + StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49 + Deinit(_3); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 + ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 + discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50 + StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 + StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 + StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50 + } + + bb7: { + StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + _41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17 + StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + _42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29 + StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 + StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 + StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41 + _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41 + StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49 + _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49 + _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49 + StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49 + StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49 + Deinit(_3); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 + ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 + discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50 + StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 + StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 + StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50 + } + + bb8: { + StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + _43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19 + StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + _44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33 + StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 + StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 + StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47 + _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47 + StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55 + _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55 + _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55 + StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55 + StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55 + Deinit(_3); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 + ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 + discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56 + StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 + StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 + StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56 + } + + bb9: { + StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + _45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19 + StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + _46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33 + StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 + StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 + StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47 + _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47 + StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55 + _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55 + _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55 + StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55 + StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55 + Deinit(_3); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 + ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 + discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56 + StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 + StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 + StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56 + } + + bb10: { + Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7 + ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7 + discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7 + StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2 + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..321f57951 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff @@ -0,0 +1,95 @@ +- // MIR for `noopt1` before EarlyOtherwiseBranch ++ // MIR for `noopt1` after EarlyOtherwiseBranch + + fn noopt1(_1: Option<u32>, _2: Option<u32>) -> u32 { + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+0:11: +0:12 + debug y => _2; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+0:27: +0:28 + let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+0:46: +0:49 + let mut _3: (std::option::Option<u32>, std::option::Option<u32>); // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + let mut _4: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:12: +1:13 + let mut _5: std::option::Option<u32>; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:15: +1:16 + let mut _6: isize; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:16: +4:23 + let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:19: +2:26 + let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:10: +2:17 + let _9: u32; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:15: +2:16 + let _10: u32; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:24: +2:25 + let _11: u32; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:15: +3:16 + let _12: u32; // in scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:21: +4:22 + scope 1 { + debug a => _9; // in scope 1 at $DIR/early_otherwise_branch_noopt.rs:+2:15: +2:16 + debug b => _10; // in scope 1 at $DIR/early_otherwise_branch_noopt.rs:+2:24: +2:25 + } + scope 2 { + debug a => _11; // in scope 2 at $DIR/early_otherwise_branch_noopt.rs:+3:15: +3:16 + } + scope 3 { + debug b => _12; // in scope 3 at $DIR/early_otherwise_branch_noopt.rs:+4:21: +4:22 + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:12: +1:13 + _4 = _1; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:12: +1:13 + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:15: +1:16 + _5 = _2; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:15: +1:16 + Deinit(_3); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + (_3.0: std::option::Option<u32>) = move _4; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + (_3.1: std::option::Option<u32>) = move _5; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:16: +1:17 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:16: +1:17 + _8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + switchInt(move _8) -> [0_isize: bb1, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 + } + + bb1: { + _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + switchInt(move _6) -> [0_isize: bb2, 1_isize: bb7, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 + } + + bb2: { + _0 = const 3_u32; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+5:25: +5:26 + goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+5:25: +5:26 + } + + bb3: { + unreachable; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + } + + bb4: { + _7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 + switchInt(move _7) -> [0_isize: bb6, 1_isize: bb5, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 + } + + bb5: { + StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:15: +2:16 + _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:15: +2:16 + StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:24: +2:25 + _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:24: +2:25 + _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch_noopt.rs:+2:31: +2:32 + StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:31: +2:32 + StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:31: +2:32 + goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+2:31: +2:32 + } + + bb6: { + StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:15: +3:16 + _11 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:15: +3:16 + _0 = const 1_u32; // scope 2 at $DIR/early_otherwise_branch_noopt.rs:+3:28: +3:29 + StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:28: +3:29 + goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+3:28: +3:29 + } + + bb7: { + StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:21: +4:22 + _12 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:21: +4:22 + _0 = const 2_u32; // scope 3 at $DIR/early_otherwise_branch_noopt.rs:+4:28: +4:29 + StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:28: +4:29 + goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+4:28: +4:29 + } + + bb8: { + StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+7:1: +7:2 + return; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+7:2: +7:2 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch_noopt.rs b/src/test/mir-opt/early_otherwise_branch_noopt.rs new file mode 100644 index 000000000..ef766bbd4 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_noopt.rs @@ -0,0 +1,18 @@ +// unit-test: EarlyOtherwiseBranch + +// must not optimize as it does not follow the pattern of +// left and right hand side being the same variant + +// EMIT_MIR early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff +fn noopt1(x: Option<u32>, y: Option<u32>) -> u32 { + match (x, y) { + (Some(a), Some(b)) => 0, + (Some(a), None) => 1, + (None, Some(b)) => 2, + (None, None) => 3, + } +} + +fn main() { + noopt1(None, Some(0)); +} diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..8b556acb2 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff @@ -0,0 +1,47 @@ +- // MIR for `no_deref_ptr` before EarlyOtherwiseBranch ++ // MIR for `no_deref_ptr` after EarlyOtherwiseBranch + + fn no_deref_ptr(_1: Option<i32>, _2: *const Option<i32>) -> i32 { + debug a => _1; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:24: +0:25 + debug b => _2; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:40: +0:41 + let mut _0: i32; // return place in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:66: +0:69 + let mut _3: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:9: +3:16 + let mut _4: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:13: +4:20 + let _5: i32; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:18: +4:19 + scope 1 { + debug v => _5; // in scope 1 at $DIR/early_otherwise_branch_soundness.rs:+4:18: +4:19 + } + + bb0: { + _3 = discriminant(_1); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:11: +1:12 + switchInt(move _3) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+7:14: +7:15 + goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+7:14: +7:15 + } + + bb2: { + _4 = discriminant((*_2)); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:26: +3:28 + switchInt(move _4) -> [1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:20: +3:28 + } + + bb3: { + _0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+5:18: +5:19 + goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+5:18: +5:19 + } + + bb4: { + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:18: +4:19 + _5 = (((*_2) as Some).0: i32); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:18: +4:19 + _0 = _5; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+4:24: +4:25 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:24: +4:25 + goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+4:24: +4:25 + } + + bb5: { + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+9:2: +9:2 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..3d7b3f75a --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff @@ -0,0 +1,40 @@ +- // MIR for `no_downcast` before EarlyOtherwiseBranch ++ // MIR for `no_downcast` after EarlyOtherwiseBranch + + fn no_downcast(_1: &E) -> u32 { + debug e => _1; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:16: +0:17 + let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:26: +0:29 + let mut _2: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:20: +1:30 + let mut _3: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + let mut _4: &E; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:+0:16: +0:17 + scope 1 { + } + + bb0: { + _3 = discriminant((*_1)); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + switchInt(move _3) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + } + + bb1: { + StorageLive(_4); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + _4 = deref_copy (((*_1) as Some).0: &E); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + _2 = discriminant((*_4)); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + StorageDead(_4); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + } + + bb2: { + _0 = const 1_u32; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:38: +1:39 + goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:5: +1:52 + } + + bb3: { + _0 = const 2_u32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:49: +1:50 + goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:5: +1:52 + } + + bb4: { + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.rs b/src/test/mir-opt/early_otherwise_branch_soundness.rs new file mode 100644 index 000000000..cd4589232 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_soundness.rs @@ -0,0 +1,32 @@ +// unit-test: EarlyOtherwiseBranch + +// Tests various cases that the `early_otherwise_branch` opt should *not* optimize + +// From #78496 +enum E<'a> { + Empty, + Some(&'a E<'a>), +} + +// EMIT_MIR early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff +fn no_downcast(e: &E) -> u32 { + if let E::Some(E::Some(_)) = e { 1 } else { 2 } +} + +// SAFETY: if `a` is `Some`, `b` must point to a valid, initialized value +// EMIT_MIR early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff +unsafe fn no_deref_ptr(a: Option<i32>, b: *const Option<i32>) -> i32 { + match a { + // `*b` being correct depends on `a == Some(_)` + Some(_) => match *b { + Some(v) => v, + _ => 0, + }, + _ => 0, + } +} + +fn main() { + no_downcast(&E::Empty); + unsafe { no_deref_ptr(None, std::ptr::null()) }; +} diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir new file mode 100644 index 000000000..afca2fd29 --- /dev/null +++ b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir @@ -0,0 +1,13 @@ +// MIR for `bar` 0 mir_map + +fn bar(_1: Bar) -> usize { + debug bar => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 + let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 + let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir new file mode 100644 index 000000000..c79596d78 --- /dev/null +++ b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir @@ -0,0 +1,13 @@ +// MIR for `boo` 0 mir_map + +fn boo(_1: Boo) -> usize { + debug boo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 + let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 + let mut _2: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir new file mode 100644 index 000000000..8ced136db --- /dev/null +++ b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir @@ -0,0 +1,54 @@ +// MIR for `droppy` 0 mir_map + +fn droppy() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13 + let _1: (); // in scope 0 at $DIR/enum_cast.rs:+1:5: +6:6 + let _2: Droppy; // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14 + let mut _4: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 + let _5: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + scope 1 { + debug x => _2; // in scope 1 at $DIR/enum_cast.rs:+2:13: +2:14 + scope 2 { + debug y => _3; // in scope 2 at $DIR/enum_cast.rs:+5:13: +5:14 + } + scope 3 { + let _3: usize; // in scope 3 at $DIR/enum_cast.rs:+5:13: +5:14 + } + } + scope 4 { + debug z => _5; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6 + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14 + _2 = Droppy::C; // scope 0 at $DIR/enum_cast.rs:+2:17: +2:26 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14 + StorageLive(_3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14 + _4 = discriminant(_2); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + _3 = move _4 as usize (Misc); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + FakeRead(ForLet(None), _3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14 + _1 = const (); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6 + StorageDead(_3); // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6 + drop(_2) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + StorageDead(_1); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + StorageLive(_5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + _5 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22 + FakeRead(ForLet(None), _5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + _0 = const (); // scope 0 at $DIR/enum_cast.rs:+0:13: +8:2 + drop(_5) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 + } + + bb2: { + StorageDead(_5); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 + return; // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2 + } + + bb3 (cleanup): { + resume; // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2 + } +} diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir new file mode 100644 index 000000000..39d6adeba --- /dev/null +++ b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir @@ -0,0 +1,13 @@ +// MIR for `foo` 0 mir_map + +fn foo(_1: Foo) -> usize { + debug foo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 + let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 + let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/enum_cast.rs b/src/test/mir-opt/enum_cast.rs new file mode 100644 index 000000000..090142aaf --- /dev/null +++ b/src/test/mir-opt/enum_cast.rs @@ -0,0 +1,50 @@ +// EMIT_MIR enum_cast.foo.mir_map.0.mir +// EMIT_MIR enum_cast.bar.mir_map.0.mir +// EMIT_MIR enum_cast.boo.mir_map.0.mir + +enum Foo { + A +} + +enum Bar { + A, B +} + +#[repr(u8)] +enum Boo { + A, B +} + +fn foo(foo: Foo) -> usize { + foo as usize +} + +fn bar(bar: Bar) -> usize { + bar as usize +} + +fn boo(boo: Boo) -> usize { + boo as usize +} + +// EMIT_MIR enum_cast.droppy.mir_map.0.mir +enum Droppy { + A, B, C +} + +impl Drop for Droppy { + fn drop(&mut self) {} +} + +fn droppy() { + { + let x = Droppy::C; + // remove this entire test once `cenum_impl_drop_cast` becomes a hard error + #[allow(cenum_impl_drop_cast)] + let y = x as usize; + } + let z = Droppy::B; +} + +fn main() { +} diff --git a/src/test/mir-opt/equal_true.opt.InstCombine.diff b/src/test/mir-opt/equal_true.opt.InstCombine.diff new file mode 100644 index 000000000..89982308e --- /dev/null +++ b/src/test/mir-opt/equal_true.opt.InstCombine.diff @@ -0,0 +1,35 @@ +- // MIR for `opt` before InstCombine ++ // MIR for `opt` after InstCombine + + fn opt(_1: bool) -> i32 { + debug x => _1; // in scope 0 at $DIR/equal_true.rs:+0:8: +0:9 + let mut _0: i32; // return place in scope 0 at $DIR/equal_true.rs:+0:20: +0:23 + let mut _2: bool; // in scope 0 at $DIR/equal_true.rs:+1:8: +1:17 + let mut _3: bool; // in scope 0 at $DIR/equal_true.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/equal_true.rs:+1:8: +1:17 + StorageLive(_3); // scope 0 at $DIR/equal_true.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/equal_true.rs:+1:8: +1:9 +- _2 = Eq(move _3, const true); // scope 0 at $DIR/equal_true.rs:+1:8: +1:17 ++ _2 = move _3; // scope 0 at $DIR/equal_true.rs:+1:8: +1:17 + StorageDead(_3); // scope 0 at $DIR/equal_true.rs:+1:16: +1:17 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/equal_true.rs:+1:8: +1:17 + } + + bb1: { + _0 = const 0_i32; // scope 0 at $DIR/equal_true.rs:+1:20: +1:21 + goto -> bb3; // scope 0 at $DIR/equal_true.rs:+1:5: +1:34 + } + + bb2: { + _0 = const 1_i32; // scope 0 at $DIR/equal_true.rs:+1:31: +1:32 + goto -> bb3; // scope 0 at $DIR/equal_true.rs:+1:5: +1:34 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/equal_true.rs:+1:33: +1:34 + return; // scope 0 at $DIR/equal_true.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/equal_true.rs b/src/test/mir-opt/equal_true.rs new file mode 100644 index 000000000..994cd194a --- /dev/null +++ b/src/test/mir-opt/equal_true.rs @@ -0,0 +1,9 @@ +// EMIT_MIR equal_true.opt.InstCombine.diff + +fn opt(x: bool) -> i32 { + if x == true { 0 } else { 1 } +} + +fn main() { + opt(true); +} diff --git a/src/test/mir-opt/exponential-or.rs b/src/test/mir-opt/exponential-or.rs new file mode 100644 index 000000000..0b8be8385 --- /dev/null +++ b/src/test/mir-opt/exponential-or.rs @@ -0,0 +1,11 @@ +// Test that simple or-patterns don't get expanded to exponentially large CFGs + +// EMIT_MIR exponential_or.match_tuple.SimplifyCfg-initial.after.mir +fn match_tuple(x: (u32, bool, Option<i32>, u32)) -> u32 { + match x { + (y @ (1 | 4), true | false, Some(1 | 8) | None, z @ (6..=9 | 13..=16)) => y ^ z, + _ => 0, + } +} + +fn main() {} diff --git a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..d39145973 --- /dev/null +++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir @@ -0,0 +1,83 @@ +// MIR for `match_tuple` after SimplifyCfg-initial + +fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 { + debug x => _1; // in scope 0 at $DIR/exponential-or.rs:+0:16: +0:17 + let mut _0: u32; // return place in scope 0 at $DIR/exponential-or.rs:+0:53: +0:56 + let mut _2: isize; // in scope 0 at $DIR/exponential-or.rs:+2:37: +2:48 + let mut _3: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 + let mut _4: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 + let mut _5: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 + let mut _6: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 + let _7: u32; // in scope 0 at $DIR/exponential-or.rs:+2:10: +2:21 + let _8: u32; // in scope 0 at $DIR/exponential-or.rs:+2:57: +2:78 + let mut _9: u32; // in scope 0 at $DIR/exponential-or.rs:+2:83: +2:84 + let mut _10: u32; // in scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 + scope 1 { + debug y => _7; // in scope 1 at $DIR/exponential-or.rs:+2:10: +2:21 + debug z => _8; // in scope 1 at $DIR/exponential-or.rs:+2:57: +2:78 + } + + bb0: { + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential-or.rs:+1:11: +1:12 + switchInt((_1.0: u32)) -> [1_u32: bb2, 4_u32: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:15: +2:20 + } + + bb1: { + _0 = const 0_u32; // scope 0 at $DIR/exponential-or.rs:+3:14: +3:15 + goto -> bb10; // scope 0 at $DIR/exponential-or.rs:+3:14: +3:15 + } + + bb2: { + _2 = discriminant((_1.2: std::option::Option<i32>)); // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55 + switchInt(move _2) -> [0_isize: bb4, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55 + } + + bb3: { + switchInt((((_1.2: std::option::Option<i32>) as Some).0: i32)) -> [1_i32: bb4, 8_i32: bb4, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55 + } + + bb4: { + _5 = Le(const 6_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 + switchInt(move _5) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 + } + + bb5: { + _6 = Le((_1.3: u32), const 9_u32); // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 + switchInt(move _6) -> [false: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67 + } + + bb6: { + _3 = Le(const 13_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 + switchInt(move _3) -> [false: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 + } + + bb7: { + _4 = Le((_1.3: u32), const 16_u32); // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 + switchInt(move _4) -> [false: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77 + } + + bb8: { + falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:9: +2:79 + } + + bb9: { + StorageLive(_7); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:21 + _7 = (_1.0: u32); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:21 + StorageLive(_8); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:78 + _8 = (_1.3: u32); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:78 + StorageLive(_9); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84 + _9 = _7; // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84 + StorageLive(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 + _10 = _8; // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 + _0 = BitXor(move _9, move _10); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:88 + StorageDead(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 + StorageDead(_9); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88 + StorageDead(_8); // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 + StorageDead(_7); // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 + goto -> bb10; // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88 + } + + bb10: { + return; // scope 0 at $DIR/exponential-or.rs:+5:2: +5:2 + } +} diff --git a/src/test/mir-opt/fn-ptr-shim.rs b/src/test/mir-opt/fn-ptr-shim.rs new file mode 100644 index 000000000..64fbdc9de --- /dev/null +++ b/src/test/mir-opt/fn-ptr-shim.rs @@ -0,0 +1,15 @@ +// compile-flags: -Zmir-opt-level=0 + +// Tests that the `<fn() as Fn>` shim does not create a `Call` terminator with a `Self` callee +// (as only `FnDef` and `FnPtr` callees are allowed in MIR). + +// EMIT_MIR core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir +fn main() { + call(noop as fn()); +} + +fn noop() {} + +fn call<F: Fn()>(f: F) { + f(); +} diff --git a/src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir b/src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir new file mode 100644 index 000000000..c63433d36 --- /dev/null +++ b/src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir @@ -0,0 +1,13 @@ +// MIR for `std::ops::Fn::call` before AddMovesForPackedDrops + +fn std::ops::Fn::call(_1: *const fn(), _2: ()) -> <fn() as FnOnce<()>>::Output { + let mut _0: <fn() as std::ops::FnOnce<()>>::Output; // return place in scope 0 at $SRC_DIR/core/src/ops/function.rs:+0:5: +0:67 + + bb0: { + _0 = move (*_1)() -> bb1; // scope 0 at $SRC_DIR/core/src/ops/function.rs:+0:5: +0:67 + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/ops/function.rs:+0:5: +0:67 + } +} diff --git a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff new file mode 100644 index 000000000..dca36b1a7 --- /dev/null +++ b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff @@ -0,0 +1,146 @@ +- // MIR for `float_to_exponential_common` before ConstProp ++ // MIR for `float_to_exponential_common` after ConstProp + + fn float_to_exponential_common(_1: &mut Formatter, _2: &T, _3: bool) -> Result<(), std::fmt::Error> { + debug fmt => _1; // in scope 0 at $DIR/funky_arms.rs:+0:35: +0:38 + debug num => _2; // in scope 0 at $DIR/funky_arms.rs:+0:60: +0:63 + debug upper => _3; // in scope 0 at $DIR/funky_arms.rs:+0:69: +0:74 + let mut _0: std::result::Result<(), std::fmt::Error>; // return place in scope 0 at $DIR/funky_arms.rs:+0:85: +0:91 + let _4: bool; // in scope 0 at $DIR/funky_arms.rs:+4:9: +4:19 + let mut _5: &std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:+4:22: +4:37 + let mut _7: std::option::Option<usize>; // in scope 0 at $DIR/funky_arms.rs:+13:30: +13:45 + let mut _8: &std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:+13:30: +13:45 + let mut _9: isize; // in scope 0 at $DIR/funky_arms.rs:+13:12: +13:27 + let mut _11: &mut std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:+15:43: +15:46 + let mut _12: &T; // in scope 0 at $DIR/funky_arms.rs:+15:48: +15:51 + let mut _13: core::num::flt2dec::Sign; // in scope 0 at $DIR/funky_arms.rs:+15:53: +15:57 + let mut _14: u32; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:79 + let mut _15: u32; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:75 + let mut _16: usize; // in scope 0 at $DIR/funky_arms.rs:+15:59: +15:68 + let mut _17: bool; // in scope 0 at $DIR/funky_arms.rs:+15:81: +15:86 + let mut _18: &mut std::fmt::Formatter; // in scope 0 at $DIR/funky_arms.rs:+17:46: +17:49 + let mut _19: &T; // in scope 0 at $DIR/funky_arms.rs:+17:51: +17:54 + let mut _20: core::num::flt2dec::Sign; // in scope 0 at $DIR/funky_arms.rs:+17:56: +17:60 + let mut _21: bool; // in scope 0 at $DIR/funky_arms.rs:+17:62: +17:67 + scope 1 { + debug force_sign => _4; // in scope 1 at $DIR/funky_arms.rs:+4:9: +4:19 + let _6: core::num::flt2dec::Sign; // in scope 1 at $DIR/funky_arms.rs:+8:9: +8:13 + scope 2 { + debug sign => _6; // in scope 2 at $DIR/funky_arms.rs:+8:9: +8:13 + scope 3 { + debug precision => _10; // in scope 3 at $DIR/funky_arms.rs:+13:17: +13:26 + let _10: usize; // in scope 3 at $DIR/funky_arms.rs:+13:17: +13:26 + } + } + } + + bb0: { + StorageLive(_4); // scope 0 at $DIR/funky_arms.rs:+4:9: +4:19 + StorageLive(_5); // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37 + _5 = &(*_1); // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37 + _4 = Formatter::sign_plus(move _5) -> bb1; // scope 0 at $DIR/funky_arms.rs:+4:22: +4:37 + // mir::Constant + // + span: $DIR/funky_arms.rs:15:26: 15:35 + // + literal: Const { ty: for<'r> fn(&'r Formatter) -> bool {Formatter::sign_plus}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_5); // scope 0 at $DIR/funky_arms.rs:+4:36: +4:37 + StorageLive(_6); // scope 1 at $DIR/funky_arms.rs:+8:9: +8:13 + switchInt(_4) -> [false: bb3, otherwise: bb2]; // scope 1 at $DIR/funky_arms.rs:+8:16: +8:32 + } + + bb2: { + Deinit(_6); // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41 + discriminant(_6) = 1; // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41 + goto -> bb4; // scope 1 at $DIR/funky_arms.rs:+10:17: +10:41 + } + + bb3: { + Deinit(_6); // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38 + discriminant(_6) = 0; // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38 + goto -> bb4; // scope 1 at $DIR/funky_arms.rs:+9:18: +9:38 + } + + bb4: { + StorageLive(_7); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45 + StorageLive(_8); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45 + _8 = &(*_1); // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45 + _7 = Formatter::precision(move _8) -> bb5; // scope 3 at $DIR/funky_arms.rs:+13:30: +13:45 + // mir::Constant + // + span: $DIR/funky_arms.rs:24:34: 24:43 + // + literal: Const { ty: for<'r> fn(&'r Formatter) -> Option<usize> {Formatter::precision}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_8); // scope 3 at $DIR/funky_arms.rs:+13:44: +13:45 + _9 = discriminant(_7); // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27 + switchInt(move _9) -> [1_isize: bb6, otherwise: bb8]; // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27 + } + + bb6: { + StorageLive(_10); // scope 3 at $DIR/funky_arms.rs:+13:17: +13:26 + _10 = ((_7 as Some).0: usize); // scope 3 at $DIR/funky_arms.rs:+13:17: +13:26 + StorageLive(_11); // scope 3 at $DIR/funky_arms.rs:+15:43: +15:46 + _11 = &mut (*_1); // scope 3 at $DIR/funky_arms.rs:+15:43: +15:46 + StorageLive(_12); // scope 3 at $DIR/funky_arms.rs:+15:48: +15:51 + _12 = _2; // scope 3 at $DIR/funky_arms.rs:+15:48: +15:51 + StorageLive(_13); // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57 + _13 = _6; // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57 + StorageLive(_14); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79 + StorageLive(_15); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75 + StorageLive(_16); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:68 + _16 = _10; // scope 3 at $DIR/funky_arms.rs:+15:59: +15:68 + _15 = move _16 as u32 (Misc); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75 + StorageDead(_16); // scope 3 at $DIR/funky_arms.rs:+15:74: +15:75 + _14 = Add(move _15, const 1_u32); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79 + StorageDead(_15); // scope 3 at $DIR/funky_arms.rs:+15:78: +15:79 + StorageLive(_17); // scope 3 at $DIR/funky_arms.rs:+15:81: +15:86 + _17 = _3; // scope 3 at $DIR/funky_arms.rs:+15:81: +15:86 + _0 = float_to_exponential_common_exact::<T>(move _11, move _12, move _13, move _14, move _17) -> bb7; // scope 3 at $DIR/funky_arms.rs:+15:9: +15:87 + // mir::Constant + // + span: $DIR/funky_arms.rs:26:9: 26:42 + // + literal: Const { ty: for<'r, 's, 't0> fn(&'r mut Formatter<'s>, &'t0 T, Sign, u32, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_exact::<T>}, val: Value(<ZST>) } + } + + bb7: { + StorageDead(_17); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 + StorageDead(_14); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 + StorageDead(_13); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 + StorageDead(_12); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 + StorageDead(_11); // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87 + StorageDead(_10); // scope 2 at $DIR/funky_arms.rs:+16:5: +16:6 + goto -> bb10; // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6 + } + + bb8: { + StorageLive(_18); // scope 2 at $DIR/funky_arms.rs:+17:46: +17:49 + _18 = &mut (*_1); // scope 2 at $DIR/funky_arms.rs:+17:46: +17:49 + StorageLive(_19); // scope 2 at $DIR/funky_arms.rs:+17:51: +17:54 + _19 = _2; // scope 2 at $DIR/funky_arms.rs:+17:51: +17:54 + StorageLive(_20); // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60 + _20 = _6; // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60 + StorageLive(_21); // scope 2 at $DIR/funky_arms.rs:+17:62: +17:67 + _21 = _3; // scope 2 at $DIR/funky_arms.rs:+17:62: +17:67 + _0 = float_to_exponential_common_shortest::<T>(move _18, move _19, move _20, move _21) -> bb9; // scope 2 at $DIR/funky_arms.rs:+17:9: +17:68 + // mir::Constant + // + span: $DIR/funky_arms.rs:28:9: 28:45 + // + literal: Const { ty: for<'r, 's, 't0> fn(&'r mut Formatter<'s>, &'t0 T, Sign, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_shortest::<T>}, val: Value(<ZST>) } + } + + bb9: { + StorageDead(_21); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68 + StorageDead(_20); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68 + StorageDead(_19); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68 + StorageDead(_18); // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68 + goto -> bb10; // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6 + } + + bb10: { + StorageDead(_6); // scope 1 at $DIR/funky_arms.rs:+19:1: +19:2 + StorageDead(_4); // scope 0 at $DIR/funky_arms.rs:+19:1: +19:2 + StorageDead(_7); // scope 0 at $DIR/funky_arms.rs:+19:1: +19:2 + return; // scope 0 at $DIR/funky_arms.rs:+19:2: +19:2 + } + } + diff --git a/src/test/mir-opt/funky_arms.rs b/src/test/mir-opt/funky_arms.rs new file mode 100644 index 000000000..3e70d85e0 --- /dev/null +++ b/src/test/mir-opt/funky_arms.rs @@ -0,0 +1,56 @@ +// compile-flags: --crate-type lib -Cdebug-assertions=no + +#![feature(flt2dec)] + +extern crate core; + +use core::num::flt2dec; +use std::fmt::{Formatter, Result}; + +// EMIT_MIR funky_arms.float_to_exponential_common.ConstProp.diff +fn float_to_exponential_common<T>(fmt: &mut Formatter<'_>, num: &T, upper: bool) -> Result +where + T: flt2dec::DecodableFloat, +{ + let force_sign = fmt.sign_plus(); + // A bug in const propagation (never reached master, but during dev of a PR) caused the + // `sign = Minus` assignment to get propagated into all future reads of `sign`. This is + // wrong because `sign` could also have `MinusPlus` value. + let sign = match force_sign { + false => flt2dec::Sign::Minus, + true => flt2dec::Sign::MinusPlus, + }; + + if let Some(precision) = fmt.precision() { + // 1 integral digit + `precision` fractional digits = `precision + 1` total digits + float_to_exponential_common_exact(fmt, num, sign, precision as u32 + 1, upper) + } else { + float_to_exponential_common_shortest(fmt, num, sign, upper) + } +} +#[inline(never)] +fn float_to_exponential_common_exact<T>( + fmt: &mut Formatter<'_>, + num: &T, + sign: flt2dec::Sign, + precision: u32, + upper: bool, +) -> Result +where + T: flt2dec::DecodableFloat, +{ + unimplemented!() +} + +#[inline(never)] +fn float_to_exponential_common_shortest<T>( + fmt: &mut Formatter<'_>, + num: &T, + sign: flt2dec::Sign, + upper: bool, +) -> Result +where + T: flt2dec::DecodableFloat, +{ + unimplemented!() +} diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator-drop-cleanup.rs new file mode 100644 index 000000000..82c1292cb --- /dev/null +++ b/src/test/mir-opt/generator-drop-cleanup.rs @@ -0,0 +1,14 @@ +#![feature(generators, generator_trait)] + +// ignore-wasm32-bare compiled with panic=abort by default + +// Regression test for #58892, generator drop shims should not have blocks +// spuriously marked as cleanup + +// EMIT_MIR generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir +fn main() { + let gen = || { + let _s = String::new(); + yield; + }; +} diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator-storage-dead-unwind.rs new file mode 100644 index 000000000..b72170ade --- /dev/null +++ b/src/test/mir-opt/generator-storage-dead-unwind.rs @@ -0,0 +1,29 @@ +// ignore-wasm32-bare compiled with panic=abort by default + +// Test that we generate StorageDead on unwind paths for generators. +// +// Basic block and local names can safely change, but the StorageDead statements +// should not go away. + +#![feature(generators, generator_trait)] + +struct Foo(i32); + +impl Drop for Foo { + fn drop(&mut self) {} +} + +struct Bar(i32); + +fn take<T>(_x: T) {} + +// EMIT_MIR generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir +fn main() { + let _gen = || { + let a = Foo(5); + let b = Bar(6); + yield; + take(a); + take(b); + }; +} diff --git a/src/test/mir-opt/generator-tiny.rs b/src/test/mir-opt/generator-tiny.rs new file mode 100644 index 000000000..7dad63a61 --- /dev/null +++ b/src/test/mir-opt/generator-tiny.rs @@ -0,0 +1,26 @@ +//! Tests that generators that cannot return or unwind don't have unnecessary +//! panic branches. + +// compile-flags: -C panic=abort +// no-prefer-dynamic + +#![feature(generators, generator_trait)] + +struct HasDrop; + +impl Drop for HasDrop { + fn drop(&mut self) {} +} + +fn callee() {} + +// EMIT_MIR generator_tiny.main-{closure#0}.generator_resume.0.mir +fn main() { + let _gen = |_x: u8| { + let _d = HasDrop; + loop { + yield; + callee(); + } + }; +} diff --git a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir new file mode 100644 index 000000000..09765c7b9 --- /dev/null +++ b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir @@ -0,0 +1,84 @@ +// MIR for `main::{closure#0}` 0 generator_drop +/* generator_layout = GeneratorLayout { + field_tys: { + _0: std::string::String, + }, + variant_fields: { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_0], + }, + storage_conflicts: BitMatrix(1x1) { + (_0, _0), + }, +} */ + +fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 10:17]) -> () { + let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + let mut _2: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + let _3: std::string::String; // in scope 0 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15 + let _4: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14 + let mut _5: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14 + let mut _6: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:18: +0:18 + let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + let mut _8: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + scope 1 { + debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15 + } + + bb0: { + _8 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/generator-drop-cleanup.rs:+2:13: +2:14 + StorageDead(_4); // scope 1 at $DIR/generator-drop-cleanup.rs:+2:14: +2:15 + drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + } + + bb2: { + nop; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + goto -> bb8; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + } + + bb3: { + return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + } + + bb5 (cleanup): { + nop; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + goto -> bb4; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + } + + bb6: { + return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + } + + bb7: { + goto -> bb9; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + } + + bb8: { + goto -> bb3; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6 + } + + bb9: { + goto -> bb6; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + } + + bb10: { + StorageLive(_4); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + StorageLive(_5); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + goto -> bb1; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + } + + bb11: { + return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +0:17 + } +} diff --git a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir new file mode 100644 index 000000000..cb6ed3321 --- /dev/null +++ b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir @@ -0,0 +1,114 @@ +// MIR for `main::{closure#0}` before StateTransform + +fn main::{closure#0}(_1: [generator@$DIR/generator-storage-dead-unwind.rs:22:16: 22:18], _2: ()) -> () +yields () + { + let mut _0: (); // return place in scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +0:19 + let _3: Foo; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14 + let _5: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 + let mut _6: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 + let _7: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16 + let mut _8: Foo; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15 + let _9: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16 + let mut _10: Bar; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15 + scope 1 { + debug a => _3; // in scope 1 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14 + let _4: Bar; // in scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14 + scope 2 { + debug b => _4; // in scope 2 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14 + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14 + Deinit(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23 + (_3.0: i32) = const 5_i32; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23 + StorageLive(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14 + Deinit(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23 + (_4.0: i32) = const 6_i32; // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23 + StorageLive(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 + StorageLive(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 + Deinit(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 + _5 = yield(move _6) -> [resume: bb1, drop: bb5]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14 + } + + bb1: { + StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14 + StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15 + StorageLive(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16 + StorageLive(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15 + _8 = move _3; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15 + _7 = take::<Foo>(move _8) -> [return: bb2, unwind: bb9]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16 + // mir::Constant + // + span: $DIR/generator-storage-dead-unwind.rs:26:9: 26:13 + // + literal: Const { ty: fn(Foo) {take::<Foo>}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16 + StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17 + StorageLive(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16 + StorageLive(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15 + _10 = move _4; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15 + _9 = take::<Bar>(move _10) -> [return: bb3, unwind: bb8]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16 + // mir::Constant + // + span: $DIR/generator-storage-dead-unwind.rs:27:9: 27:13 + // + literal: Const { ty: fn(Bar) {take::<Bar>}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16 + StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17 + _0 = const (); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +6:6 + StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + drop(_1) -> [return: bb4, unwind: bb11]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + } + + bb4: { + return; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:18: +0:18 + } + + bb5: { + StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14 + StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15 + StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + drop(_3) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + } + + bb6: { + StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + drop(_1) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + } + + bb7: { + generator_drop; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +0:18 + } + + bb8 (cleanup): { + StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16 + StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17 + goto -> bb10; // scope 2 at no-location + } + + bb9 (cleanup): { + StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16 + StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17 + goto -> bb10; // scope 2 at no-location + } + + bb10 (cleanup): { + StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + drop(_1) -> bb11; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + } + + bb11 (cleanup): { + resume; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +0:18 + } + + bb12 (cleanup): { + StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + drop(_1) -> bb11; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6 + } +} diff --git a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir new file mode 100644 index 000000000..62e7d7b2d --- /dev/null +++ b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir @@ -0,0 +1,84 @@ +// MIR for `main::{closure#0}` 0 generator_resume +/* generator_layout = GeneratorLayout { + field_tys: { + _0: HasDrop, + }, + variant_fields: { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_0], + }, + storage_conflicts: BitMatrix(1x1) { + (_0, _0), + }, +} */ + +fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]>, _2: u8) -> GeneratorState<(), ()> { + debug _x => _10; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19 + let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + let _3: HasDrop; // in scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15 + let mut _4: !; // in scope 0 at $DIR/generator-tiny.rs:+2:9: +5:10 + let mut _5: (); // in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + let _6: u8; // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18 + let mut _7: (); // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18 + let _8: (); // in scope 0 at $DIR/generator-tiny.rs:+4:13: +4:21 + let mut _9: (); // in scope 0 at $DIR/generator-tiny.rs:+0:25: +0:25 + let _10: u8; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19 + let mut _11: u32; // in scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + scope 1 { + debug _d => (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator-tiny.rs:+1:13: +1:15 + } + + bb0: { + _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + } + + bb1: { + _10 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + nop; // scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15 + Deinit((((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop)); // scope 0 at $DIR/generator-tiny.rs:+1:18: +1:25 + StorageLive(_4); // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10 + goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10 + } + + bb2: { + StorageLive(_6); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + StorageLive(_7); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + Deinit(_7); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + Deinit(_0); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + ((_0 as Yielded).0: ()) = move _7; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + discriminant(_0) = 0; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))) = 3; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + return; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18 + } + + bb3: { + StorageDead(_7); // scope 1 at $DIR/generator-tiny.rs:+3:17: +3:18 + StorageDead(_6); // scope 1 at $DIR/generator-tiny.rs:+3:18: +3:19 + StorageLive(_8); // scope 1 at $DIR/generator-tiny.rs:+4:13: +4:21 + _8 = callee() -> bb4; // scope 1 at $DIR/generator-tiny.rs:+4:13: +4:21 + // mir::Constant + // + span: $DIR/generator-tiny.rs:23:13: 23:19 + // + literal: Const { ty: fn() {callee}, val: Value(<ZST>) } + } + + bb4: { + StorageDead(_8); // scope 1 at $DIR/generator-tiny.rs:+4:21: +4:22 + _5 = const (); // scope 1 at $DIR/generator-tiny.rs:+2:14: +5:10 + goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10 + } + + bb5: { + StorageLive(_4); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + StorageLive(_6); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + StorageLive(_7); // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + _6 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + goto -> bb3; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + } + + bb6: { + unreachable; // scope 0 at $DIR/generator-tiny.rs:+0:16: +0:24 + } +} diff --git a/src/test/mir-opt/graphviz.main.mir_map.0.dot b/src/test/mir-opt/graphviz.main.mir_map.0.dot new file mode 100644 index 000000000..8d1da7f1b --- /dev/null +++ b/src/test/mir-opt/graphviz.main.mir_map.0.dot @@ -0,0 +1,7 @@ +digraph Mir_0_3 { + graph [fontname="Courier, monospace"]; + node [fontname="Courier, monospace"]; + edge [fontname="Courier, monospace"]; + label=<fn main() -> ()<br align="left"/>>; + bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = const ()<br/></td></tr><tr><td align="left">return</td></tr></table>>]; +} diff --git a/src/test/mir-opt/graphviz.rs b/src/test/mir-opt/graphviz.rs new file mode 100644 index 000000000..074dba2c3 --- /dev/null +++ b/src/test/mir-opt/graphviz.rs @@ -0,0 +1,5 @@ +// Test graphviz output +// compile-flags: -Z dump-mir-graphviz + +// EMIT_MIR graphviz.main.mir_map.0.dot +fn main() {} diff --git a/src/test/mir-opt/if-condition-int.rs b/src/test/mir-opt/if-condition-int.rs new file mode 100644 index 000000000..398311e6b --- /dev/null +++ b/src/test/mir-opt/if-condition-int.rs @@ -0,0 +1,65 @@ +// unit-test: SimplifyComparisonIntegral +// EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff +// EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff +// EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff +// EMIT_MIR if_condition_int.opt_i8.SimplifyComparisonIntegral.diff +// EMIT_MIR if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff +// EMIT_MIR if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff +// EMIT_MIR if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff +// EMIT_MIR if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff + +fn opt_u32(x: u32) -> u32 { + if x == 42 { 0 } else { 1 } +} + +// don't opt: it is already optimal to switch on the bool +fn dont_opt_bool(x: bool) -> u32 { + if x { 0 } else { 1 } +} + +fn opt_char(x: char) -> u32 { + if x == 'x' { 0 } else { 1 } +} + +fn opt_i8(x: i8) -> u32 { + if x == 42 { 0 } else { 1 } +} + +fn opt_negative(x: i32) -> u32 { + if x == -42 { 0 } else { 1 } +} + +fn opt_multiple_ifs(x: u32) -> u32 { + if x == 42 { + 0 + } else if x != 21 { + 1 + } else { + 2 + } +} + +// test that we optimize, but do not remove the b statement, as that is used later on +fn dont_remove_comparison(a: i8) -> i32 { + let b = a == 17; + match b { + false => 10 + b as i32, + true => 100 + b as i32, + } +} + +// test that we do not optimize on floats +fn dont_opt_floats(a: f32) -> i32 { + if a == -42.0 { 0 } else { 1 } +} + +fn main() { + opt_u32(0); + opt_char('0'); + opt_i8(22); + dont_opt_bool(false); + opt_negative(0); + opt_multiple_ifs(0); + dont_remove_comparison(11); + dont_opt_floats(1.0); +} diff --git a/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..19b5ab441 --- /dev/null +++ b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff @@ -0,0 +1,30 @@ +- // MIR for `dont_opt_bool` before SimplifyComparisonIntegral ++ // MIR for `dont_opt_bool` after SimplifyComparisonIntegral + + fn dont_opt_bool(_1: bool) -> u32 { + debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:18: +0:19 + let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:30: +0:33 + let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + _2 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + } + + bb1: { + _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:12: +1:13 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:26 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:23: +1:24 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:26 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:25: +1:26 + return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..256af7b94 --- /dev/null +++ b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff @@ -0,0 +1,34 @@ +- // MIR for `dont_opt_floats` before SimplifyComparisonIntegral ++ // MIR for `dont_opt_floats` after SimplifyComparisonIntegral + + fn dont_opt_floats(_1: f32) -> i32 { + debug a => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:20: +0:21 + let mut _0: i32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:31: +0:34 + let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18 + let mut _3: f32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18 + StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + _2 = Eq(move _3, const -42f32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18 + StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:17: +1:18 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18 + } + + bb1: { + _0 = const 0_i32; // scope 0 at $DIR/if-condition-int.rs:+1:21: +1:22 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:35 + } + + bb2: { + _0 = const 1_i32; // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:35 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:34: +1:35 + return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..3f612e03f --- /dev/null +++ b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff @@ -0,0 +1,58 @@ +- // MIR for `dont_remove_comparison` before SimplifyComparisonIntegral ++ // MIR for `dont_remove_comparison` after SimplifyComparisonIntegral + + fn dont_remove_comparison(_1: i8) -> i32 { + debug a => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:27: +0:28 + let mut _0: i32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:37: +0:40 + let _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:9: +1:10 + let mut _3: i8; // in scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14 + let mut _4: i32; // in scope 0 at $DIR/if-condition-int.rs:+3:23: +3:31 + let mut _5: bool; // in scope 0 at $DIR/if-condition-int.rs:+3:23: +3:24 + let mut _6: i32; // in scope 0 at $DIR/if-condition-int.rs:+4:23: +4:31 + let mut _7: bool; // in scope 0 at $DIR/if-condition-int.rs:+4:23: +4:24 + scope 1 { + debug b => _2; // in scope 1 at $DIR/if-condition-int.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14 + _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14 +- _2 = Eq(move _3, const 17_i8); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:20 +- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20 +- switchInt(_2) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12 ++ _2 = Eq(_3, const 17_i8); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:20 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20 ++ switchInt(move _3) -> [17_i8: bb1, otherwise: bb2]; // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12 + } + + bb1: { ++ StorageDead(_3); // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12 + StorageLive(_6); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:31 + StorageLive(_7); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:24 + _7 = _2; // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:24 + _6 = move _7 as i32 (Misc); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:31 + StorageDead(_7); // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31 + _0 = Add(const 100_i32, move _6); // scope 1 at $DIR/if-condition-int.rs:+4:17: +4:31 + StorageDead(_6); // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31 + goto -> bb3; // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31 + } + + bb2: { ++ StorageDead(_3); // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12 + StorageLive(_4); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:31 + StorageLive(_5); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:24 + _5 = _2; // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:24 + _4 = move _5 as i32 (Misc); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:31 + StorageDead(_5); // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31 + _0 = Add(const 10_i32, move _4); // scope 1 at $DIR/if-condition-int.rs:+3:18: +3:31 + StorageDead(_4); // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31 + goto -> bb3; // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+6:1: +6:2 + return; // scope 0 at $DIR/if-condition-int.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..9b64c379f --- /dev/null +++ b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff @@ -0,0 +1,39 @@ +- // MIR for `opt_char` before SimplifyComparisonIntegral ++ // MIR for `opt_char` after SimplifyComparisonIntegral + + fn opt_char(_1: char) -> u32 { + debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:13: +0:14 + let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:25: +0:28 + let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + let mut _3: char; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const 'x'); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 +- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16 ++ switchInt(move _3) -> ['x': bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + } + + bb1: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33 + } + + bb2: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:30: +1:31 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33 + return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..8042d63bb --- /dev/null +++ b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff @@ -0,0 +1,39 @@ +- // MIR for `opt_i8` before SimplifyComparisonIntegral ++ // MIR for `opt_i8` after SimplifyComparisonIntegral + + fn opt_i8(_1: i8) -> u32 { + debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:11: +0:12 + let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + let mut _3: i8; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const 42_i8); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 +- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 ++ switchInt(move _3) -> [42_i8: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + } + + bb1: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:18: +1:19 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32 + } + + bb2: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:29: +1:30 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:31: +1:32 + return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..a408de1ef --- /dev/null +++ b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff @@ -0,0 +1,65 @@ +- // MIR for `opt_multiple_ifs` before SimplifyComparisonIntegral ++ // MIR for `opt_multiple_ifs` after SimplifyComparisonIntegral + + fn opt_multiple_ifs(_1: u32) -> u32 { + debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:21: +0:22 + let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:32: +0:35 + let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + let mut _3: u32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + let mut _4: bool; // in scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 + let mut _5: u32; // in scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 +- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 ++ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + } + + bb1: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+2:9: +2:10 + goto -> bb6; // scope 0 at $DIR/if-condition-int.rs:+1:5: +7:6 + } + + bb2: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + StorageLive(_4); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 + StorageLive(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16 + _5 = _1; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16 +- _4 = Ne(move _5, const 21_u32); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 +- StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:21: +3:22 +- switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+3:21: +3:22 ++ switchInt(move _5) -> [21_u32: bb4, otherwise: bb3]; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 + } + + bb3: { ++ StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 + _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+4:9: +4:10 + goto -> bb5; // scope 0 at $DIR/if-condition-int.rs:+3:12: +7:6 + } + + bb4: { ++ StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22 + _0 = const 2_u32; // scope 0 at $DIR/if-condition-int.rs:+6:9: +6:10 + goto -> bb5; // scope 0 at $DIR/if-condition-int.rs:+3:12: +7:6 + } + + bb5: { + StorageDead(_4); // scope 0 at $DIR/if-condition-int.rs:+7:5: +7:6 + goto -> bb6; // scope 0 at $DIR/if-condition-int.rs:+1:5: +7:6 + } + + bb6: { + StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+7:5: +7:6 + return; // scope 0 at $DIR/if-condition-int.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..6802f89d9 --- /dev/null +++ b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff @@ -0,0 +1,39 @@ +- // MIR for `opt_negative` before SimplifyComparisonIntegral ++ // MIR for `opt_negative` after SimplifyComparisonIntegral + + fn opt_negative(_1: i32) -> u32 { + debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:17: +0:18 + let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:28: +0:31 + let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + let mut _3: i32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const -42_i32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 +- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16 ++ switchInt(move _3) -> [-42_i32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + } + + bb1: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33 + } + + bb2: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16 + _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:30: +1:31 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33 + return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..96387771d --- /dev/null +++ b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff @@ -0,0 +1,39 @@ +- // MIR for `opt_u32` before SimplifyComparisonIntegral ++ // MIR for `opt_u32` after SimplifyComparisonIntegral + + fn opt_u32(_1: u32) -> u32 { + debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:12: +0:13 + let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:23: +0:26 + let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + let mut _3: u32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9 +- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 +- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 ++ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15 ++ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + } + + bb1: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:18: +1:19 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32 + } + + bb2: { ++ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15 + _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:29: +1:30 + goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:31: +1:32 + return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/caller-with-trivial-bound.rs b/src/test/mir-opt/inline/caller-with-trivial-bound.rs new file mode 100644 index 000000000..8545db894 --- /dev/null +++ b/src/test/mir-opt/inline/caller-with-trivial-bound.rs @@ -0,0 +1,26 @@ +// ignore-wasm32 compiled with panic=abort by default +// needs-unwind + +#![crate_type = "lib"] +pub trait Factory<T> { + type Item; +} + +pub struct IntFactory; + +impl<T> Factory<T> for IntFactory { + type Item = usize; +} + +// EMIT_MIR caller_with_trivial_bound.foo.Inline.diff +pub fn foo<T>() +where + IntFactory: Factory<T>, +{ + let mut x: <IntFactory as Factory<T>>::Item = bar::<T>(); +} + +#[inline(always)] +pub fn bar<T>() -> <IntFactory as Factory<T>>::Item { + 0usize +} diff --git a/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff b/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff new file mode 100644 index 000000000..d7deb9c66 --- /dev/null +++ b/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff @@ -0,0 +1,33 @@ +- // MIR for `foo` before Inline ++ // MIR for `foo` after Inline + + fn foo() -> () { + let mut _0: (); // return place in scope 0 at $DIR/caller-with-trivial-bound.rs:+1:1: +1:1 + let mut _1: <IntFactory as Factory<T>>::Item; // in scope 0 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14 + scope 1 { + debug x => _1; // in scope 1 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14 + _1 = bar::<T>() -> bb1; // scope 0 at $DIR/caller-with-trivial-bound.rs:+4:51: +4:61 + // mir::Constant + // + span: $DIR/caller-with-trivial-bound.rs:20:51: 20:59 + // + literal: Const { ty: fn() -> <IntFactory as Factory<T>>::Item {bar::<T>}, val: Value(<ZST>) } + } + + bb1: { + _0 = const (); // scope 0 at $DIR/caller-with-trivial-bound.rs:+3:1: +5:2 + drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:1: +5:2 + } + + bb2: { + StorageDead(_1); // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:1: +5:2 + return; // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:2: +5:2 + } + + bb3 (cleanup): { + resume; // scope 0 at $DIR/caller-with-trivial-bound.rs:+0:1: +5:2 + } + } + diff --git a/src/test/mir-opt/inline/cycle.f.Inline.diff b/src/test/mir-opt/inline/cycle.f.Inline.diff new file mode 100644 index 000000000..40fdd1cdb --- /dev/null +++ b/src/test/mir-opt/inline/cycle.f.Inline.diff @@ -0,0 +1,43 @@ +- // MIR for `f` before Inline ++ // MIR for `f` after Inline + + fn f(_1: impl Fn()) -> () { + debug g => _1; // in scope 0 at $DIR/cycle.rs:+0:6: +0:7 + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:20: +0:20 + let _2: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:8 + let mut _3: &impl Fn(); // in scope 0 at $DIR/cycle.rs:+1:5: +1:6 + let mut _4: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:8 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:8 + StorageLive(_3); // scope 0 at $DIR/cycle.rs:+1:5: +1:6 + _3 = &_1; // scope 0 at $DIR/cycle.rs:+1:5: +1:6 + StorageLive(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:8 + Deinit(_4); // scope 0 at $DIR/cycle.rs:+1:5: +1:8 + _2 = <impl Fn() as Fn<()>>::call(move _3, move _4) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/cycle.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/cycle.rs:6:5: 6:6 + // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_4); // scope 0 at $DIR/cycle.rs:+1:7: +1:8 + StorageDead(_3); // scope 0 at $DIR/cycle.rs:+1:7: +1:8 + StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:8: +1:9 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:20: +2:2 + drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/cycle.rs:+2:1: +2:2 + } + + bb2: { + return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2 + } + + bb3 (cleanup): { + drop(_1) -> bb4; // scope 0 at $DIR/cycle.rs:+2:1: +2:2 + } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/cycle.rs:+0:1: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/cycle.g.Inline.diff b/src/test/mir-opt/inline/cycle.g.Inline.diff new file mode 100644 index 000000000..59f34d379 --- /dev/null +++ b/src/test/mir-opt/inline/cycle.g.Inline.diff @@ -0,0 +1,57 @@ +- // MIR for `g` before Inline ++ // MIR for `g` after Inline + + fn g() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:8: +0:8 + let _1: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ let mut _2: fn() {main}; // in scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ scope 1 (inlined f::<fn() {main}>) { // at $DIR/cycle.rs:12:5: 12:12 ++ debug g => _2; // in scope 1 at $DIR/cycle.rs:+0:6: +0:7 ++ let _3: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8 ++ let mut _4: &fn() {main}; // in scope 1 at $DIR/cycle.rs:+0:5: +0:6 ++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8 ++ scope 2 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8 ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:5: +1:12 +- _1 = f::<fn() {main}>(main) -> bb1; // scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:12 ++ _2 = main; // scope 0 at $DIR/cycle.rs:+1:5: +1:12 + // mir::Constant +- // + span: $DIR/cycle.rs:12:5: 12:6 +- // + literal: Const { ty: fn(fn() {main}) {f::<fn() {main}>}, val: Value(<ZST>) } +- // mir::Constant + // + span: $DIR/cycle.rs:12:7: 12:11 + // + literal: Const { ty: fn() {main}, val: Value(<ZST>) } ++ StorageLive(_3); // scope 1 at $DIR/cycle.rs:+0:5: +0:8 ++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:+0:5: +0:6 ++ _4 = &_2; // scope 1 at $DIR/cycle.rs:+0:5: +0:6 ++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:+0:5: +0:8 ++ _3 = move (*_4)() -> [return: bb4, unwind: bb2]; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL + } + + bb1: { ++ StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:12 + StorageDead(_1); // scope 0 at $DIR/cycle.rs:+1:12: +1:13 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:8: +2:2 + return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2 ++ } ++ ++ bb2 (cleanup): { ++ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:+0:1: +0:2 ++ } ++ ++ bb3 (cleanup): { ++ resume; // scope 1 at $DIR/cycle.rs:+0:1: +0:2 ++ } ++ ++ bb4: { ++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:+0:7: +0:8 ++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:+0:7: +0:8 ++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:+0:8: +0:9 ++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:+0:1: +0:2 + } + } + diff --git a/src/test/mir-opt/inline/cycle.main.Inline.diff b/src/test/mir-opt/inline/cycle.main.Inline.diff new file mode 100644 index 000000000..6def7c3ee --- /dev/null +++ b/src/test/mir-opt/inline/cycle.main.Inline.diff @@ -0,0 +1,74 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ let mut _2: fn() {g}; // in scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ scope 1 (inlined f::<fn() {g}>) { // at $DIR/cycle.rs:17:5: 17:9 ++ debug g => _2; // in scope 1 at $DIR/cycle.rs:+0:6: +0:7 ++ let _3: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8 ++ let mut _4: &fn() {g}; // in scope 1 at $DIR/cycle.rs:+0:5: +0:6 ++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:+0:5: +0:8 ++ scope 2 (inlined <fn() {g} as Fn<()>>::call - shim(fn() {g})) { // at $DIR/cycle.rs:6:5: 6:8 ++ scope 3 (inlined g) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ let mut _6: fn() {main}; // in scope 3 at $DIR/cycle.rs:+0:5: +0:12 ++ scope 4 (inlined f::<fn() {main}>) { // at $DIR/cycle.rs:12:5: 12:12 ++ debug g => _6; // in scope 4 at $DIR/cycle.rs:+0:6: +0:7 ++ let _7: (); // in scope 4 at $DIR/cycle.rs:+0:5: +0:8 ++ let mut _8: &fn() {main}; // in scope 4 at $DIR/cycle.rs:+0:5: +0:6 ++ scope 5 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8 ++ } ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:5: +1:9 +- _1 = f::<fn() {g}>(g) -> bb1; // scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ StorageLive(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:9 ++ _2 = g; // scope 0 at $DIR/cycle.rs:+1:5: +1:9 + // mir::Constant +- // + span: $DIR/cycle.rs:17:5: 17:6 +- // + literal: Const { ty: fn(fn() {g}) {f::<fn() {g}>}, val: Value(<ZST>) } +- // mir::Constant + // + span: $DIR/cycle.rs:17:7: 17:8 + // + literal: Const { ty: fn() {g}, val: Value(<ZST>) } ++ StorageLive(_3); // scope 1 at $DIR/cycle.rs:+0:5: +0:8 ++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:+0:5: +0:6 ++ _4 = &_2; // scope 1 at $DIR/cycle.rs:+0:5: +0:6 ++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:+0:5: +0:8 ++ StorageLive(_6); // scope 3 at $DIR/cycle.rs:+0:5: +0:12 ++ StorageLive(_7); // scope 4 at $DIR/cycle.rs:+0:5: +0:8 ++ StorageLive(_8); // scope 4 at $DIR/cycle.rs:+0:5: +0:6 ++ _8 = &_6; // scope 4 at $DIR/cycle.rs:+0:5: +0:6 ++ _7 = move (*_8)() -> [return: bb4, unwind: bb2]; // scope 5 at $SRC_DIR/core/src/ops/function.rs:LL:COL + } + + bb1: { ++ StorageDead(_2); // scope 0 at $DIR/cycle.rs:+1:5: +1:9 + StorageDead(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:10 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +2:2 + return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2 ++ } ++ ++ bb2 (cleanup): { ++ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:+0:1: +0:2 ++ } ++ ++ bb3 (cleanup): { ++ resume; // scope 1 at $DIR/cycle.rs:+0:1: +0:2 ++ } ++ ++ bb4: { ++ StorageDead(_8); // scope 4 at $DIR/cycle.rs:+0:7: +0:8 ++ StorageDead(_7); // scope 4 at $DIR/cycle.rs:+0:8: +0:9 ++ StorageDead(_6); // scope 3 at $DIR/cycle.rs:+0:5: +0:12 ++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:+0:7: +0:8 ++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:+0:7: +0:8 ++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:+0:8: +0:9 ++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:+0:1: +0:2 + } + } + diff --git a/src/test/mir-opt/inline/cycle.rs b/src/test/mir-opt/inline/cycle.rs new file mode 100644 index 000000000..9e8950d8a --- /dev/null +++ b/src/test/mir-opt/inline/cycle.rs @@ -0,0 +1,18 @@ +// ignore-wasm32-bare compiled with panic=abort by default + +// EMIT_MIR cycle.f.Inline.diff +#[inline(always)] +fn f(g: impl Fn()) { + g(); +} + +// EMIT_MIR cycle.g.Inline.diff +#[inline(always)] +fn g() { + f(main); +} + +// EMIT_MIR cycle.main.Inline.diff +fn main() { + f(g); +} diff --git a/src/test/mir-opt/inline/dyn-trait.rs b/src/test/mir-opt/inline/dyn-trait.rs new file mode 100644 index 000000000..6a46e1e07 --- /dev/null +++ b/src/test/mir-opt/inline/dyn-trait.rs @@ -0,0 +1,35 @@ +#![crate_type = "lib"] + +use std::fmt::Debug; + +pub trait Cache { + type V: Debug; + + fn store_nocache(&self); +} + +pub trait Query { + type V; + type C: Cache<V = Self::V>; + + fn cache<T>(s: &T) -> &Self::C; +} + +// EMIT_MIR dyn_trait.mk_cycle.Inline.diff +#[inline(always)] +pub fn mk_cycle<V: Debug>(c: &dyn Cache<V = V>) { + c.store_nocache() +} + +// EMIT_MIR dyn_trait.try_execute_query.Inline.diff +#[inline(always)] +pub fn try_execute_query<C: Cache>(c: &C) { + mk_cycle(c) +} + +// EMIT_MIR dyn_trait.get_query.Inline.diff +#[inline(always)] +pub fn get_query<Q: Query, T>(t: &T) { + let c = Q::cache(t); + try_execute_query(c) +} diff --git a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff new file mode 100644 index 000000000..8eae04c4d --- /dev/null +++ b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff @@ -0,0 +1,62 @@ +- // MIR for `get_query` before Inline ++ // MIR for `get_query` after Inline + + fn get_query(_1: &T) -> () { + debug t => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:31: +0:32 + let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:38: +0:38 + let _2: &<Q as Query>::C; // in scope 0 at $DIR/dyn-trait.rs:+1:9: +1:10 + let mut _3: &T; // in scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23 + let mut _4: &<Q as Query>::C; // in scope 0 at $DIR/dyn-trait.rs:+2:23: +2:24 + scope 1 { + debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:+1:9: +1:10 ++ scope 2 (inlined try_execute_query::<<Q as Query>::C>) { // at $DIR/dyn-trait.rs:34:5: 34:25 ++ debug c => _4; // in scope 2 at $DIR/dyn-trait.rs:+0:36: +0:37 ++ let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15 ++ let mut _6: &<Q as Query>::C; // in scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15 ++ scope 3 (inlined mk_cycle::<<Q as Query>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16 ++ debug c => _5; // in scope 3 at $DIR/dyn-trait.rs:+0:27: +0:28 ++ let mut _7: &dyn Cache<V = <Q as Query>::V>; // in scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22 ++ } ++ } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23 + _3 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23 + _2 = <Q as Query>::cache::<T>(move _3) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:13: +1:24 + // mir::Constant + // + span: $DIR/dyn-trait.rs:33:13: 33:21 + // + user_ty: UserType(0) + // + literal: Const { ty: for<'r> fn(&'r T) -> &'r <Q as Query>::C {<Q as Query>::cache::<T>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:23: +1:24 + StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24 + _4 = &(*_2); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24 +- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> bb2; // scope 1 at $DIR/dyn-trait.rs:+2:5: +2:25 ++ StorageLive(_5); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15 ++ StorageLive(_6); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15 ++ _6 = _4; // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15 ++ _5 = move _6 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15 ++ StorageDead(_6); // scope 2 at $DIR/dyn-trait.rs:+0:14: +0:15 ++ StorageLive(_7); // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22 ++ _7 = _5; // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22 ++ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _7) -> bb2; // scope 3 at $DIR/dyn-trait.rs:+0:5: +0:22 + // mir::Constant +- // + span: $DIR/dyn-trait.rs:34:5: 34:22 +- // + literal: Const { ty: for<'r> fn(&'r <Q as Query>::C) {try_execute_query::<<Q as Query>::C>}, val: Value(<ZST>) } ++ // + span: $DIR/dyn-trait.rs:21:7: 21:20 ++ // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = <Q as Query>::V>) {<dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache}, val: Value(<ZST>) } + } + + bb2: { ++ StorageDead(_7); // scope 3 at $DIR/dyn-trait.rs:+0:21: +0:22 ++ StorageDead(_5); // scope 2 at $DIR/dyn-trait.rs:+0:15: +0:16 + StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:+2:24: +2:25 + StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+3:1: +3:2 + return; // scope 0 at $DIR/dyn-trait.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff new file mode 100644 index 000000000..994930ef4 --- /dev/null +++ b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff @@ -0,0 +1,23 @@ +- // MIR for `mk_cycle` before Inline ++ // MIR for `mk_cycle` after Inline + + fn mk_cycle(_1: &dyn Cache<V = V>) -> () { + debug c => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:27: +0:28 + let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:49: +0:49 + let mut _2: &dyn Cache<V = V>; // in scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22 + _2 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22 + _0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22 + // mir::Constant + // + span: $DIR/dyn-trait.rs:21:7: 21:20 + // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = V>) {<dyn Cache<V = V> as Cache>::store_nocache}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:21: +1:22 + return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff new file mode 100644 index 000000000..e7c5972f4 --- /dev/null +++ b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff @@ -0,0 +1,37 @@ +- // MIR for `try_execute_query` before Inline ++ // MIR for `try_execute_query` after Inline + + fn try_execute_query(_1: &C) -> () { + debug c => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:36: +0:37 + let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:43: +0:43 + let mut _2: &dyn Cache<V = <C as Cache>::V>; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 + let mut _3: &C; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 ++ scope 1 (inlined mk_cycle::<<C as Cache>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16 ++ debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:+0:27: +0:28 ++ let mut _4: &dyn Cache<V = <C as Cache>::V>; // in scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 + StorageLive(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 + _3 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 + _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 + StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15 +- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:16 ++ StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22 ++ _4 = _2; // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22 ++ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _4) -> bb1; // scope 1 at $DIR/dyn-trait.rs:+0:5: +0:22 + // mir::Constant +- // + span: $DIR/dyn-trait.rs:27:5: 27:13 +- // + literal: Const { ty: for<'r> fn(&'r (dyn Cache<V = <C as Cache>::V> + 'r)) {mk_cycle::<<C as Cache>::V>}, val: Value(<ZST>) } ++ // + span: $DIR/dyn-trait.rs:21:7: 21:20 ++ // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = <C as Cache>::V>) {<dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache}, val: Value(<ZST>) } + } + + bb1: { ++ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:+0:21: +0:22 + StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:15: +1:16 + return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline-any-operand.rs b/src/test/mir-opt/inline/inline-any-operand.rs new file mode 100644 index 000000000..fb0de020f --- /dev/null +++ b/src/test/mir-opt/inline/inline-any-operand.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z span_free_formats + +// Tests that MIR inliner works for any operand + +fn main() { + println!("{}", bar()); +} + +// EMIT_MIR inline_any_operand.bar.Inline.after.mir +fn bar() -> bool { + let f = foo; + f(1, -1) +} + +#[inline(always)] +fn foo(x: i32, y: i32) -> bool { + x == y +} diff --git a/src/test/mir-opt/inline/inline-async.rs b/src/test/mir-opt/inline/inline-async.rs new file mode 100644 index 000000000..5c838159b --- /dev/null +++ b/src/test/mir-opt/inline/inline-async.rs @@ -0,0 +1,18 @@ +// Checks that inliner doesn't introduce cycles when optimizing generators. +// The outcome of optimization is not verfied, just the absence of the cycle. +// Regression test for #76181. +// +// edition:2018 + +#![crate_type = "lib"] + +pub struct S; + +impl S { + pub async fn g(&mut self) { + self.h(); + } + pub fn h(&mut self) { + let _ = self.g(); + } +} diff --git a/src/test/mir-opt/inline/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline/inline-closure-borrows-arg.rs new file mode 100644 index 000000000..d76bc33f5 --- /dev/null +++ b/src/test/mir-opt/inline/inline-closure-borrows-arg.rs @@ -0,0 +1,17 @@ +// compile-flags: -Z span_free_formats -Zunsound-mir-opts + +// Tests that MIR inliner can handle closure arguments, +// even when (#45894) + +fn main() { + println!("{}", foo(0, &14)); +} + +// EMIT_MIR inline_closure_borrows_arg.foo.Inline.after.mir +fn foo<T: Copy>(_t: T, q: &i32) -> i32 { + let x = |r: &i32, _s: &i32| { + let variable = &*r; + *variable + }; + x(q, q) +} diff --git a/src/test/mir-opt/inline/inline-closure-captures.rs b/src/test/mir-opt/inline/inline-closure-captures.rs new file mode 100644 index 000000000..52b6817e4 --- /dev/null +++ b/src/test/mir-opt/inline/inline-closure-captures.rs @@ -0,0 +1,13 @@ +// compile-flags: -Z span_free_formats + +// Tests that MIR inliner can handle closure captures. + +fn main() { + println!("{:?}", foo(0, 14)); +} + +// EMIT_MIR inline_closure_captures.foo.Inline.after.mir +fn foo<T: Copy>(t: T, q: i32) -> (i32, T) { + let x = |_q| (q, t); + x(q) +} diff --git a/src/test/mir-opt/inline/inline-closure.rs b/src/test/mir-opt/inline/inline-closure.rs new file mode 100644 index 000000000..715fd0138 --- /dev/null +++ b/src/test/mir-opt/inline/inline-closure.rs @@ -0,0 +1,13 @@ +// compile-flags: -Z span_free_formats + +// Tests that MIR inliner can handle closure arguments. (#45894) + +fn main() { + println!("{}", foo(0, 14)); +} + +// EMIT_MIR inline_closure.foo.Inline.after.mir +fn foo<T: Copy>(_t: T, q: i32) -> i32 { + let x = |_t, _q| _t; + x(q, q) +} diff --git a/src/test/mir-opt/inline/inline-compatibility.rs b/src/test/mir-opt/inline/inline-compatibility.rs new file mode 100644 index 000000000..30aff0a64 --- /dev/null +++ b/src/test/mir-opt/inline/inline-compatibility.rs @@ -0,0 +1,55 @@ +// Checks that only functions with compatible attributes are inlined. +// +// only-x86_64 + +#![crate_type = "lib"] +#![feature(no_sanitize)] +#![feature(target_feature_11)] +#![feature(c_variadic)] + +// EMIT_MIR inline_compatibility.inlined_target_feature.Inline.diff +#[target_feature(enable = "sse2")] +pub unsafe fn inlined_target_feature() { + target_feature(); +} + +// EMIT_MIR inline_compatibility.not_inlined_target_feature.Inline.diff +pub unsafe fn not_inlined_target_feature() { + target_feature(); +} + +// EMIT_MIR inline_compatibility.inlined_no_sanitize.Inline.diff +#[no_sanitize(address)] +pub unsafe fn inlined_no_sanitize() { + no_sanitize(); +} + +// EMIT_MIR inline_compatibility.not_inlined_no_sanitize.Inline.diff +pub unsafe fn not_inlined_no_sanitize() { + no_sanitize(); +} + +#[inline] +#[target_feature(enable = "sse2")] +pub unsafe fn target_feature() {} + +#[inline] +#[no_sanitize(address)] +pub unsafe fn no_sanitize() {} + +// EMIT_MIR inline_compatibility.not_inlined_c_variadic.Inline.diff +pub unsafe fn not_inlined_c_variadic() { + let s = sum(4u32, 4u32, 30u32, 200u32, 1000u32); +} + +#[no_mangle] +#[inline(always)] +unsafe extern "C" fn sum(n: u32, mut vs: ...) -> u32 { + let mut s = 0; + let mut i = 0; + while i != n { + s += vs.arg::<u32>(); + i += 1; + } + s +} diff --git a/src/test/mir-opt/inline/inline-cycle-generic.rs b/src/test/mir-opt/inline/inline-cycle-generic.rs new file mode 100644 index 000000000..24b4f3793 --- /dev/null +++ b/src/test/mir-opt/inline/inline-cycle-generic.rs @@ -0,0 +1,40 @@ +// Check that inliner handles various forms of recursion and doesn't fall into +// an infinite inlining cycle. The particular outcome of inlining is not +// crucial otherwise. +// +// Regression test for issue #78573. + +// EMIT_MIR inline_cycle_generic.main.Inline.diff +fn main() { + <C as Call>::call(); +} + +pub trait Call { + fn call(); +} + +pub struct A; +pub struct B<T>(T); +pub struct C; + +impl Call for A { + #[inline] + fn call() { + <B<C> as Call>::call() + } +} + + +impl<T: Call> Call for B<T> { + #[inline] + fn call() { + <T as Call>::call() + } +} + +impl Call for C { + #[inline] + fn call() { + <B<A> as Call>::call() + } +} diff --git a/src/test/mir-opt/inline/inline-cycle.rs b/src/test/mir-opt/inline/inline-cycle.rs new file mode 100644 index 000000000..63ad57de1 --- /dev/null +++ b/src/test/mir-opt/inline/inline-cycle.rs @@ -0,0 +1,60 @@ +// Check that inliner handles various forms of recursion and doesn't fall into +// an infinite inlining cycle. The particular outcome of inlining is not +// crucial otherwise. +// +// Regression test for issue #78573. + +fn main() { + one(); + two(); +} + +// EMIT_MIR inline_cycle.one.Inline.diff +fn one() { + <C as Call>::call(); +} + +pub trait Call { + fn call(); +} + +pub struct A<T>(T); +pub struct B<T>(T); +pub struct C; + +impl<T: Call> Call for A<T> { + #[inline] + fn call() { + <B<T> as Call>::call() + } +} + + +impl<T: Call> Call for B<T> { + #[inline] + fn call() { + <T as Call>::call() + } +} + +impl Call for C { + #[inline] + fn call() { + A::<C>::call() + } +} + +// EMIT_MIR inline_cycle.two.Inline.diff +fn two() { + call(f); +} + +#[inline] +fn call<F: FnOnce()>(f: F) { + f(); +} + +#[inline] +fn f() { + call(f); +} diff --git a/src/test/mir-opt/inline/inline-diverging.rs b/src/test/mir-opt/inline/inline-diverging.rs new file mode 100644 index 000000000..ae6f814c2 --- /dev/null +++ b/src/test/mir-opt/inline/inline-diverging.rs @@ -0,0 +1,40 @@ +// Tests inlining of diverging calls. +// +// ignore-wasm32-bare compiled with panic=abort by default +#![crate_type = "lib"] + +// EMIT_MIR inline_diverging.f.Inline.diff +pub fn f() { + sleep(); +} + +// EMIT_MIR inline_diverging.g.Inline.diff +pub fn g(i: i32) -> u32 { + if i > 0 { + i as u32 + } else { + panic(); + } +} + +// EMIT_MIR inline_diverging.h.Inline.diff +pub fn h() { + call_twice(sleep); +} + +#[inline(always)] +pub fn call_twice<R, F: Fn() -> R>(f: F) -> (R, R) { + let a = f(); + let b = f(); + (a, b) +} + +#[inline(always)] +fn panic() -> ! { + panic!(); +} + +#[inline(always)] +fn sleep() -> ! { + loop {} +} diff --git a/src/test/mir-opt/inline/inline-generator.rs b/src/test/mir-opt/inline/inline-generator.rs new file mode 100644 index 000000000..d11b3e548 --- /dev/null +++ b/src/test/mir-opt/inline/inline-generator.rs @@ -0,0 +1,16 @@ +// ignore-wasm32-bare compiled with panic=abort by default +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::pin::Pin; + +// EMIT_MIR inline_generator.main.Inline.diff +fn main() { + let _r = Pin::new(&mut g()).resume(false); +} + +#[inline(always)] +pub fn g() -> impl Generator<bool> { + #[inline(always)] + |a| { yield if a { 7 } else { 13 } } +} diff --git a/src/test/mir-opt/inline/inline-instruction-set.rs b/src/test/mir-opt/inline/inline-instruction-set.rs new file mode 100644 index 000000000..be36ff50c --- /dev/null +++ b/src/test/mir-opt/inline/inline-instruction-set.rs @@ -0,0 +1,54 @@ +// Checks that only functions with the compatible instruction_set attributes are inlined. +// +// compile-flags: --target thumbv4t-none-eabi +// needs-llvm-components: arm + +#![crate_type = "lib"] +#![feature(rustc_attrs)] +#![feature(no_core, lang_items)] +#![feature(isa_attribute)] +#![no_core] + +#[rustc_builtin_macro] +#[macro_export] +macro_rules! asm { + ("assembly template", + $(operands,)* + $(options($(option),*))? + ) => { + /* compiler built-in */ + }; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +#[instruction_set(arm::a32)] +#[inline] +fn instruction_set_a32() {} + +#[instruction_set(arm::t32)] +#[inline] +fn instruction_set_t32() {} + +#[inline] +fn instruction_set_default() {} + +// EMIT_MIR inline_instruction_set.t32.Inline.diff +#[instruction_set(arm::t32)] +pub fn t32() { + instruction_set_a32(); + instruction_set_t32(); + // The default instruction set is currently + // conservatively assumed to be incompatible. + instruction_set_default(); +} + +// EMIT_MIR inline_instruction_set.default.Inline.diff +pub fn default() { + instruction_set_a32(); + instruction_set_t32(); + instruction_set_default(); +} diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs new file mode 100644 index 000000000..049a97816 --- /dev/null +++ b/src/test/mir-opt/inline/inline-into-box-place.rs @@ -0,0 +1,9 @@ +// ignore-endian-big +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -Z mir-opt-level=4 +// EMIT_MIR_FOR_EACH_BIT_WIDTH +#![feature(box_syntax)] +// EMIT_MIR inline_into_box_place.main.Inline.diff +fn main() { + let _x: Box<Vec<u32>> = box Vec::new(); +} diff --git a/src/test/mir-opt/inline/inline-options.rs b/src/test/mir-opt/inline/inline-options.rs new file mode 100644 index 000000000..477f050b6 --- /dev/null +++ b/src/test/mir-opt/inline/inline-options.rs @@ -0,0 +1,19 @@ +// Checks that inlining threshold can be controlled with +// inline-mir-threshold and inline-hint-threshold options. +// +// compile-flags: -Zinline-mir-threshold=90 +// compile-flags: -Zinline-mir-hint-threshold=50 + +// EMIT_MIR inline_options.main.Inline.after.mir +fn main() { + not_inlined(); + inlined::<u32>(); +} + +// Cost is approximately 3 * 25 + 5 = 80. +#[inline] +pub fn not_inlined() { g(); g(); g(); } +pub fn inlined<T>() { g(); g(); g(); } + +#[inline(never)] +fn g() {} diff --git a/src/test/mir-opt/inline/inline-retag.rs b/src/test/mir-opt/inline/inline-retag.rs new file mode 100644 index 000000000..c6950f269 --- /dev/null +++ b/src/test/mir-opt/inline/inline-retag.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z span_free_formats -Z mir-emit-retag + +// Tests that MIR inliner fixes up `Retag`'s `fn_entry` flag + +fn main() { + println!("{}", bar()); +} + +// EMIT_MIR inline_retag.bar.Inline.after.mir +fn bar() -> bool { + let f = foo; + f(&1, &-1) +} + +#[inline(always)] +fn foo(x: &i32, y: &i32) -> bool { + *x == *y +} diff --git a/src/test/mir-opt/inline/inline-shims.rs b/src/test/mir-opt/inline/inline-shims.rs new file mode 100644 index 000000000..7c8618f71 --- /dev/null +++ b/src/test/mir-opt/inline/inline-shims.rs @@ -0,0 +1,13 @@ +// ignore-wasm32-bare compiled with panic=abort by default +#![crate_type = "lib"] + +// EMIT_MIR inline_shims.clone.Inline.diff +pub fn clone<A, B>(f: fn(A, B)) -> fn(A, B) { + f.clone() +} + +// EMIT_MIR inline_shims.drop.Inline.diff +pub fn drop<A, B>(a: *mut Vec<A>, b: *mut Option<B>) { + unsafe { std::ptr::drop_in_place(a) } + unsafe { std::ptr::drop_in_place(b) } +} diff --git a/src/test/mir-opt/inline/inline-specialization.rs b/src/test/mir-opt/inline/inline-specialization.rs new file mode 100644 index 000000000..87275b4e5 --- /dev/null +++ b/src/test/mir-opt/inline/inline-specialization.rs @@ -0,0 +1,15 @@ +#![feature(specialization)] + +// EMIT_MIR inline_specialization.main.Inline.diff +fn main() { + let x = <Vec::<()> as Foo>::bar(); +} + +trait Foo { + fn bar() -> u32; +} + +impl<T> Foo for Vec<T> { + #[inline(always)] + default fn bar() -> u32 { 123 } +} diff --git a/src/test/mir-opt/inline/inline-trait-method.rs b/src/test/mir-opt/inline/inline-trait-method.rs new file mode 100644 index 000000000..74be53f55 --- /dev/null +++ b/src/test/mir-opt/inline/inline-trait-method.rs @@ -0,0 +1,22 @@ +// compile-flags: -Z span_free_formats + +fn main() { + println!("{}", test(&())); +} + +// EMIT_MIR inline_trait_method.test.Inline.after.mir +fn test(x: &dyn X) -> u32 { + x.y() +} + +trait X { + fn y(&self) -> u32 { + 1 + } +} + +impl X for () { + fn y(&self) -> u32 { + 2 + } +} diff --git a/src/test/mir-opt/inline/inline-trait-method_2.rs b/src/test/mir-opt/inline/inline-trait-method_2.rs new file mode 100644 index 000000000..378e71a25 --- /dev/null +++ b/src/test/mir-opt/inline/inline-trait-method_2.rs @@ -0,0 +1,27 @@ +// compile-flags: -Z span_free_formats -Z mir-opt-level=4 + +// EMIT_MIR inline_trait_method_2.test2.Inline.after.mir +fn test2(x: &dyn X) -> bool { + test(x) +} + +#[inline] +fn test(x: &dyn X) -> bool { + x.y() +} + +trait X { + fn y(&self) -> bool { + false + } +} + +impl X for () { + fn y(&self) -> bool { + true + } +} + +fn main() { + println!("Should be true: {}", test2(&())); +} diff --git a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir new file mode 100644 index 000000000..630225258 --- /dev/null +++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir @@ -0,0 +1,44 @@ +// MIR for `bar` after Inline + +fn bar() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/inline-any-operand.rs:+0:13: +0:17 + let _1: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:+1:9: +1:10 + let mut _2: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:6 + let mut _3: i32; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:13 + let mut _4: i32; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:13 + scope 1 { + debug f => _1; // in scope 1 at $DIR/inline-any-operand.rs:+1:9: +1:10 + scope 2 (inlined foo) { // at $DIR/inline-any-operand.rs:12:5: 12:13 + debug x => _3; // in scope 2 at $DIR/inline-any-operand.rs:+6:8: +6:9 + debug y => _4; // in scope 2 at $DIR/inline-any-operand.rs:+6:16: +6:17 + let mut _5: i32; // in scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6 + let mut _6: i32; // in scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-any-operand.rs:+1:9: +1:10 + _1 = foo; // scope 0 at $DIR/inline-any-operand.rs:+1:13: +1:16 + // mir::Constant + // + span: $DIR/inline-any-operand.rs:11:13: 11:16 + // + literal: Const { ty: fn(i32, i32) -> bool {foo}, val: Value(<ZST>) } + StorageLive(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:6 + _2 = _1; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:6 + StorageLive(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 + _3 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 + StorageLive(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 + _4 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 + StorageLive(_5); // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6 + _5 = _3; // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:6 + StorageLive(_6); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11 + _6 = _4; // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11 + _0 = Eq(move _5, move _6); // scope 2 at $DIR/inline-any-operand.rs:+7:5: +7:11 + StorageDead(_6); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11 + StorageDead(_5); // scope 2 at $DIR/inline-any-operand.rs:+7:10: +7:11 + StorageDead(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 + StorageDead(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13 + StorageDead(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:12: +2:13 + StorageDead(_1); // scope 0 at $DIR/inline-any-operand.rs:+3:1: +3:2 + return; // scope 0 at $DIR/inline-any-operand.rs:+3:2: +3:2 + } +} diff --git a/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir new file mode 100644 index 000000000..1fadd2464 --- /dev/null +++ b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir @@ -0,0 +1,49 @@ +// MIR for `foo` after Inline + +fn foo(_1: T, _2: i32) -> i32 { + debug _t => _1; // in scope 0 at $DIR/inline-closure.rs:+0:17: +0:19 + debug q => _2; // in scope 0 at $DIR/inline-closure.rs:+0:24: +0:25 + let mut _0: i32; // return place in scope 0 at $DIR/inline-closure.rs:+0:35: +0:38 + let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure.rs:+1:9: +1:10 + let mut _4: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:6 + let mut _5: (i32, i32); // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12 + let mut _6: i32; // in scope 0 at $DIR/inline-closure.rs:+2:7: +2:8 + let mut _7: i32; // in scope 0 at $DIR/inline-closure.rs:+2:10: +2:11 + let mut _8: i32; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12 + let mut _9: i32; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12 + scope 1 { + debug x => _3; // in scope 1 at $DIR/inline-closure.rs:+1:9: +1:10 + scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure.rs:12:5: 12:12 + debug _t => _8; // in scope 2 at $DIR/inline-closure.rs:+1:14: +1:16 + debug _q => _9; // in scope 2 at $DIR/inline-closure.rs:+1:18: +1:20 + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/inline-closure.rs:+1:9: +1:10 + Deinit(_3); // scope 0 at $DIR/inline-closure.rs:+1:13: +1:24 + StorageLive(_4); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:6 + _4 = &_3; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:6 + StorageLive(_5); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + StorageLive(_6); // scope 1 at $DIR/inline-closure.rs:+2:7: +2:8 + _6 = _2; // scope 1 at $DIR/inline-closure.rs:+2:7: +2:8 + StorageLive(_7); // scope 1 at $DIR/inline-closure.rs:+2:10: +2:11 + _7 = _2; // scope 1 at $DIR/inline-closure.rs:+2:10: +2:11 + Deinit(_5); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + (_5.0: i32) = move _6; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + (_5.1: i32) = move _7; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + StorageLive(_8); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + _8 = move (_5.0: i32); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + StorageLive(_9); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + _9 = move (_5.1: i32); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + _0 = _8; // scope 2 at $DIR/inline-closure.rs:+1:22: +1:24 + StorageDead(_9); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + StorageDead(_8); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12 + StorageDead(_7); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12 + StorageDead(_6); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12 + StorageDead(_5); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12 + StorageDead(_4); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12 + StorageDead(_3); // scope 0 at $DIR/inline-closure.rs:+3:1: +3:2 + return; // scope 0 at $DIR/inline-closure.rs:+3:2: +3:2 + } +} diff --git a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir new file mode 100644 index 000000000..4069e9f89 --- /dev/null +++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir @@ -0,0 +1,56 @@ +// MIR for `foo` after Inline + +fn foo(_1: T, _2: &i32) -> i32 { + debug _t => _1; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:17: +0:19 + debug q => _2; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:24: +0:25 + let mut _0: i32; // return place in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:36: +0:39 + let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10 + let mut _4: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6 + let mut _5: (&i32, &i32); // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + let mut _6: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8 + let mut _7: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11 + let mut _8: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + let mut _9: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + scope 1 { + debug x => _3; // in scope 1 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10 + scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 + debug r => _8; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+1:14: +1:15 + debug _s => _9; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+1:23: +1:25 + let _10: &i32; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21 + scope 3 { + debug variable => _10; // in scope 3 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21 + } + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10 + Deinit(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:13: +4:6 + StorageLive(_4); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6 + _4 = &_3; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6 + StorageLive(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + StorageLive(_6); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8 + _6 = &(*_2); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8 + StorageLive(_7); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11 + _7 = &(*_2); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11 + Deinit(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + (_5.0: &i32) = move _6; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + (_5.1: &i32) = move _7; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + StorageLive(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + _8 = move (_5.0: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + StorageLive(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + _9 = move (_5.1: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + StorageLive(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21 + _10 = _8; // scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:24: +2:27 + _0 = (*_10); // scope 3 at $DIR/inline-closure-borrows-arg.rs:+3:9: +3:18 + StorageDead(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:+4:5: +4:6 + StorageDead(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + StorageDead(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12 + StorageDead(_7); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12 + StorageDead(_6); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12 + StorageDead(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12 + StorageDead(_4); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12 + StorageDead(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+6:1: +6:2 + return; // scope 0 at $DIR/inline-closure-borrows-arg.rs:+6:2: +6:2 + } +} diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir new file mode 100644 index 000000000..d60b06460 --- /dev/null +++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -0,0 +1,69 @@ +// MIR for `foo` after Inline + +fn foo(_1: T, _2: i32) -> (i32, T) { + debug t => _1; // in scope 0 at $DIR/inline-closure-captures.rs:+0:17: +0:18 + debug q => _2; // in scope 0 at $DIR/inline-closure-captures.rs:+0:23: +0:24 + let mut _0: (i32, T); // return place in scope 0 at $DIR/inline-closure-captures.rs:+0:34: +0:42 + let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:+1:9: +1:10 + let mut _4: &i32; // in scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + let mut _5: &T; // in scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + let mut _6: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:6 + let mut _7: (i32,); // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + let mut _8: i32; // in scope 0 at $DIR/inline-closure-captures.rs:+2:7: +2:8 + let mut _9: i32; // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + scope 1 { + debug x => _3; // in scope 1 at $DIR/inline-closure-captures.rs:+1:9: +1:10 + scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure-captures.rs:12:5: 12:9 + debug _q => _9; // in scope 2 at $DIR/inline-closure-captures.rs:+1:14: +1:16 + debug q => (*((*_6).0: &i32)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:23: +0:24 + debug t => (*((*_6).1: &T)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:17: +0:18 + let mut _10: i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 + let mut _11: T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 + let mut _12: &i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:17 + let mut _13: &T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:17 + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/inline-closure-captures.rs:+1:9: +1:10 + StorageLive(_4); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + _4 = &_2; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + StorageLive(_5); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + _5 = &_1; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + Deinit(_3); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + (_3.0: &i32) = move _4; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + (_3.1: &T) = move _5; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24 + StorageDead(_5); // scope 0 at $DIR/inline-closure-captures.rs:+1:16: +1:17 + StorageDead(_4); // scope 0 at $DIR/inline-closure-captures.rs:+1:16: +1:17 + StorageLive(_6); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:6 + _6 = &_3; // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:6 + StorageLive(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + StorageLive(_8); // scope 1 at $DIR/inline-closure-captures.rs:+2:7: +2:8 + _8 = _2; // scope 1 at $DIR/inline-closure-captures.rs:+2:7: +2:8 + Deinit(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + (_7.0: i32) = move _8; // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + StorageLive(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + _9 = move (_7.0: i32); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + StorageLive(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 + StorageLive(_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 + _12 = deref_copy ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 + _10 = (*_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20 + StorageDead(_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 + StorageLive(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 + StorageLive(_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 + _13 = deref_copy ((*_6).1: &T); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 + _11 = (*_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23 + StorageDead(_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24 + Deinit(_0); // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24 + (_0.0: i32) = move _10; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24 + (_0.1: T) = move _11; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24 + StorageDead(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:23: +1:24 + StorageDead(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:23: +1:24 + StorageDead(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9 + StorageDead(_8); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9 + StorageDead(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9 + StorageDead(_6); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9 + StorageDead(_3); // scope 0 at $DIR/inline-closure-captures.rs:+3:1: +3:2 + return; // scope 0 at $DIR/inline-closure-captures.rs:+3:2: +3:2 + } +} diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff new file mode 100644 index 000000000..cf800ba11 --- /dev/null +++ b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff @@ -0,0 +1,24 @@ +- // MIR for `inlined_no_sanitize` before Inline ++ // MIR for `inlined_no_sanitize` after Inline + + fn inlined_no_sanitize() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:37: +0:37 + let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 ++ scope 1 (inlined no_sanitize) { // at $DIR/inline-compatibility.rs:24:5: 24:18 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 +- _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 +- // mir::Constant +- // + span: $DIR/inline-compatibility.rs:24:5: 24:16 +- // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(<ZST>) } +- } +- +- bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:18: +1:19 + _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:37: +2:2 + return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff new file mode 100644 index 000000000..a45f95902 --- /dev/null +++ b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff @@ -0,0 +1,24 @@ +- // MIR for `inlined_target_feature` before Inline ++ // MIR for `inlined_target_feature` after Inline + + fn inlined_target_feature() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40 + let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 ++ scope 1 (inlined target_feature) { // at $DIR/inline-compatibility.rs:13:5: 13:21 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 +- _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 +- // mir::Constant +- // + span: $DIR/inline-compatibility.rs:13:5: 13:19 +- // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(<ZST>) } +- } +- +- bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:21: +1:22 + _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:40: +2:2 + return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff new file mode 100644 index 000000000..49aea431e --- /dev/null +++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff @@ -0,0 +1,25 @@ +- // MIR for `not_inlined_c_variadic` before Inline ++ // MIR for `not_inlined_c_variadic` after Inline + + fn not_inlined_c_variadic() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40 + let _1: u32; // in scope 0 at $DIR/inline-compatibility.rs:+1:9: +1:10 + scope 1 { + debug s => _1; // in scope 1 at $DIR/inline-compatibility.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:9: +1:10 + _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:13: +1:52 + // mir::Constant + // + span: $DIR/inline-compatibility.rs:42:13: 42:16 + // + literal: Const { ty: unsafe extern "C" fn(u32, ...) -> u32 {sum}, val: Value(<ZST>) } + } + + bb1: { + _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:40: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff new file mode 100644 index 000000000..94ce574a9 --- /dev/null +++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff @@ -0,0 +1,22 @@ +- // MIR for `not_inlined_no_sanitize` before Inline ++ // MIR for `not_inlined_no_sanitize` after Inline + + fn not_inlined_no_sanitize() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:41: +0:41 + let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 + _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18 + // mir::Constant + // + span: $DIR/inline-compatibility.rs:29:5: 29:16 + // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:18: +1:19 + _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:41: +2:2 + return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff new file mode 100644 index 000000000..8506e257b --- /dev/null +++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff @@ -0,0 +1,22 @@ +- // MIR for `not_inlined_target_feature` before Inline ++ // MIR for `not_inlined_target_feature` after Inline + + fn not_inlined_target_feature() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:44: +0:44 + let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 + _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21 + // mir::Constant + // + span: $DIR/inline-compatibility.rs:18:5: 18:19 + // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:21: +1:22 + _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:44: +2:2 + return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff new file mode 100644 index 000000000..b1c476362 --- /dev/null +++ b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff @@ -0,0 +1,30 @@ +- // MIR for `one` before Inline ++ // MIR for `one` after Inline + + fn one() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:+0:10: +0:10 + let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24 ++ scope 1 (inlined <C as Call>::call) { // at $DIR/inline-cycle.rs:14:5: 14:24 ++ scope 2 (inlined <A<C> as Call>::call) { // at $DIR/inline-cycle.rs:43:9: 43:23 ++ scope 3 (inlined <B<C> as Call>::call) { // at $DIR/inline-cycle.rs:28:9: 28:31 ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24 +- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24 ++ _1 = <C as Call>::call() -> bb1; // scope 3 at $DIR/inline-cycle.rs:+23:9: +23:28 + // mir::Constant +- // + span: $DIR/inline-cycle.rs:14:5: 14:22 ++ // + span: $DIR/inline-cycle.rs:36:9: 36:26 + // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:24: +1:25 + _0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2 + return; // scope 0 at $DIR/inline-cycle.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff new file mode 100644 index 000000000..dc890a365 --- /dev/null +++ b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff @@ -0,0 +1,55 @@ +- // MIR for `two` before Inline ++ // MIR for `two` after Inline + + fn two() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:+0:10: +0:10 + let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 ++ let mut _2: fn() {f}; // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 ++ scope 1 (inlined call::<fn() {f}>) { // at $DIR/inline-cycle.rs:49:5: 49:12 ++ debug f => _2; // in scope 1 at $DIR/inline-cycle.rs:+5:22: +5:23 ++ let _3: (); // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8 ++ let mut _4: fn() {f}; // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6 ++ let mut _5: (); // in scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8 ++ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) { // at $DIR/inline-cycle.rs:54:5: 54:8 ++ scope 3 (inlined f) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ let _6: (); // in scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12 ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 +- _1 = call::<fn() {f}>(f) -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 ++ StorageLive(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 ++ _2 = f; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 + // mir::Constant +- // + span: $DIR/inline-cycle.rs:49:5: 49:9 ++ // + span: $DIR/inline-cycle.rs:49:10: 49:11 ++ // + literal: Const { ty: fn() {f}, val: Value(<ZST>) } ++ StorageLive(_3); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8 ++ StorageLive(_4); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6 ++ _4 = move _2; // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:6 ++ StorageLive(_5); // scope 1 at $DIR/inline-cycle.rs:+6:5: +6:8 ++ StorageLive(_6); // scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12 ++ _6 = call::<fn() {f}>(f) -> bb1; // scope 3 at $DIR/inline-cycle.rs:+11:5: +11:12 ++ // mir::Constant ++ // + span: $DIR/inline-cycle.rs:59:5: 59:9 + // + literal: Const { ty: fn(fn() {f}) {call::<fn() {f}>}, val: Value(<ZST>) } + // mir::Constant +- // + span: $DIR/inline-cycle.rs:49:10: 49:11 ++ // + span: $DIR/inline-cycle.rs:59:10: 59:11 + // + literal: Const { ty: fn() {f}, val: Value(<ZST>) } + } + + bb1: { ++ StorageDead(_6); // scope 3 at $DIR/inline-cycle.rs:+11:12: +11:13 ++ StorageDead(_5); // scope 1 at $DIR/inline-cycle.rs:+6:7: +6:8 ++ StorageDead(_4); // scope 1 at $DIR/inline-cycle.rs:+6:7: +6:8 ++ StorageDead(_3); // scope 1 at $DIR/inline-cycle.rs:+6:8: +6:9 ++ StorageDead(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12 + StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:12: +1:13 + _0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2 + return; // scope 0 at $DIR/inline-cycle.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff new file mode 100644 index 000000000..082f57e59 --- /dev/null +++ b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff @@ -0,0 +1,32 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-cycle-generic.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24 ++ scope 1 (inlined <C as Call>::call) { // at $DIR/inline-cycle-generic.rs:9:5: 9:24 ++ scope 2 (inlined <B<A> as Call>::call) { // at $DIR/inline-cycle-generic.rs:38:9: 38:31 ++ scope 3 (inlined <A as Call>::call) { // at $DIR/inline-cycle-generic.rs:31:9: 31:28 ++ scope 4 (inlined <B<C> as Call>::call) { // at $DIR/inline-cycle-generic.rs:23:9: 23:31 ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24 +- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24 ++ _1 = <C as Call>::call() -> bb1; // scope 4 at $DIR/inline-cycle-generic.rs:+23:9: +23:28 + // mir::Constant +- // + span: $DIR/inline-cycle-generic.rs:9:5: 9:22 ++ // + span: $DIR/inline-cycle-generic.rs:31:9: 31:26 + // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:24: +1:25 + _0 = const (); // scope 0 at $DIR/inline-cycle-generic.rs:+0:11: +2:2 + return; // scope 0 at $DIR/inline-cycle-generic.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff new file mode 100644 index 000000000..6b24b3e16 --- /dev/null +++ b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff @@ -0,0 +1,24 @@ +- // MIR for `f` before Inline ++ // MIR for `f` after Inline + + fn f() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:+0:12: +0:12 + let mut _1: !; // in scope 0 at $DIR/inline-diverging.rs:+0:12: +2:2 + let _2: !; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12 ++ scope 1 (inlined sleep) { // at $DIR/inline-diverging.rs:8:5: 8:12 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12 +- _2 = sleep(); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12 +- // mir::Constant +- // + span: $DIR/inline-diverging.rs:8:5: 8:10 +- // + literal: Const { ty: fn() -> ! {sleep}, val: Value(<ZST>) } ++ goto -> bb1; // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12 ++ } ++ ++ bb1: { ++ goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:+32:5: +32:12 + } + } + diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff new file mode 100644 index 000000000..a25f1454f --- /dev/null +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -0,0 +1,49 @@ +- // MIR for `g` before Inline ++ // MIR for `g` after Inline + + fn g(_1: i32) -> u32 { + debug i => _1; // in scope 0 at $DIR/inline-diverging.rs:+0:10: +0:11 + let mut _0: u32; // return place in scope 0 at $DIR/inline-diverging.rs:+0:21: +0:24 + let mut _2: bool; // in scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13 + let mut _3: i32; // in scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9 + let mut _4: i32; // in scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10 + let mut _5: !; // in scope 0 at $DIR/inline-diverging.rs:+3:12: +5:6 + let _6: !; // in scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16 ++ scope 1 (inlined panic) { // at $DIR/inline-diverging.rs:16:9: 16:16 ++ let mut _7: !; // in scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13 + StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9 + _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13 + StorageDead(_3); // scope 0 at $DIR/inline-diverging.rs:+1:12: +1:13 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13 + } + + bb1: { + StorageLive(_4); // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10 + _4 = _1; // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10 + _0 = move _4 as u32 (Misc); // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:17 + StorageDead(_4); // scope 0 at $DIR/inline-diverging.rs:+2:16: +2:17 + StorageDead(_2); // scope 0 at $DIR/inline-diverging.rs:+5:5: +5:6 + return; // scope 0 at $DIR/inline-diverging.rs:+6:2: +6:2 + } + + bb2: { + StorageLive(_6); // scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16 +- _6 = panic(); // scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16 ++ StorageLive(_7); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL ++ _7 = begin_panic::<&str>(const "explicit panic"); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL + // mir::Constant +- // + span: $DIR/inline-diverging.rs:16:9: 16:14 +- // + literal: Const { ty: fn() -> ! {panic}, val: Value(<ZST>) } ++ // + span: $SRC_DIR/std/src/panic.rs:LL:COL ++ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) } ++ // mir::Constant ++ // + span: $SRC_DIR/std/src/panic.rs:LL:COL ++ // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + } + diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff new file mode 100644 index 000000000..8759f3d02 --- /dev/null +++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff @@ -0,0 +1,56 @@ +- // MIR for `h` before Inline ++ // MIR for `h` after Inline + + fn h() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:+0:12: +0:12 + let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 ++ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 ++ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22 ++ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:+5:36: +5:37 ++ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:+6:9: +6:10 ++ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14 ++ let mut _5: (); // in scope 1 at $DIR/inline-diverging.rs:+6:13: +6:16 ++ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:+7:13: +7:14 ++ let mut _8: (); // in scope 1 at $DIR/inline-diverging.rs:+7:13: +7:16 ++ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:+8:6: +8:7 ++ let mut _10: !; // in scope 1 at $DIR/inline-diverging.rs:+8:9: +8:10 ++ scope 2 { ++ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:+6:9: +6:10 ++ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:+7:9: +7:10 ++ scope 3 { ++ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:+7:9: +7:10 ++ } ++ scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:28:13: 28:16 ++ scope 7 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ } ++ } ++ } ++ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:27:13: 27:16 ++ scope 5 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 +- _1 = call_twice::<!, fn() -> ! {sleep}>(sleep); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 ++ StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 ++ _2 = sleep; // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22 + // mir::Constant +- // + span: $DIR/inline-diverging.rs:22:5: 22:15 +- // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice::<!, fn() -> ! {sleep}>}, val: Value(<ZST>) } +- // mir::Constant + // + span: $DIR/inline-diverging.rs:22:16: 22:21 + // + literal: Const { ty: fn() -> ! {sleep}, val: Value(<ZST>) } ++ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:+6:9: +6:10 ++ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14 ++ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:14 ++ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:+6:13: +6:16 ++ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:+18:5: +18:12 ++ } ++ ++ bb1: { ++ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:+18:5: +18:12 + } + } + diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff new file mode 100644 index 000000000..c7c2759cc --- /dev/null +++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff @@ -0,0 +1,156 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-generator.rs:+0:11: +0:11 + let _1: std::ops::GeneratorState<i32, bool>; // in scope 0 at $DIR/inline-generator.rs:+1:9: +1:11 + let mut _2: std::pin::Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline-generator.rs:+1:14: +1:32 + let mut _3: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline-generator.rs:+1:23: +1:31 + let mut _4: [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline-generator.rs:+1:28: +1:31 ++ let mut _7: bool; // in scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 + scope 1 { + debug _r => _1; // in scope 1 at $DIR/inline-generator.rs:+1:9: +1:11 + } ++ scope 2 (inlined g) { // at $DIR/inline-generator.rs:9:28: 9:31 ++ } ++ scope 3 (inlined Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new) { // at $DIR/inline-generator.rs:9:14: 9:32 ++ debug pointer => _3; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL ++ let mut _5: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL ++ debug pointer => _5; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ let mut _6: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ } ++ } ++ } ++ scope 6 (inlined g::{closure#0}) { // at $DIR/inline-generator.rs:9:14: 9:46 ++ debug a => _11; // in scope 6 at $DIR/inline-generator.rs:+7:6: +7:7 ++ let mut _8: i32; // in scope 6 at $DIR/inline-generator.rs:+7:17: +7:39 ++ let mut _9: bool; // in scope 6 at $DIR/inline-generator.rs:+7:20: +7:21 ++ let mut _10: bool; // in scope 6 at $DIR/inline-generator.rs:+7:9: +7:9 ++ let _11: bool; // in scope 6 at $DIR/inline-generator.rs:+7:6: +7:7 ++ let mut _12: u32; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ let mut _13: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ let mut _14: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ let mut _15: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-generator.rs:+1:9: +1:11 + StorageLive(_2); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32 + StorageLive(_3); // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31 + StorageLive(_4); // scope 0 at $DIR/inline-generator.rs:+1:28: +1:31 +- _4 = g() -> bb1; // scope 0 at $DIR/inline-generator.rs:+1:28: +1:31 +- // mir::Constant +- // + span: $DIR/inline-generator.rs:9:28: 9:29 +- // + literal: Const { ty: fn() -> impl Generator<bool> {g}, val: Value(<ZST>) } +- } +- +- bb1: { ++ Deinit(_4); // scope 2 at $DIR/inline-generator.rs:+7:5: +7:41 ++ discriminant(_4) = 0; // scope 2 at $DIR/inline-generator.rs:+7:5: +7:41 + _3 = &mut _4; // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31 +- _2 = Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32 +- // mir::Constant +- // + span: $DIR/inline-generator.rs:9:14: 9:22 +- // + user_ty: UserType(0) +- // + literal: Const { ty: fn(&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]) -> Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]> {Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new}, val: Value(<ZST>) } +- } +- +- bb2: { ++ StorageLive(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL ++ _5 = move _3; // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL ++ StorageLive(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ _6 = move _5; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ Deinit(_2); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]) = move _6; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ StorageDead(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ StorageDead(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/inline-generator.rs:+1:31: +1:32 +- _1 = <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 +- // mir::Constant +- // + span: $DIR/inline-generator.rs:9:33: 9:39 +- // + literal: Const { ty: for<'r> fn(Pin<&'r mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::Yield, <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::Return> {<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::resume}, val: Value(<ZST>) } ++ StorageLive(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 ++ _7 = const false; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 ++ StorageLive(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 ++ StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 ++ StorageLive(_12); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 ++ StorageLive(_13); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ _13 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ StorageDead(_13); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 + } + +- bb3: { ++ bb1: { ++ StorageDead(_12); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 ++ StorageDead(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 ++ StorageDead(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 ++ StorageDead(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 + StorageDead(_2); // scope 0 at $DIR/inline-generator.rs:+1:45: +1:46 + StorageDead(_4); // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47 + _0 = const (); // scope 0 at $DIR/inline-generator.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline-generator.rs:+2:2: +2:2 + } + +- bb4 (cleanup): { ++ bb2 (cleanup): { + resume; // scope 0 at $DIR/inline-generator.rs:+0:1: +2:2 ++ } ++ ++ bb3: { ++ _11 = move _7; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39 ++ StorageLive(_9); // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21 ++ _9 = _11; // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21 ++ switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline-generator.rs:+7:20: +7:21 ++ } ++ ++ bb4: { ++ _8 = const 7_i32; // scope 6 at $DIR/inline-generator.rs:+7:24: +7:25 ++ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39 ++ } ++ ++ bb5: { ++ _8 = const 13_i32; // scope 6 at $DIR/inline-generator.rs:+7:35: +7:37 ++ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:+7:17: +7:39 ++ } ++ ++ bb6: { ++ StorageDead(_9); // scope 6 at $DIR/inline-generator.rs:+7:38: +7:39 ++ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39 ++ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39 ++ discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39 ++ StorageLive(_14); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39 ++ _14 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39 ++ discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39 ++ StorageDead(_14); // scope 6 at $DIR/inline-generator.rs:+7:11: +7:39 ++ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:+7:11: +7:39 ++ } ++ ++ bb7: { ++ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ _10 = move _7; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ StorageDead(_8); // scope 6 at $DIR/inline-generator.rs:+7:38: +7:39 ++ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8 ++ ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8 ++ discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8 ++ StorageLive(_15); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8 ++ _15 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8 ++ discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8 ++ StorageDead(_15); // scope 6 at $DIR/inline-generator.rs:+7:8: +7:8 ++ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:+7:8: +7:8 ++ } ++ ++ bb8: { ++ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 ++ } ++ ++ bb9: { ++ unreachable; // scope 6 at $DIR/inline-generator.rs:+7:5: +7:8 + } + } + diff --git a/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff new file mode 100644 index 000000000..076509df3 --- /dev/null +++ b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff @@ -0,0 +1,44 @@ +- // MIR for `default` before Inline ++ // MIR for `default` after Inline + + fn default() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:+0:18: +0:18 + let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 + let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 + let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30 ++ scope 1 (inlined instruction_set_default) { // at $DIR/inline-instruction-set.rs:53:5: 53:30 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 + _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 + // mir::Constant + // + span: $DIR/inline-instruction-set.rs:51:5: 51:24 + // + literal: Const { ty: fn() {instruction_set_a32}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:26: +1:27 + StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 + _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 + // mir::Constant + // + span: $DIR/inline-instruction-set.rs:52:5: 52:24 + // + literal: Const { ty: fn() {instruction_set_t32}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:26: +2:27 + StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30 +- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30 +- // mir::Constant +- // + span: $DIR/inline-instruction-set.rs:53:5: 53:28 +- // + literal: Const { ty: fn() {instruction_set_default}, val: Value(<ZST>) } +- } +- +- bb3: { + StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:+3:30: +3:31 + _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:+0:18: +4:2 + return; // scope 0 at $DIR/inline-instruction-set.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff new file mode 100644 index 000000000..b275d08e0 --- /dev/null +++ b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff @@ -0,0 +1,46 @@ +- // MIR for `t32` before Inline ++ // MIR for `t32` after Inline + + fn t32() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:+0:14: +0:14 + let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 + let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 + let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30 ++ scope 1 (inlined instruction_set_t32) { // at $DIR/inline-instruction-set.rs:43:5: 43:26 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 + _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26 + // mir::Constant + // + span: $DIR/inline-instruction-set.rs:42:5: 42:24 + // + literal: Const { ty: fn() {instruction_set_a32}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:26: +1:27 + StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 +- _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26 +- // mir::Constant +- // + span: $DIR/inline-instruction-set.rs:43:5: 43:24 +- // + literal: Const { ty: fn() {instruction_set_t32}, val: Value(<ZST>) } +- } +- +- bb2: { + StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:26: +2:27 + StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30 +- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30 ++ _3 = instruction_set_default() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30 + // mir::Constant + // + span: $DIR/inline-instruction-set.rs:46:5: 46:28 + // + literal: Const { ty: fn() {instruction_set_default}, val: Value(<ZST>) } + } + +- bb3: { ++ bb2: { + StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:+5:30: +5:31 + _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:+0:14: +6:2 + return; // scope 0 at $DIR/inline-instruction-set.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff new file mode 100644 index 000000000..deaba70e0 --- /dev/null +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff @@ -0,0 +1,86 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11 + let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11 + let mut _2: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _3: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _4: *mut u8; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 + let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 ++ let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + scope 1 { + debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11 + } + scope 2 { + } ++ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11 + _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + // mir::Constant + // + span: $DIR/inline-into-box-place.rs:8:29: 8:43 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 +- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // mir::Constant +- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 +- // + user_ty: UserType(1) +- // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) } +- } +- +- bb2: { ++ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ // + user_ty: UserType(0) ++ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) } ++ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 + _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2 +- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 ++ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 + } + +- bb3: { ++ bb2: { + StorageDead(_1); // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline-into-box-place.rs:+2:2: +2:2 + } + +- bb4 (cleanup): { +- StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 +- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb5; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 +- // mir::Constant +- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43 +- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) } +- } +- +- bb5 (cleanup): { ++ bb3 (cleanup): { + resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff new file mode 100644 index 000000000..deaba70e0 --- /dev/null +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff @@ -0,0 +1,86 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11 + let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11 + let mut _2: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _3: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _4: *mut u8; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 + let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 ++ let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + scope 1 { + debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11 + } + scope 2 { + } ++ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11 + _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + // mir::Constant + // + span: $DIR/inline-into-box-place.rs:8:29: 8:43 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 +- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 ++ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // mir::Constant +- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 +- // + user_ty: UserType(1) +- // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) } +- } +- +- bb2: { ++ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ // + user_ty: UserType(0) ++ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) } ++ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43 + StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 + _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2 +- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 ++ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 + } + +- bb3: { ++ bb2: { + StorageDead(_1); // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline-into-box-place.rs:+2:2: +2:2 + } + +- bb4 (cleanup): { +- StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 +- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb5; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43 +- // mir::Constant +- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43 +- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) } +- } +- +- bb5 (cleanup): { ++ bb3 (cleanup): { + resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir new file mode 100644 index 000000000..275493066 --- /dev/null +++ b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir @@ -0,0 +1,55 @@ +// MIR for `main` after Inline + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-options.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/inline-options.rs:+1:5: +1:18 + let _2: (); // in scope 0 at $DIR/inline-options.rs:+2:5: +2:21 + scope 1 (inlined inlined::<u32>) { // at $DIR/inline-options.rs:10:5: 10:21 + let _3: (); // in scope 1 at $DIR/inline-options.rs:+8:23: +8:26 + let _4: (); // in scope 1 at $DIR/inline-options.rs:+8:28: +8:31 + let _5: (); // in scope 1 at $DIR/inline-options.rs:+8:33: +8:36 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-options.rs:+1:5: +1:18 + _1 = not_inlined() -> bb1; // scope 0 at $DIR/inline-options.rs:+1:5: +1:18 + // mir::Constant + // + span: $DIR/inline-options.rs:9:5: 9:16 + // + literal: Const { ty: fn() {not_inlined}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-options.rs:+1:18: +1:19 + StorageLive(_2); // scope 0 at $DIR/inline-options.rs:+2:5: +2:21 + StorageLive(_3); // scope 1 at $DIR/inline-options.rs:+8:23: +8:26 + _3 = g() -> bb2; // scope 1 at $DIR/inline-options.rs:+8:23: +8:26 + // mir::Constant + // + span: $DIR/inline-options.rs:16:23: 16:24 + // + literal: Const { ty: fn() {g}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_3); // scope 1 at $DIR/inline-options.rs:+8:26: +8:27 + StorageLive(_4); // scope 1 at $DIR/inline-options.rs:+8:28: +8:31 + _4 = g() -> bb3; // scope 1 at $DIR/inline-options.rs:+8:28: +8:31 + // mir::Constant + // + span: $DIR/inline-options.rs:16:28: 16:29 + // + literal: Const { ty: fn() {g}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_4); // scope 1 at $DIR/inline-options.rs:+8:31: +8:32 + StorageLive(_5); // scope 1 at $DIR/inline-options.rs:+8:33: +8:36 + _5 = g() -> bb4; // scope 1 at $DIR/inline-options.rs:+8:33: +8:36 + // mir::Constant + // + span: $DIR/inline-options.rs:16:33: 16:34 + // + literal: Const { ty: fn() {g}, val: Value(<ZST>) } + } + + bb4: { + StorageDead(_5); // scope 1 at $DIR/inline-options.rs:+8:36: +8:37 + StorageDead(_2); // scope 0 at $DIR/inline-options.rs:+2:21: +2:22 + _0 = const (); // scope 0 at $DIR/inline-options.rs:+0:11: +3:2 + return; // scope 0 at $DIR/inline-options.rs:+3:2: +3:2 + } +} diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir new file mode 100644 index 000000000..768608564 --- /dev/null +++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir @@ -0,0 +1,72 @@ +// MIR for `bar` after Inline + +fn bar() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/inline-retag.rs:+0:13: +0:17 + let _1: for<'r, 's> fn(&'r i32, &'s i32) -> bool {foo}; // in scope 0 at $DIR/inline-retag.rs:+1:9: +1:10 + let mut _2: for<'r, 's> fn(&'r i32, &'s i32) -> bool {foo}; // in scope 0 at $DIR/inline-retag.rs:+2:5: +2:6 + let mut _3: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:7: +2:9 + let _4: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:7: +2:9 + let _5: i32; // in scope 0 at $DIR/inline-retag.rs:+2:8: +2:9 + let mut _6: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:11: +2:14 + let _7: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:11: +2:14 + let _8: i32; // in scope 0 at $DIR/inline-retag.rs:+2:12: +2:14 + scope 1 { + debug f => _1; // in scope 1 at $DIR/inline-retag.rs:+1:9: +1:10 + let mut _9: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + let mut _10: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + scope 2 (inlined foo) { // at $DIR/inline-retag.rs:12:5: 12:15 + debug x => _3; // in scope 2 at $DIR/inline-retag.rs:+6:8: +6:9 + debug y => _6; // in scope 2 at $DIR/inline-retag.rs:+6:17: +6:18 + let mut _11: i32; // in scope 2 at $DIR/inline-retag.rs:+7:5: +7:7 + let mut _12: i32; // in scope 2 at $DIR/inline-retag.rs:+7:11: +7:13 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-retag.rs:+1:9: +1:10 + _1 = foo; // scope 0 at $DIR/inline-retag.rs:+1:13: +1:16 + // mir::Constant + // + span: $DIR/inline-retag.rs:11:13: 11:16 + // + literal: Const { ty: for<'r, 's> fn(&'r i32, &'s i32) -> bool {foo}, val: Value(<ZST>) } + StorageLive(_2); // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6 + _2 = _1; // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6 + StorageLive(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + StorageLive(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + _10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + // mir::Constant + // + span: $DIR/inline-retag.rs:12:7: 12:9 + // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) } + Retag(_10); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + _4 = &(*_10); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + Retag(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + _3 = &(*_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + Retag(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + StorageLive(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + StorageLive(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + _9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + // mir::Constant + // + span: $DIR/inline-retag.rs:12:11: 12:14 + // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) } + Retag(_9); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + _7 = &(*_9); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + Retag(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + _6 = &(*_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + Retag(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + Retag(_3); // scope 2 at $DIR/inline-retag.rs:+6:1: +8:2 + Retag(_6); // scope 2 at $DIR/inline-retag.rs:+6:1: +8:2 + StorageLive(_11); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:7 + _11 = (*_3); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:7 + StorageLive(_12); // scope 2 at $DIR/inline-retag.rs:+7:11: +7:13 + _12 = (*_6); // scope 2 at $DIR/inline-retag.rs:+7:11: +7:13 + _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline-retag.rs:+7:5: +7:13 + StorageDead(_12); // scope 2 at $DIR/inline-retag.rs:+7:12: +7:13 + StorageDead(_11); // scope 2 at $DIR/inline-retag.rs:+7:12: +7:13 + StorageDead(_6); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15 + StorageDead(_3); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15 + StorageDead(_2); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15 + StorageDead(_1); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2 + StorageDead(_7); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2 + StorageDead(_4); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2 + return; // scope 0 at $DIR/inline-retag.rs:+3:2: +3:2 + } +} diff --git a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff new file mode 100644 index 000000000..25ca05893 --- /dev/null +++ b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff @@ -0,0 +1,26 @@ +- // MIR for `clone` before Inline ++ // MIR for `clone` after Inline + + fn clone(_1: fn(A, B)) -> fn(A, B) { + debug f => _1; // in scope 0 at $DIR/inline-shims.rs:+0:20: +0:21 + let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline-shims.rs:+0:36: +0:44 + let mut _2: &fn(A, B); // in scope 0 at $DIR/inline-shims.rs:+1:5: +1:14 ++ scope 1 (inlined <fn(A, B) as Clone>::clone - shim(fn(A, B))) { // at $DIR/inline-shims.rs:6:5: 6:14 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14 + _2 = &_1; // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14 +- _0 = <fn(A, B) as Clone>::clone(move _2) -> bb1; // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14 +- // mir::Constant +- // + span: $DIR/inline-shims.rs:6:7: 6:12 +- // + literal: Const { ty: for<'r> fn(&'r fn(A, B)) -> fn(A, B) {<fn(A, B) as Clone>::clone}, val: Value(<ZST>) } +- } +- +- bb1: { ++ _0 = (*_2); // scope 1 at $SRC_DIR/core/src/clone.rs:LL:COL + StorageDead(_2); // scope 0 at $DIR/inline-shims.rs:+1:13: +1:14 + return; // scope 0 at $DIR/inline-shims.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff new file mode 100644 index 000000000..f7b1cde80 --- /dev/null +++ b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff @@ -0,0 +1,56 @@ +- // MIR for `drop` before Inline ++ // MIR for `drop` after Inline + + fn drop(_1: *mut Vec<A>, _2: *mut Option<B>) -> () { + debug a => _1; // in scope 0 at $DIR/inline-shims.rs:+0:19: +0:20 + debug b => _2; // in scope 0 at $DIR/inline-shims.rs:+0:35: +0:36 + let mut _0: (); // return place in scope 0 at $DIR/inline-shims.rs:+0:54: +0:54 + let _3: (); // in scope 0 at $DIR/inline-shims.rs:+1:14: +1:40 + let mut _4: *mut std::vec::Vec<A>; // in scope 0 at $DIR/inline-shims.rs:+1:38: +1:39 + let mut _5: *mut std::option::Option<B>; // in scope 0 at $DIR/inline-shims.rs:+2:38: +2:39 + scope 1 { + } + scope 2 { ++ scope 3 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) { // at $DIR/inline-shims.rs:12:14: 12:40 ++ let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/inline-shims.rs:+1:5: +1:42 + StorageLive(_4); // scope 1 at $DIR/inline-shims.rs:+1:38: +1:39 + _4 = _1; // scope 1 at $DIR/inline-shims.rs:+1:38: +1:39 + _3 = std::ptr::drop_in_place::<Vec<A>>(move _4) -> bb1; // scope 1 at $DIR/inline-shims.rs:+1:14: +1:40 + // mir::Constant + // + span: $DIR/inline-shims.rs:11:14: 11:37 + // + literal: Const { ty: unsafe fn(*mut Vec<A>) {std::ptr::drop_in_place::<Vec<A>>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/inline-shims.rs:+1:39: +1:40 + StorageDead(_3); // scope 0 at $DIR/inline-shims.rs:+1:41: +1:42 + StorageLive(_5); // scope 2 at $DIR/inline-shims.rs:+2:38: +2:39 + _5 = _2; // scope 2 at $DIR/inline-shims.rs:+2:38: +2:39 +- _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> bb2; // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 +- // mir::Constant +- // + span: $DIR/inline-shims.rs:12:14: 12:37 +- // + literal: Const { ty: unsafe fn(*mut Option<B>) {std::ptr::drop_in_place::<Option<B>>}, val: Value(<ZST>) } ++ StorageLive(_6); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 ++ StorageLive(_7); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 ++ _6 = discriminant((*_5)); // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ switchInt(move _6) -> [0_isize: bb2, otherwise: bb3]; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + } + + bb2: { ++ StorageDead(_7); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 ++ StorageDead(_6); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40 + StorageDead(_5); // scope 2 at $DIR/inline-shims.rs:+2:39: +2:40 + return; // scope 0 at $DIR/inline-shims.rs:+3:2: +3:2 ++ } ++ ++ bb3: { ++ drop((((*_5) as Some).0: B)) -> bb2; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + } + } + diff --git a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff new file mode 100644 index 000000000..106291b36 --- /dev/null +++ b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff @@ -0,0 +1,28 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-specialization.rs:+0:11: +0:11 + let _1: u32; // in scope 0 at $DIR/inline-specialization.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/inline-specialization.rs:+1:9: +1:10 + } ++ scope 2 (inlined <Vec<()> as Foo>::bar) { // at $DIR/inline-specialization.rs:5:13: 5:38 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-specialization.rs:+1:9: +1:10 +- _1 = <Vec<()> as Foo>::bar() -> bb1; // scope 0 at $DIR/inline-specialization.rs:+1:13: +1:38 +- // mir::Constant +- // + span: $DIR/inline-specialization.rs:5:13: 5:36 +- // + literal: Const { ty: fn() -> u32 {<Vec<()> as Foo>::bar}, val: Value(<ZST>) } +- } +- +- bb1: { ++ _1 = const 123_u32; // scope 2 at $DIR/inline-specialization.rs:+10:31: +10:34 + _0 = const (); // scope 0 at $DIR/inline-specialization.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/inline-specialization.rs:+2:1: +2:2 + return; // scope 0 at $DIR/inline-specialization.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir new file mode 100644 index 000000000..ed95edd16 --- /dev/null +++ b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir @@ -0,0 +1,21 @@ +// MIR for `test` after Inline + +fn test(_1: &dyn X) -> u32 { + debug x => _1; // in scope 0 at $DIR/inline-trait-method.rs:+0:9: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/inline-trait-method.rs:+0:23: +0:26 + let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10 + _2 = &(*_1); // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10 + _0 = <dyn X as X>::y(move _2) -> bb1; // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10 + // mir::Constant + // + span: $DIR/inline-trait-method.rs:9:7: 9:8 + // + literal: Const { ty: for<'r> fn(&'r dyn X) -> u32 {<dyn X as X>::y}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/inline-trait-method.rs:+1:9: +1:10 + return; // scope 0 at $DIR/inline-trait-method.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir new file mode 100644 index 000000000..116ae4e36 --- /dev/null +++ b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir @@ -0,0 +1,32 @@ +// MIR for `test2` after Inline + +fn test2(_1: &dyn X) -> bool { + debug x => _1; // in scope 0 at $DIR/inline-trait-method_2.rs:+0:10: +0:11 + let mut _0: bool; // return place in scope 0 at $DIR/inline-trait-method_2.rs:+0:24: +0:28 + let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 + let mut _3: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 + scope 1 (inlined test) { // at $DIR/inline-trait-method_2.rs:5:5: 5:12 + debug x => _2; // in scope 1 at $DIR/inline-trait-method_2.rs:+5:9: +5:10 + let mut _4: &dyn X; // in scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 + StorageLive(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 + _3 = &(*_1); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 + _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11 + StorageLive(_4); // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10 + _4 = _2; // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10 + _0 = <dyn X as X>::y(move _4) -> bb1; // scope 1 at $DIR/inline-trait-method_2.rs:+6:5: +6:10 + // mir::Constant + // + span: $DIR/inline-trait-method_2.rs:10:7: 10:8 + // + literal: Const { ty: for<'r> fn(&'r dyn X) -> bool {<dyn X as X>::y}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/inline-trait-method_2.rs:+6:9: +6:10 + StorageDead(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:11: +1:12 + return; // scope 0 at $DIR/inline-trait-method_2.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs new file mode 100644 index 000000000..94f926d39 --- /dev/null +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs @@ -0,0 +1,27 @@ +// EMIT_MIR issue_58867_inline_as_ref_as_mut.a.Inline.after.mir +pub fn a<T>(x: &mut [T]) -> &mut [T] { + x.as_mut() +} + +// EMIT_MIR issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +pub fn b<T>(x: &mut Box<T>) -> &mut T { + x.as_mut() +} + +// EMIT_MIR issue_58867_inline_as_ref_as_mut.c.Inline.after.mir +pub fn c<T>(x: &[T]) -> &[T] { + x.as_ref() +} + +// EMIT_MIR issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +pub fn d<T>(x: &Box<T>) -> &T { + x.as_ref() +} + +fn main() { + let mut boxed = Box::new(1); + println!("{:?}", a(&mut [1])); + println!("{:?}", b(&mut boxed)); + println!("{:?}", c(&[1])); + println!("{:?}", d(&boxed)); +} diff --git a/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs b/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs new file mode 100644 index 000000000..76d806acc --- /dev/null +++ b/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs @@ -0,0 +1,7 @@ +// Tests that MIR inliner can handle `SourceScopeData` parenting correctly. (#76997) + +// EMIT_MIR issue_76997_inline_scopes_parenting.main.Inline.after.mir +fn main() { + let f = |x| { let y = x; y }; + f(()) +} diff --git a/src/test/mir-opt/inline/issue-78442.rs b/src/test/mir-opt/inline/issue-78442.rs new file mode 100644 index 000000000..aa8ede2df --- /dev/null +++ b/src/test/mir-opt/inline/issue-78442.rs @@ -0,0 +1,20 @@ +// compile-flags: -Z mir-opt-level=3 -Z inline-mir +// ignore-wasm32-bare compiled with panic=abort by default +#![crate_type = "lib"] + +// EMIT_MIR issue_78442.bar.RevealAll.diff +// EMIT_MIR issue_78442.bar.Inline.diff +pub fn bar<P>( + // Error won't happen if "bar" is not generic + _baz: P, +) { + hide_foo()(); +} + +fn hide_foo() -> impl Fn() { + // Error won't happen if "iterate" hasn't impl Trait or has generics + foo +} + +fn foo() { // Error won't happen if "foo" isn't used in "iterate" or has generics +} diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir new file mode 100644 index 000000000..5168ae031 --- /dev/null +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir @@ -0,0 +1,30 @@ +// MIR for `a` after Inline + +fn a(_1: &mut [T]) -> &mut [T] { + debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14 + let mut _0: &mut [T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:29: +0:37 + let mut _2: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + let mut _3: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + let mut _4: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 + debug self => _4; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + let mut _5: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + _5 = &mut (*_4); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + _3 = &mut (*_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15 + _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 + StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir new file mode 100644 index 000000000..4006dd15a --- /dev/null +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -0,0 +1,42 @@ +// MIR for `b` after Inline + +fn b(_1: &mut Box<T>) -> &mut T { + debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14 + let mut _0: &mut T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:32: +0:38 + let mut _2: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + let mut _3: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + let mut _4: &mut std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + scope 1 (inlined <Box<T> as AsMut<T>>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 + debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _6: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _7: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _8: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageLive(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _7 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageLive(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _8 = (((_7.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _6 = &mut (*_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _5 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15 + _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 + StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir new file mode 100644 index 000000000..c7f20ff98 --- /dev/null +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir @@ -0,0 +1,22 @@ +// MIR for `c` after Inline + +fn c(_1: &[T]) -> &[T] { + debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14 + let mut _0: &[T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:25: +0:29 + let _2: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + let mut _3: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:15 + debug self => _3; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + _2 = _3; // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15 + StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir new file mode 100644 index 000000000..e516269c1 --- /dev/null +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -0,0 +1,30 @@ +// MIR for `d` after Inline + +fn d(_1: &Box<T>) -> &T { + debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14 + let mut _0: &T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:28: +0:30 + let _2: &T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + let mut _3: &std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + scope 1 (inlined <Box<T> as AsRef<T>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 + debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _4: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _5: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageLive(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _4 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _5 = (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15 + StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15 + StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir new file mode 100644 index 000000000..fca53a72f --- /dev/null +++ b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir @@ -0,0 +1,42 @@ +// MIR for `main` after Inline + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+0:11: +0:11 + let _1: [closure@$DIR/issue-76997-inline-scopes-parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10 + let mut _2: &[closure@$DIR/issue-76997-inline-scopes-parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6 + let mut _3: ((),); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + let mut _4: (); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9 + let mut _5: (); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + scope 1 { + debug f => _1; // in scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10 + scope 2 (inlined main::{closure#0}) { // at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 + debug x => _5; // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:14: +1:15 + let _6: (); // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24 + scope 3 { + debug y => _6; // in scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10 + Deinit(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:13: +1:33 + StorageLive(_2); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6 + _2 = &_1; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6 + StorageLive(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + StorageLive(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9 + Deinit(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9 + Deinit(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + (_3.0: ()) = move _4; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + StorageLive(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + _5 = move (_3.0: ()); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + StorageLive(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24 + StorageDead(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:32: +1:33 + StorageDead(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10 + StorageDead(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10 + StorageDead(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10 + StorageDead(_2); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10 + StorageDead(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+3:1: +3:2 + return; // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+3:2: +3:2 + } +} diff --git a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff new file mode 100644 index 000000000..c16dfdf39 --- /dev/null +++ b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff @@ -0,0 +1,68 @@ +- // MIR for `bar` before Inline ++ // MIR for `bar` after Inline + + fn bar(_1: P) -> () { + debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:+2:5: +2:9 + let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:+3:3: +3:3 + let _2: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 ++ scope 1 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) { // at $DIR/issue-78442.rs:11:5: 11:17 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 +- _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 ++ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + // mir::Constant + // + span: $DIR/issue-78442.rs:11:5: 11:13 + // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(<ZST>) } + } + + bb1: { + _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 +- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 +- // mir::Constant +- // + span: $DIR/issue-78442.rs:11:5: 11:15 +- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r fn() {foo}, ()) -> <fn() {foo} as FnOnce<()>>::Output {<fn() {foo} as Fn<()>>::call}, val: Value(<ZST>) } ++ _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $SRC_DIR/core/src/ops/function.rs:LL:COL + } + + bb2: { +- StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 +- StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 +- StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 +- StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 +- _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 +- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 ++ return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 + } + +- bb3: { +- return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 ++ bb3 (cleanup): { ++ drop(_1) -> bb4; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + } + + bb4 (cleanup): { +- drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 ++ resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 + } + +- bb5 (cleanup): { +- resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 ++ bb5: { ++ StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 ++ StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 ++ StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 ++ StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 ++ _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 ++ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + } + } + diff --git a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff new file mode 100644 index 000000000..0faa522cb --- /dev/null +++ b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff @@ -0,0 +1,57 @@ +- // MIR for `bar` before RevealAll ++ // MIR for `bar` after RevealAll + + fn bar(_1: P) -> () { + debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:+2:5: +2:9 + let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:+3:3: +3:3 + let _2: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 +- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 +- let _4: impl Fn(); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 ++ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 ++ let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + // mir::Constant + // + span: $DIR/issue-78442.rs:11:5: 11:13 + // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(<ZST>) } + } + + bb1: { + _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 +- _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 ++ _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 + // mir::Constant + // + span: $DIR/issue-78442.rs:11:5: 11:15 +- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(<ZST>) } ++ // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r fn() {foo}, ()) -> <fn() {foo} as FnOnce<()>>::Output {<fn() {foo} as Fn<()>>::call}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 + StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 + StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 + StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 + _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 + drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + } + + bb3: { + return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 + } + + bb4 (cleanup): { + drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 + } + } + diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff new file mode 100644 index 000000000..b78ef36ea --- /dev/null +++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff @@ -0,0 +1,13 @@ +- // MIR for `bar` before InstrumentCoverage ++ // MIR for `bar` after InstrumentCoverage + + fn bar() -> bool { + let mut _0: bool; // return place in scope 0 at /the/src/instrument_coverage.rs:+0:13: +0:17 + + bb0: { ++ Coverage::Counter(1) for /the/src/instrument_coverage.rs:19:1 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2 + _0 = const true; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +1:9 + return; // scope 0 at /the/src/instrument_coverage.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff new file mode 100644 index 000000000..0490c0df2 --- /dev/null +++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -0,0 +1,51 @@ +- // MIR for `main` before InstrumentCoverage ++ // MIR for `main` after InstrumentCoverage + + fn main() -> () { + let mut _0: (); // return place in scope 0 at /the/src/instrument_coverage.rs:+0:11: +0:11 + let mut _1: (); // in scope 0 at /the/src/instrument_coverage.rs:+0:1: +6:2 + let mut _2: bool; // in scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17 + let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:+2:18: +4:10 + + bb0: { ++ Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 10:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6 + goto -> bb1; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6 + } + + bb1: { ++ Coverage::Expression(4294967295) = 1 + 2 for /the/src/instrument_coverage.rs:11:5 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6 + falseUnwind -> [real: bb2, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6 + } + + bb2: { + StorageLive(_2); // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17 + _2 = bar() -> [return: bb3, unwind: bb6]; // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17 + // mir::Constant + // + span: /the/src/instrument_coverage.rs:12:12: 12:15 + // + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) } + } + + bb3: { + switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17 + } + + bb4: { ++ Coverage::Expression(4294967293) = 4294967294 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2 ++ Coverage::Expression(4294967294) = 4294967295 - 2 for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2 + _0 = const (); // scope 0 at /the/src/instrument_coverage.rs:+3:13: +3:18 + StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:+4:9: +4:10 + return; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2 + } + + bb5: { ++ Coverage::Counter(2) for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6 + _1 = const (); // scope 0 at /the/src/instrument_coverage.rs:+4:10: +4:10 + StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:+4:9: +4:10 + goto -> bb1; // scope 0 at /the/src/instrument_coverage.rs:+1:5: +5:6 + } + + bb6 (cleanup): { + resume; // scope 0 at /the/src/instrument_coverage.rs:+0:1: +6:2 + } + } + diff --git a/src/test/mir-opt/instrument_coverage.rs b/src/test/mir-opt/instrument_coverage.rs new file mode 100644 index 000000000..a748f2c5c --- /dev/null +++ b/src/test/mir-opt/instrument_coverage.rs @@ -0,0 +1,36 @@ +// Test that `-C instrument-coverage` injects Coverage statements. The Coverage Counter statements +// are later converted into LLVM instrprof.increment intrinsics, during codegen. + +// needs-profiler-support +// ignore-windows +// compile-flags: -C instrument-coverage --remap-path-prefix={{src-base}}=/the/src + +// EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff +// EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff +fn main() { + loop { + if bar() { + break; + } + } +} + +#[inline(never)] +fn bar() -> bool { + true +} + +// Note that the MIR with injected coverage intrinsics includes references to source locations, +// including the source file absolute path. Typically, MIR pretty print output with file +// references are safe because the file prefixes are substituted with `$DIR`, but in this case +// the file references are encoded as function arguments, with an `Operand` type representation +// (`Slice` `Allocation` interned byte array) that cannot be normalized by simple substitution. +// +// The first workaround is to use the `SourceMap`-supported `--remap-path-prefix` option; however, +// the implementation of the `--remap-path-prefix` option currently joins the new prefix and the +// remaining source path with an OS-specific path separator (`\` on Windows). This difference still +// shows up in the byte array representation of the path, causing Windows tests to fail to match +// blessed results baselined with a `/` path separator. +// +// Since this `mir-opt` test does not have any significant platform dependencies, other than the +// path separator differences, the final workaround is to disable testing on Windows. diff --git a/src/test/mir-opt/issue-38669.rs b/src/test/mir-opt/issue-38669.rs new file mode 100644 index 000000000..db3f89472 --- /dev/null +++ b/src/test/mir-opt/issue-38669.rs @@ -0,0 +1,12 @@ +// check that we don't StorageDead booleans before they are used + +// EMIT_MIR issue_38669.main.SimplifyCfg-initial.after.mir +fn main() { + let mut should_break = false; + loop { + if should_break { + break; + } + should_break = true; + } +} diff --git a/src/test/mir-opt/issue-41110.rs b/src/test/mir-opt/issue-41110.rs new file mode 100644 index 000000000..638dc601e --- /dev/null +++ b/src/test/mir-opt/issue-41110.rs @@ -0,0 +1,30 @@ +// ignore-wasm32-bare compiled with panic=abort by default + +// check that we don't emit multiple drop flags when they are not needed. + + +// EMIT_MIR issue_41110.main.ElaborateDrops.after.mir +fn main() { + let x = S.other(S.id()); +} + +// no_mangle to make sure this gets instantiated even in an executable. +#[no_mangle] +// EMIT_MIR issue_41110.test.ElaborateDrops.after.mir +pub fn test() { + let u = S; + let mut v = S; + drop(v); + v = u; +} + +struct S; +impl Drop for S { + fn drop(&mut self) { + } +} + +impl S { + fn id(self) -> Self { self } + fn other(self, s: Self) {} +} diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs new file mode 100644 index 000000000..5c34d8e68 --- /dev/null +++ b/src/test/mir-opt/issue-41697.rs @@ -0,0 +1,40 @@ +// Regression test for #41697. Using dump-mir was triggering +// artificial cycles: during type-checking, we had to get the MIR for +// the constant expressions in `[u8; 2]`, which in turn would trigger +// an attempt to get the def-path, which in turn would request the +// types of the impl, which would trigger a cycle. We suppressed this +// cycle now by forcing mir-dump to avoid asking for types of an impl. + +#![feature(rustc_attrs)] + +use std::sync::Arc; + +trait Foo { + fn get(&self) -> [u8; 2]; +} + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir +impl Foo for [u8; 1+1] { + fn get(&self) -> [u8; 2] { + *self + } +} + +struct Bar<T: ?Sized>(T); + +fn unsize_fat_ptr<'a>(x: &'a Bar<Foo + Send + 'a>) -> &'a Bar<Foo + 'a> { + x +} + +fn unsize_nested_fat_ptr(x: Arc<Foo + Send>) -> Arc<Foo> { + x +} + +fn main() { + let x: Box<Bar<Foo + Send>> = Box::new(Bar([1,2])); + assert_eq!(unsize_fat_ptr(&*x).0.get(), [1, 2]); + + let x: Arc<Foo + Send> = Arc::new([3, 4]); + assert_eq!(unsize_nested_fat_ptr(x).get(), [3, 4]); +} diff --git a/src/test/mir-opt/issue-41888.rs b/src/test/mir-opt/issue-41888.rs new file mode 100644 index 000000000..c1046c14d --- /dev/null +++ b/src/test/mir-opt/issue-41888.rs @@ -0,0 +1,24 @@ +// ignore-wasm32-bare compiled with panic=abort by default +// check that we clear the "ADT master drop flag" even when there are +// no fields to be dropped. + +// EMIT_MIR issue_41888.main.ElaborateDrops.after.mir +fn main() { + let e; + if cond() { + e = E::F(K); + if let E::F(_k) = e { + // older versions of rustc used to not clear the + // drop flag for `e` in this path. + } + } +} + +fn cond() -> bool { false } + +struct K; + +enum E { + F(K), + G(Box<E>) +} diff --git a/src/test/mir-opt/issue-49232.rs b/src/test/mir-opt/issue-49232.rs new file mode 100644 index 000000000..86494c76a --- /dev/null +++ b/src/test/mir-opt/issue-49232.rs @@ -0,0 +1,15 @@ +// We must mark a variable whose initialization fails due to an +// abort statement as StorageDead. + +// EMIT_MIR issue_49232.main.mir_map.0.mir +fn main() { + loop { + let beacon = { + match true { + false => 4, + true => break, + } + }; + drop(&beacon); + } +} diff --git a/src/test/mir-opt/issue-62289.rs b/src/test/mir-opt/issue-62289.rs new file mode 100644 index 000000000..37e3390d5 --- /dev/null +++ b/src/test/mir-opt/issue-62289.rs @@ -0,0 +1,14 @@ +// check that we don't forget to drop the Box if we early return before +// initializing it +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(box_syntax)] + +// EMIT_MIR issue_62289.test.ElaborateDrops.before.mir +fn test() -> Option<Box<u32>> { + Some(box (None?)) +} + +fn main() { + test(); +} diff --git a/src/test/mir-opt/issue-72181-1.rs b/src/test/mir-opt/issue-72181-1.rs new file mode 100644 index 000000000..91e98adbe --- /dev/null +++ b/src/test/mir-opt/issue-72181-1.rs @@ -0,0 +1,21 @@ +// compile-flags: -Z mir-opt-level=1 +// Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags. + +#![feature(never_type)] +#![allow(unused, invalid_value)] + +enum Void {} + +// EMIT_MIR issue_72181_1.f.mir_map.0.mir +fn f(v: Void) -> ! { + match v {} +} + +// EMIT_MIR issue_72181_1.main.mir_map.0.mir +fn main() { + let v: Void = unsafe { + std::mem::transmute::<(), Void>(()) + }; + + f(v); +} diff --git a/src/test/mir-opt/issue-72181.rs b/src/test/mir-opt/issue-72181.rs new file mode 100644 index 000000000..844d53a4b --- /dev/null +++ b/src/test/mir-opt/issue-72181.rs @@ -0,0 +1,28 @@ +// compile-flags: -Z mir-opt-level=1 +// Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags. + +use std::mem; + +#[derive(Copy, Clone)] +enum Never {} + +union Foo { + a: u64, + b: Never +} + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR issue_72181.foo.mir_map.0.mir +fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 } + +// EMIT_MIR issue_72181.bar.mir_map.0.mir +fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x } + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR issue_72181.main.mir_map.0.mir +fn main() { + let _ = mem::size_of::<Foo>(); + + let f = [Foo { a: 42 }, Foo { a: 10 }]; + let _ = unsafe { f[0].a }; +} diff --git a/src/test/mir-opt/issue-73223.rs b/src/test/mir-opt/issue-73223.rs new file mode 100644 index 000000000..703b87612 --- /dev/null +++ b/src/test/mir-opt/issue-73223.rs @@ -0,0 +1,13 @@ +fn main() { + let split = match Some(1) { + Some(v) => v, + None => return, + }; + + let _prev = Some(split); + assert_eq!(split, 1); +} + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff +// EMIT_MIR issue_73223.main.PreCodegen.diff diff --git a/src/test/mir-opt/issue-78192.rs b/src/test/mir-opt/issue-78192.rs new file mode 100644 index 000000000..39f665402 --- /dev/null +++ b/src/test/mir-opt/issue-78192.rs @@ -0,0 +1,11 @@ +// compile-flags: -Zmir-opt-level=1 -Zinline-mir +pub fn f<T>(a: &T) -> *const T { + let b: &*const T = &(a as *const T); + *b +} + +fn main() { + f(&2); +} + +// EMIT_MIR issue_78192.f.InstCombine.diff diff --git a/src/test/mir-opt/issue-99325.rs b/src/test/mir-opt/issue-99325.rs new file mode 100644 index 000000000..b79946ea8 --- /dev/null +++ b/src/test/mir-opt/issue-99325.rs @@ -0,0 +1,12 @@ +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] { + BYTES +} + +// EMIT_MIR issue_99325.main.mir_map.0.mir +pub fn main() { + assert_eq!(function_with_bytes::<b"AAAA">(), &[0x41, 0x41, 0x41, 0x41]); + assert_eq!(function_with_bytes::<{ &[0x41, 0x41, 0x41, 0x41] }>(), b"AAAA"); +} diff --git a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..b13987f73 --- /dev/null +++ b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir @@ -0,0 +1,52 @@ +// MIR for `main` after SimplifyCfg-initial + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-38669.rs:+0:11: +0:11 + let mut _1: bool; // in scope 0 at $DIR/issue-38669.rs:+1:9: +1:25 + let mut _2: (); // in scope 0 at $DIR/issue-38669.rs:+0:1: +8:2 + let _3: (); // in scope 0 at $DIR/issue-38669.rs:+3:9: +5:10 + let mut _4: bool; // in scope 0 at $DIR/issue-38669.rs:+3:12: +3:24 + let mut _5: !; // in scope 0 at $DIR/issue-38669.rs:+3:25: +5:10 + scope 1 { + debug should_break => _1; // in scope 1 at $DIR/issue-38669.rs:+1:9: +1:25 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-38669.rs:+1:9: +1:25 + _1 = const false; // scope 0 at $DIR/issue-38669.rs:+1:28: +1:33 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue-38669.rs:+1:9: +1:25 + goto -> bb1; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6 + } + + bb1: { + falseUnwind -> [real: bb2, cleanup: bb5]; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6 + } + + bb2: { + StorageLive(_3); // scope 1 at $DIR/issue-38669.rs:+3:9: +5:10 + StorageLive(_4); // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24 + _4 = _1; // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24 + switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24 + } + + bb3: { + _0 = const (); // scope 1 at $DIR/issue-38669.rs:+4:13: +4:18 + StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10 + StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10 + StorageDead(_1); // scope 0 at $DIR/issue-38669.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue-38669.rs:+8:2: +8:2 + } + + bb4: { + _3 = const (); // scope 1 at $DIR/issue-38669.rs:+5:10: +5:10 + StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10 + StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10 + _1 = const true; // scope 1 at $DIR/issue-38669.rs:+6:9: +6:28 + _2 = const (); // scope 1 at $DIR/issue-38669.rs:+2:10: +7:6 + goto -> bb1; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6 + } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/issue-38669.rs:+0:1: +8:2 + } +} diff --git a/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir new file mode 100644 index 000000000..1d7cb91d6 --- /dev/null +++ b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir @@ -0,0 +1,70 @@ +// MIR for `main` after ElaborateDrops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-41110.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 + let mut _2: S; // in scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 + let mut _3: S; // in scope 0 at $DIR/issue-41110.rs:+1:21: +1:27 + let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:+1:21: +1:22 + let mut _5: bool; // in scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + scope 1 { + debug x => _1; // in scope 1 at $DIR/issue-41110.rs:+1:9: +1:10 + } + + bb0: { + _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 + _5 = const true; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 + _2 = S; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 + StorageLive(_3); // scope 0 at $DIR/issue-41110.rs:+1:21: +1:27 + StorageLive(_4); // scope 0 at $DIR/issue-41110.rs:+1:21: +1:22 + _4 = S; // scope 0 at $DIR/issue-41110.rs:+1:21: +1:22 + _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-41110.rs:+1:21: +1:27 + // mir::Constant + // + span: $DIR/issue-41110.rs:8:23: 8:25 + // + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_4); // scope 0 at $DIR/issue-41110.rs:+1:26: +1:27 + _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:28 + _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:28 + // mir::Constant + // + span: $DIR/issue-41110.rs:8:15: 8:20 + // + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + StorageDead(_2); // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + _0 = const (); // scope 0 at $DIR/issue-41110.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue-41110.rs:+2:2: +2:2 + } + + bb3 (cleanup): { + goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + } + + bb4 (cleanup): { + goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+1:26: +1:27 + } + + bb5 (cleanup): { + goto -> bb8; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/issue-41110.rs:+0:1: +2:2 + } + + bb7 (cleanup): { + drop(_2) -> bb6; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + } + + bb8 (cleanup): { + switchInt(_5) -> [false: bb6, otherwise: bb7]; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28 + } +} diff --git a/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir new file mode 100644 index 000000000..b0e3496b2 --- /dev/null +++ b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir @@ -0,0 +1,101 @@ +// MIR for `test` after ElaborateDrops + +fn test() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-41110.rs:+0:15: +0:15 + let _1: S; // in scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 + let _3: (); // in scope 0 at $DIR/issue-41110.rs:+3:5: +3:12 + let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:+3:10: +3:11 + let mut _5: S; // in scope 0 at $DIR/issue-41110.rs:+4:9: +4:10 + let mut _6: bool; // in scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + scope 1 { + debug u => _1; // in scope 1 at $DIR/issue-41110.rs:+1:9: +1:10 + let mut _2: S; // in scope 1 at $DIR/issue-41110.rs:+2:9: +2:14 + scope 2 { + debug v => _2; // in scope 2 at $DIR/issue-41110.rs:+2:9: +2:14 + } + } + + bb0: { + _6 = const false; // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10 + _6 = const true; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 + _1 = S; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/issue-41110.rs:+2:9: +2:14 + _2 = S; // scope 1 at $DIR/issue-41110.rs:+2:17: +2:18 + StorageLive(_3); // scope 2 at $DIR/issue-41110.rs:+3:5: +3:12 + StorageLive(_4); // scope 2 at $DIR/issue-41110.rs:+3:10: +3:11 + _4 = move _2; // scope 2 at $DIR/issue-41110.rs:+3:10: +3:11 + _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue-41110.rs:+3:5: +3:12 + // mir::Constant + // + span: $DIR/issue-41110.rs:17:5: 17:9 + // + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_4); // scope 2 at $DIR/issue-41110.rs:+3:11: +3:12 + StorageDead(_3); // scope 2 at $DIR/issue-41110.rs:+3:12: +3:13 + StorageLive(_5); // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 + _6 = const false; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 + _5 = move _1; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 + goto -> bb12; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 + } + + bb2: { + goto -> bb3; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 + } + + bb3: { + StorageDead(_5); // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 + _0 = const (); // scope 0 at $DIR/issue-41110.rs:+0:15: +5:2 + drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2 + } + + bb4: { + StorageDead(_2); // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2 + goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + } + + bb5: { + _6 = const false; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue-41110.rs:+5:2: +5:2 + } + + bb6 (cleanup): { + goto -> bb8; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10 + } + + bb7 (cleanup): { + goto -> bb8; // scope 2 at $DIR/issue-41110.rs:+3:11: +3:12 + } + + bb8 (cleanup): { + goto -> bb9; // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2 + } + + bb9 (cleanup): { + goto -> bb14; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + } + + bb10 (cleanup): { + resume; // scope 0 at $DIR/issue-41110.rs:+0:1: +5:2 + } + + bb11 (cleanup): { + _2 = move _5; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 + goto -> bb6; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 + } + + bb12: { + _2 = move _5; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 + goto -> bb2; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6 + } + + bb13 (cleanup): { + drop(_1) -> bb10; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + } + + bb14 (cleanup): { + switchInt(_6) -> [false: bb10, otherwise: bb13]; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2 + } +} diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir new file mode 100644 index 000000000..047b24db4 --- /dev/null +++ b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.32bit.mir @@ -0,0 +1,20 @@ +// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts + +<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = { + let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + let mut _1: (usize, bool); // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + + bb0: { + _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + } + + bb1: { + _0 = move (_1.0: usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + return; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + } +} diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir new file mode 100644 index 000000000..047b24db4 --- /dev/null +++ b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.64bit.mir @@ -0,0 +1,20 @@ +// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts + +<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = { + let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + let mut _1: (usize, bool); // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + + bb0: { + _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + } + + bb1: { + _0 = move (_1.0: usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + return; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22 + } +} diff --git a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir new file mode 100644 index 000000000..f95a0a1c0 --- /dev/null +++ b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir @@ -0,0 +1,152 @@ +// MIR for `main` after ElaborateDrops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-41888.rs:+0:11: +0:11 + let _1: E; // in scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 + let mut _2: bool; // in scope 0 at $DIR/issue-41888.rs:+2:8: +2:14 + let mut _3: E; // in scope 0 at $DIR/issue-41888.rs:+3:13: +3:20 + let mut _4: K; // in scope 0 at $DIR/issue-41888.rs:+3:18: +3:19 + let mut _5: isize; // in scope 0 at $DIR/issue-41888.rs:+4:16: +4:24 + let mut _7: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + let mut _8: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + let mut _9: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + let mut _10: isize; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + let mut _11: isize; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + scope 1 { + debug e => _1; // in scope 1 at $DIR/issue-41888.rs:+1:9: +1:10 + scope 2 { + debug _k => _6; // in scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 + let _6: K; // in scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 + } + } + + bb0: { + _9 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 + _7 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 + _8 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14 + _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14 + // mir::Constant + // + span: $DIR/issue-41888.rs:8:8: 8:12 + // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) } + } + + bb1: { + switchInt(move _2) -> [false: bb7, otherwise: bb2]; // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14 + } + + bb2: { + StorageLive(_3); // scope 1 at $DIR/issue-41888.rs:+3:13: +3:20 + StorageLive(_4); // scope 1 at $DIR/issue-41888.rs:+3:18: +3:19 + _4 = K; // scope 1 at $DIR/issue-41888.rs:+3:18: +3:19 + _3 = E::F(move _4); // scope 1 at $DIR/issue-41888.rs:+3:13: +3:20 + StorageDead(_4); // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20 + goto -> bb14; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + } + + bb3: { + goto -> bb4; // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20 + } + + bb4: { + StorageDead(_3); // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20 + _5 = discriminant(_1); // scope 2 at $DIR/issue-41888.rs:+4:16: +4:24 + switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 2 at $DIR/issue-41888.rs:+4:16: +4:24 + } + + bb5: { + StorageLive(_6); // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 + _9 = const false; // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 + _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23 + _0 = const (); // scope 2 at $DIR/issue-41888.rs:+4:29: +7:10 + StorageDead(_6); // scope 1 at $DIR/issue-41888.rs:+7:9: +7:10 + goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+4:9: +7:10 + } + + bb6: { + _0 = const (); // scope 1 at $DIR/issue-41888.rs:+7:10: +7:10 + goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+4:9: +7:10 + } + + bb7: { + _0 = const (); // scope 1 at $DIR/issue-41888.rs:+8:6: +8:6 + goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+2:5: +8:6 + } + + bb8: { + StorageDead(_2); // scope 1 at $DIR/issue-41888.rs:+8:5: +8:6 + goto -> bb20; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb9: { + _7 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + _8 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + _9 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + StorageDead(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + return; // scope 0 at $DIR/issue-41888.rs:+9:2: +9:2 + } + + bb10 (cleanup): { + goto -> bb11; // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20 + } + + bb11 (cleanup): { + goto -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb12 (cleanup): { + resume; // scope 0 at $DIR/issue-41888.rs:+0:1: +9:2 + } + + bb13 (cleanup): { + _7 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + _8 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + _9 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + goto -> bb10; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + } + + bb14: { + _7 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + _8 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + _9 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + goto -> bb3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10 + } + + bb15: { + _7 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + goto -> bb9; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb16 (cleanup): { + goto -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb17: { + drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb18 (cleanup): { + drop(_1) -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb19: { + _10 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + switchInt(move _10) -> [0_isize: bb15, otherwise: bb17]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb20: { + switchInt(_7) -> [false: bb15, otherwise: bb19]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb21 (cleanup): { + _11 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + switchInt(move _11) -> [0_isize: bb16, otherwise: bb18]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } + + bb22 (cleanup): { + switchInt(_7) -> [false: bb12, otherwise: bb21]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2 + } +} diff --git a/src/test/mir-opt/issue_49232.main.mir_map.0.mir b/src/test/mir-opt/issue_49232.main.mir_map.0.mir new file mode 100644 index 000000000..821323b5e --- /dev/null +++ b/src/test/mir-opt/issue_49232.main.mir_map.0.mir @@ -0,0 +1,82 @@ +// MIR for `main` 0 mir_map + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-49232.rs:+0:11: +0:11 + let mut _1: (); // in scope 0 at $DIR/issue-49232.rs:+0:1: +10:2 + let _2: i32; // in scope 0 at $DIR/issue-49232.rs:+2:13: +2:19 + let mut _3: bool; // in scope 0 at $DIR/issue-49232.rs:+3:19: +3:23 + let mut _4: !; // in scope 0 at $DIR/issue-49232.rs:+5:25: +5:30 + let _5: (); // in scope 0 at $DIR/issue-49232.rs:+8:9: +8:22 + let mut _6: &i32; // in scope 0 at $DIR/issue-49232.rs:+8:14: +8:21 + scope 1 { + debug beacon => _2; // in scope 1 at $DIR/issue-49232.rs:+2:13: +2:19 + } + + bb0: { + goto -> bb1; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6 + } + + bb1: { + falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6 + } + + bb2: { + StorageLive(_2); // scope 0 at $DIR/issue-49232.rs:+2:13: +2:19 + StorageLive(_3); // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23 + _3 = const true; // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23 + FakeRead(ForMatchedPlace(None), _3); // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23 + switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/issue-49232.rs:+3:13: +3:23 + } + + bb3: { + falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at $DIR/issue-49232.rs:+4:17: +4:22 + } + + bb4: { + _0 = const (); // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30 + goto -> bb10; // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30 + } + + bb5: { + _2 = const 4_i32; // scope 0 at $DIR/issue-49232.rs:+4:26: +4:27 + goto -> bb8; // scope 0 at $DIR/issue-49232.rs:+4:26: +4:27 + } + + bb6: { + unreachable; // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30 + } + + bb7: { + goto -> bb8; // scope 0 at $DIR/issue-49232.rs:+6:13: +6:14 + } + + bb8: { + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-49232.rs:+2:13: +2:19 + StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:+7:10: +7:11 + StorageLive(_5); // scope 1 at $DIR/issue-49232.rs:+8:9: +8:22 + StorageLive(_6); // scope 1 at $DIR/issue-49232.rs:+8:14: +8:21 + _6 = &_2; // scope 1 at $DIR/issue-49232.rs:+8:14: +8:21 + _5 = std::mem::drop::<&i32>(move _6) -> [return: bb9, unwind: bb11]; // scope 1 at $DIR/issue-49232.rs:+8:9: +8:22 + // mir::Constant + // + span: $DIR/issue-49232.rs:13:9: 13:13 + // + literal: Const { ty: fn(&i32) {std::mem::drop::<&i32>}, val: Value(<ZST>) } + } + + bb9: { + StorageDead(_6); // scope 1 at $DIR/issue-49232.rs:+8:21: +8:22 + StorageDead(_5); // scope 1 at $DIR/issue-49232.rs:+8:22: +8:23 + _1 = const (); // scope 0 at $DIR/issue-49232.rs:+1:10: +9:6 + StorageDead(_2); // scope 0 at $DIR/issue-49232.rs:+9:5: +9:6 + goto -> bb1; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6 + } + + bb10: { + StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:+7:10: +7:11 + StorageDead(_2); // scope 0 at $DIR/issue-49232.rs:+9:5: +9:6 + return; // scope 0 at $DIR/issue-49232.rs:+10:2: +10:2 + } + + bb11 (cleanup): { + resume; // scope 0 at $DIR/issue-49232.rs:+0:1: +10:2 + } +} diff --git a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir new file mode 100644 index 000000000..72603dc5d --- /dev/null +++ b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir @@ -0,0 +1,122 @@ +// MIR for `test` before ElaborateDrops + +fn test() -> Option<Box<u32>> { + let mut _0: std::option::Option<std::boxed::Box<u32>>; // return place in scope 0 at $DIR/issue-62289.rs:+0:14: +0:30 + let mut _1: std::boxed::Box<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + let mut _2: usize; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + let mut _3: usize; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + let mut _4: *mut u8; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + let mut _5: std::boxed::Box<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + let mut _6: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:19 + let mut _8: isize; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + let _9: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + let mut _10: !; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + let mut _11: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + let _12: u32; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + scope 1 { + } + scope 2 { + debug residual => _9; // in scope 2 at $DIR/issue-62289.rs:+1:19: +1:20 + scope 3 { + } + } + scope 4 { + debug val => _12; // in scope 4 at $DIR/issue-62289.rs:+1:15: +1:20 + scope 5 { + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + _2 = SizeOf(u32); // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21 + _3 = AlignOf(u32); // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21 + // mir::Constant + // + span: $DIR/issue-62289.rs:9:10: 9:21 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + _5 = ShallowInitBox(move _4, u32); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + StorageLive(_6); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + StorageLive(_7); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:19 + _7 = Option::<u32>::None; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:19 + _6 = <Option<u32> as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + // mir::Constant + // + span: $DIR/issue-62289.rs:9:15: 9:20 + // + literal: Const { ty: fn(Option<u32>) -> ControlFlow<<Option<u32> as Try>::Residual, <Option<u32> as Try>::Output> {<Option<u32> as Try>::branch}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_7); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + _8 = discriminant(_6); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + switchInt(move _8) -> [0_isize: bb3, 1_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + } + + bb3: { + StorageLive(_12); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + _12 = ((_6 as Continue).0: u32); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + (*_5) = _12; // scope 5 at $DIR/issue-62289.rs:+1:15: +1:20 + StorageDead(_12); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + _1 = move _5; // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21 + drop(_5) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 + } + + bb4: { + unreachable; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20 + } + + bb5: { + StorageLive(_9); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + _9 = ((_6 as Break).0: std::option::Option<std::convert::Infallible>); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + StorageLive(_11); // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20 + _11 = _9; // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20 + _0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; // scope 3 at $DIR/issue-62289.rs:+1:15: +1:20 + // mir::Constant + // + span: $DIR/issue-62289.rs:9:19: 9:20 + // + literal: Const { ty: fn(Option<Infallible>) -> Option<Box<u32>> {<Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual}, val: Value(<ZST>) } + } + + bb6: { + StorageDead(_11); // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20 + StorageDead(_9); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20 + drop(_5) -> bb9; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 + } + + bb7: { + StorageDead(_5); // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 + _0 = Option::<Box<u32>>::Some(move _1); // scope 0 at $DIR/issue-62289.rs:+1:5: +1:22 + drop(_1) -> bb8; // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22 + } + + bb8: { + StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22 + StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:+2:1: +2:2 + goto -> bb10; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2 + } + + bb9: { + StorageDead(_5); // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 + StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22 + StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:+2:1: +2:2 + goto -> bb10; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2 + } + + bb10: { + return; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2 + } + + bb11 (cleanup): { + drop(_1) -> bb13; // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22 + } + + bb12 (cleanup): { + drop(_5) -> bb13; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21 + } + + bb13 (cleanup): { + resume; // scope 0 at $DIR/issue-62289.rs:+0:1: +2:2 + } +} diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir new file mode 100644 index 000000000..972ce1d50 --- /dev/null +++ b/src/test/mir-opt/issue_72181.bar.mir_map.0.32bit.mir @@ -0,0 +1,17 @@ +// MIR for `bar` 0 mir_map + +fn bar(_1: [(Never, u32); 1]) -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43 + let _2: u32; // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 + scope 1 { + debug x => _2; // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 + _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 + _0 = _2; // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47 + StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49 + return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49 + } +} diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir new file mode 100644 index 000000000..972ce1d50 --- /dev/null +++ b/src/test/mir-opt/issue_72181.bar.mir_map.0.64bit.mir @@ -0,0 +1,17 @@ +// MIR for `bar` 0 mir_map + +fn bar(_1: [(Never, u32); 1]) -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43 + let _2: u32; // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 + scope 1 { + debug x => _2; // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 + _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14 + _0 = _2; // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47 + StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49 + return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49 + } +} diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir new file mode 100644 index 000000000..534f131ea --- /dev/null +++ b/src/test/mir-opt/issue_72181.foo.mir_map.0.32bit.mir @@ -0,0 +1,27 @@ +// MIR for `foo` 0 mir_map + +fn foo(_1: [(Never, u32); 1]) -> u32 { + debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37 + let _2: usize; // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 + let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 + _2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 + _3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + _4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + } + + bb1: { + _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47 + StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49 + return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49 + } +} diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir new file mode 100644 index 000000000..534f131ea --- /dev/null +++ b/src/test/mir-opt/issue_72181.foo.mir_map.0.64bit.mir @@ -0,0 +1,27 @@ +// MIR for `foo` 0 mir_map + +fn foo(_1: [(Never, u32); 1]) -> u32 { + debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10 + let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37 + let _2: usize; // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 + let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 + _2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44 + _3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + _4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45 + } + + bb1: { + _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47 + StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49 + return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49 + } +} diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir new file mode 100644 index 000000000..425906f84 --- /dev/null +++ b/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir @@ -0,0 +1,62 @@ +// MIR for `main` 0 mir_map + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11 + let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 + let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27 + let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42 + let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30 + let _6: usize; // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25 + let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26 + let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26 + scope 1 { + let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 + scope 2 { + debug f => _2; // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10 + scope 3 { + } + scope 4 { + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 + _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 + // mir::Constant + // + span: $DIR/issue-72181.rs:24:13: 24:32 + // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35 + StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 + StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27 + _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27 + StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42 + _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42 + _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43 + StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43 + StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43 + FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 + StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30 + StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25 + _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25 + _7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 + _8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 + assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 + } + + bb2: { + _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28 + StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31 + StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31 + _0 = const (); // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2 + StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2 + } + + bb3 (cleanup): { + resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2 + } +} diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir new file mode 100644 index 000000000..425906f84 --- /dev/null +++ b/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir @@ -0,0 +1,62 @@ +// MIR for `main` 0 mir_map + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11 + let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 + let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27 + let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42 + let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30 + let _6: usize; // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25 + let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26 + let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26 + scope 1 { + let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 + scope 2 { + debug f => _2; // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10 + scope 3 { + } + scope 4 { + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 + _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34 + // mir::Constant + // + span: $DIR/issue-72181.rs:24:13: 24:32 + // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35 + StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 + StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27 + _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27 + StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42 + _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42 + _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43 + StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43 + StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43 + FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10 + StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30 + StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25 + _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25 + _7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 + _8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 + assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26 + } + + bb2: { + _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28 + StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31 + StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31 + _0 = const (); // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2 + StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2 + } + + bb3 (cleanup): { + resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2 + } +} diff --git a/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir new file mode 100644 index 000000000..e1a35d88b --- /dev/null +++ b/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir @@ -0,0 +1,29 @@ +// MIR for `f` 0 mir_map + +fn f(_1: Void) -> ! { + debug v => _1; // in scope 0 at $DIR/issue-72181-1.rs:+0:6: +0:7 + let mut _0: !; // return place in scope 0 at $DIR/issue-72181-1.rs:+0:18: +0:19 + let mut _2: !; // in scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2 + let mut _3: !; // in scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2 + StorageLive(_3); // scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15 + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/issue-72181-1.rs:+1:11: +1:12 + unreachable; // scope 0 at $DIR/issue-72181-1.rs:+1:11: +1:12 + } + + bb1: { + unreachable; // scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15 + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/issue-72181-1.rs:+1:14: +1:15 + unreachable; // scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue-72181-1.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir new file mode 100644 index 000000000..336693337 --- /dev/null +++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir @@ -0,0 +1,57 @@ +// MIR for `main` 0 mir_map + +| User Type Annotations +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void +| +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-72181-1.rs:+0:11: +0:11 + let mut _1: !; // in scope 0 at $DIR/issue-72181-1.rs:+0:11: +6:2 + let _2: Void as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10 + let mut _3: (); // in scope 0 at $DIR/issue-72181-1.rs:+2:41: +2:43 + let _4: !; // in scope 0 at $DIR/issue-72181-1.rs:+5:5: +5:9 + let mut _5: Void; // in scope 0 at $DIR/issue-72181-1.rs:+5:7: +5:8 + scope 1 { + debug v => _2; // in scope 1 at $DIR/issue-72181-1.rs:+1:9: +1:10 + } + scope 2 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10 + StorageLive(_3); // scope 2 at $DIR/issue-72181-1.rs:+2:41: +2:43 + _3 = (); // scope 2 at $DIR/issue-72181-1.rs:+2:41: +2:43 + _2 = transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue-72181-1.rs:+2:9: +2:44 + // mir::Constant + // + span: $DIR/issue-72181-1.rs:17:9: 17:40 + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Void {transmute::<(), Void>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 2 at $DIR/issue-72181-1.rs:+2:43: +2:44 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10 + AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:+1:12: +1:16 + StorageLive(_4); // scope 1 at $DIR/issue-72181-1.rs:+5:5: +5:9 + StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:+5:7: +5:8 + _5 = move _2; // scope 1 at $DIR/issue-72181-1.rs:+5:7: +5:8 + _4 = f(move _5) -> bb4; // scope 1 at $DIR/issue-72181-1.rs:+5:5: +5:9 + // mir::Constant + // + span: $DIR/issue-72181-1.rs:20:5: 20:6 + // + literal: Const { ty: fn(Void) -> ! {f}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_5); // scope 1 at $DIR/issue-72181-1.rs:+5:8: +5:9 + StorageDead(_4); // scope 1 at $DIR/issue-72181-1.rs:+5:9: +5:10 + StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:+6:1: +6:2 + unreachable; // scope 0 at $DIR/issue-72181-1.rs:+0:11: +6:2 + } + + bb3: { + return; // scope 0 at $DIR/issue-72181-1.rs:+6:2: +6:2 + } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/issue-72181-1.rs:+0:1: +6:2 + } +} diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff new file mode 100644 index 000000000..be8e86a83 --- /dev/null +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff @@ -0,0 +1,117 @@ +- // MIR for `main` before PreCodegen ++ // MIR for `main` after PreCodegen + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 + let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + let _3: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _12: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _19: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 1 { + debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14 + let _4: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + scope 3 { + debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14 + let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 4 { + debug left_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _13: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 5 { + debug kind => _13; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + } + } + scope 2 { + debug v => _3; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + _1 = _3; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21 + StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21 + StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7 + StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + _7 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.1: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _8 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _9 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _12 = (*_8); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = Eq(move _12, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _10 = Not(move _11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _10) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb1: { + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) } + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + } + + bb2: { + StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff new file mode 100644 index 000000000..be8e86a83 --- /dev/null +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff @@ -0,0 +1,117 @@ +- // MIR for `main` before PreCodegen ++ // MIR for `main` after PreCodegen + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 + let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + let _3: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _12: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _19: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 1 { + debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14 + let _4: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + scope 3 { + debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14 + let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 4 { + debug left_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _13: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 5 { + debug kind => _13; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + } + } + scope 2 { + debug v => _3; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + _1 = _3; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21 + StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21 + StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7 + StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + _7 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.1: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _8 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _9 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _12 = (*_8); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = Eq(move _12, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _10 = Not(move _11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _10) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb1: { + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) } + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + } + + bb2: { + StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff new file mode 100644 index 000000000..50948180f --- /dev/null +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff @@ -0,0 +1,157 @@ +- // MIR for `main` before SimplifyArmIdentity ++ // MIR for `main` after SimplifyArmIdentity + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 + let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + let mut _3: isize; // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16 + let _4: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + let mut _5: !; // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23 + let mut _7: i32; // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27 + let _8: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _9: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _10: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _12: i32; // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24 + let mut _15: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _16: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _18: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _27: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 1 { + debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14 + let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + scope 3 { + debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14 + let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 4 { + debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _14; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 5 { + debug kind => _20; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + } + } + scope 2 { + debug v => _4; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + _3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + goto -> bb2; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30 + } + + bb1: { + nop; // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23 + StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7 + StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2 + } + + bb2: { + StorageLive(_4); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + _1 = _4; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21 + StorageDead(_4); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21 + StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7 + StorageLive(_6); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + StorageLive(_7); // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27 + _7 = _1; // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27 + Deinit(_6); // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 + ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 + discriminant(_6) = 1; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 + StorageDead(_7); // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28 + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = (_9.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = (_9.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _15) -> [false: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb3: { + StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_24); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _23 = _24; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_26); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _26 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = _26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_27) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) } + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + } + + bb4: { + nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + nop; // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2 + StorageDead(_6); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff new file mode 100644 index 000000000..50948180f --- /dev/null +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff @@ -0,0 +1,157 @@ +- // MIR for `main` before SimplifyArmIdentity ++ // MIR for `main` after SimplifyArmIdentity + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 + let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + let mut _3: isize; // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16 + let _4: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + let mut _5: !; // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23 + let mut _7: i32; // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27 + let _8: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _9: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _10: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _12: i32; // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24 + let mut _15: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _16: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _18: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _27: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 1 { + debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14 + let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + scope 3 { + debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14 + let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 4 { + debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _14; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 5 { + debug kind => _20; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + } + } + scope 2 { + debug v => _4; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + _3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30 + goto -> bb2; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30 + } + + bb1: { + nop; // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23 + StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7 + StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2 + } + + bb2: { + StorageLive(_4); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15 + _1 = _4; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21 + StorageDead(_4); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21 + StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7 + StorageLive(_6); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14 + StorageLive(_7); // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27 + _7 = _1; // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27 + Deinit(_6); // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 + ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 + discriminant(_6) = 1; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28 + StorageDead(_7); // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28 + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = (_9.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = (_9.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _15) -> [false: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb3: { + StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_24); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _23 = _24; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_26); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _26 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = _26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_27) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) } + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + } + + bb4: { + nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + nop; // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2 + StorageDead(_6); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2 + return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/issue_76432.rs b/src/test/mir-opt/issue_76432.rs new file mode 100644 index 000000000..c8b405ca8 --- /dev/null +++ b/src/test/mir-opt/issue_76432.rs @@ -0,0 +1,16 @@ +// Check that we do not insert StorageDead at each target if StorageDead was never seen + +// EMIT_MIR issue_76432.test.SimplifyComparisonIntegral.diff +use std::fmt::Debug; + +fn test<T: Copy + Debug + PartialEq>(x: T) { + let v: &[T] = &[x, x, x]; + match v { + [ref v1, ref v2, ref v3] => [v1 as *const _, v2 as *const _, v3 as *const _], + _ => unreachable!(), + }; +} + +fn main() { + test(0u32); +} diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..2368c021e --- /dev/null +++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -0,0 +1,115 @@ +- // MIR for `test` before SimplifyComparisonIntegral ++ // MIR for `test` after SimplifyComparisonIntegral + + fn test(_1: T) -> () { + debug x => _1; // in scope 0 at $DIR/issue_76432.rs:+0:38: +0:39 + let mut _0: (); // return place in scope 0 at $DIR/issue_76432.rs:+0:44: +0:44 + let _2: &[T]; // in scope 0 at $DIR/issue_76432.rs:+1:9: +1:10 + let mut _3: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + let _4: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + let _5: [T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:20: +1:29 + let mut _6: T; // in scope 0 at $DIR/issue_76432.rs:+1:21: +1:22 + let mut _7: T; // in scope 0 at $DIR/issue_76432.rs:+1:24: +1:25 + let mut _8: T; // in scope 0 at $DIR/issue_76432.rs:+1:27: +1:28 + let _9: [*const T; 3]; // in scope 0 at $DIR/issue_76432.rs:+2:5: +5:6 + let mut _10: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _11: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _12: bool; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _16: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:38: +3:52 + let mut _17: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:38: +3:52 + let mut _18: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:54: +3:68 + let mut _19: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:54: +3:68 + let mut _20: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84 + let mut _21: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84 + let mut _22: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL + let mut _23: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + scope 1 { + debug v => _2; // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10 + let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + let _15: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + scope 2 { + debug v1 => _13; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16 + debug v2 => _14; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24 + debug v3 => _15; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_76432.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + StorageLive(_4); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + StorageLive(_5); // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29 + StorageLive(_6); // scope 0 at $DIR/issue_76432.rs:+1:21: +1:22 + _6 = _1; // scope 0 at $DIR/issue_76432.rs:+1:21: +1:22 + StorageLive(_7); // scope 0 at $DIR/issue_76432.rs:+1:24: +1:25 + _7 = _1; // scope 0 at $DIR/issue_76432.rs:+1:24: +1:25 + StorageLive(_8); // scope 0 at $DIR/issue_76432.rs:+1:27: +1:28 + _8 = _1; // scope 0 at $DIR/issue_76432.rs:+1:27: +1:28 + _5 = [move _6, move _7, move _8]; // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29 + StorageDead(_8); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29 + StorageDead(_7); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29 + StorageDead(_6); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29 + _4 = &_5; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + _3 = _4; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + StorageLive(_23); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + _23 = _3; // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + _2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 + StorageDead(_3); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29 + StorageDead(_4); // scope 0 at $DIR/issue_76432.rs:+1:29: +1:30 + StorageLive(_9); // scope 1 at $DIR/issue_76432.rs:+2:5: +5:6 + _10 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + StorageDead(_23); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + _11 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + _12 = const true; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + goto -> bb2; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + } + + bb1: { + StorageLive(_22); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL + _22 = core::panicking::panic(const "internal error: entered unreachable code"); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/panic.rs:LL:COL + // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(<ZST>) } + // mir::Constant + // + span: $SRC_DIR/core/src/panic.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb2: { + StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + _13 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + _14 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + StorageLive(_15); // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + _15 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + StorageLive(_16); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52 + StorageLive(_17); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52 + _17 = &raw const (*_13); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:40 + _16 = _17; // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52 + StorageLive(_18); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68 + StorageLive(_19); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68 + _19 = &raw const (*_14); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:56 + _18 = _19; // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68 + StorageLive(_20); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84 + StorageLive(_21); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84 + _21 = &raw const (*_15); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:72 + _20 = _21; // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84 + _9 = [move _16, move _18, move _20]; // scope 2 at $DIR/issue_76432.rs:+3:37: +3:85 + StorageDead(_21); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_20); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_19); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_18); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_17); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_16); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_15); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_14); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_13); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageDead(_9); // scope 1 at $DIR/issue_76432.rs:+5:6: +5:7 + nop; // scope 0 at $DIR/issue_76432.rs:+0:44: +6:2 + StorageDead(_5); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 + StorageDead(_2); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 + return; // scope 0 at $DIR/issue_76432.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/issue_78192.f.InstCombine.diff b/src/test/mir-opt/issue_78192.f.InstCombine.diff new file mode 100644 index 000000000..8ec94d65f --- /dev/null +++ b/src/test/mir-opt/issue_78192.f.InstCombine.diff @@ -0,0 +1,29 @@ +- // MIR for `f` before InstCombine ++ // MIR for `f` after InstCombine + + fn f(_1: &T) -> *const T { + debug a => _1; // in scope 0 at $DIR/issue-78192.rs:+0:13: +0:14 + let mut _0: *const T; // return place in scope 0 at $DIR/issue-78192.rs:+0:23: +0:31 + let _2: &*const T; // in scope 0 at $DIR/issue-78192.rs:+1:9: +1:10 + let _3: &*const T; // in scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 + let _4: *const T; // in scope 0 at $DIR/issue-78192.rs:+1:25: +1:40 + scope 1 { + debug b => _2; // in scope 1 at $DIR/issue-78192.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-78192.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 + StorageLive(_4); // scope 0 at $DIR/issue-78192.rs:+1:25: +1:40 + _4 = &raw const (*_1); // scope 0 at $DIR/issue-78192.rs:+1:26: +1:27 + _3 = &_4; // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 +- _2 = &(*_3); // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 ++ _2 = _3; // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40 + StorageDead(_3); // scope 0 at $DIR/issue-78192.rs:+1:40: +1:41 + _0 = (*_2); // scope 1 at $DIR/issue-78192.rs:+2:5: +2:7 + StorageDead(_4); // scope 0 at $DIR/issue-78192.rs:+3:1: +3:2 + StorageDead(_2); // scope 0 at $DIR/issue-78192.rs:+3:1: +3:2 + return; // scope 0 at $DIR/issue-78192.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/issue_99325.main.mir_map.0.mir b/src/test/mir-opt/issue_99325.main.mir_map.0.mir new file mode 100644 index 000000000..5bca9f0ea --- /dev/null +++ b/src/test/mir-opt/issue_99325.main.mir_map.0.mir @@ -0,0 +1,295 @@ +// MIR for `main` 0 mir_map + +| User Type Annotations +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [], promoted: None }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue-99325.rs:+0:15: +0:15 + let _1: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _2: (&&[u8], &&[u8; 4]); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _3: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _4: &[u8]; // in scope 0 at $DIR/issue-99325.rs:+1:16: +1:48 + let mut _5: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _6: &[u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+1:50: +1:75 + let _7: [u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+1:51: +1:75 + let _8: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _9: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _12: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _13: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _16: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _18: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _19: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _20: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _22: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _23: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _24: (&&[u8], &&[u8; 4]); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _25: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _26: &[u8]; // in scope 0 at $DIR/issue-99325.rs:+2:16: +2:70 + let mut _27: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _28: &[u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+2:72: +2:79 + let _29: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _30: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _31: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _32: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _33: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _34: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _35: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _37: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _38: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _39: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _40: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _41: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _42: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _43: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 1 { + debug left_val => _8; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _9; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _15: core::panicking::AssertKind; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 2 { + debug kind => _15; // in scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + scope 3 { + debug left_val => _29; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _30; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _36: core::panicking::AssertKind; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 4 { + debug kind => _36; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + + bb0: { + StorageLive(_1); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_4); // scope 0 at $DIR/issue-99325.rs:+1:16: +1:48 + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb19]; // scope 0 at $DIR/issue-99325.rs:+1:16: +1:48 + // mir::Constant + // + span: $DIR/issue-99325.rs:10:16: 10:46 + // + user_ty: UserType(0) + // + literal: Const { ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}, val: Value(<ZST>) } + } + + bb1: { + _3 = &_4; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_6); // scope 0 at $DIR/issue-99325.rs:+1:50: +1:75 + StorageLive(_7); // scope 0 at $DIR/issue-99325.rs:+1:51: +1:75 + _7 = [const 65_u8, const 65_u8, const 65_u8, const 65_u8]; // scope 0 at $DIR/issue-99325.rs:+1:51: +1:75 + _6 = &_7; // scope 0 at $DIR/issue-99325.rs:+1:50: +1:75 + _5 = &_6; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _2 = (move _3, move _5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + FakeRead(ForMatchedPlace(None), _2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_8); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _8 = (_2.0: &&[u8]); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _9 = (_2.1: &&[u8; 4]); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_10); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_12); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _12 = &(*_8); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = &(*_9); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _12, move _13) -> [return: bb2, unwind: bb19]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's> fn(&'r &[u8], &'s &[u8; 4]) -> bool {<&[u8] as PartialEq<&[u8; 4]>>::eq}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_13); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_12); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _10 = Not(move _11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _10) -> [false: bb4, otherwise: bb3]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb3: { + StorageLive(_15); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _15 = core::panicking::AssertKind::Eq; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + FakeRead(ForLet(None), _15); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_16); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_17); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _17 = move _15; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_19); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _19 = &(*_8); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = &(*_19); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_20); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = &(*_9); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _20 = &(*_21); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = Option::<Arguments>::None; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _17, move _18, move _20, move _22) -> bb19; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r &[u8], &'s &[u8; 4], Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<&[u8], &[u8; 4]>}, val: Value(<ZST>) } + } + + bb4: { + goto -> bb7; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb5: { + StorageDead(_22); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_20); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_18); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_17); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_21); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_19); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_16); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_15); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + unreachable; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb6: { + goto -> bb8; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb7: { + _1 = const (); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + goto -> bb8; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb8: { + StorageDead(_10); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + goto -> bb9; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb9: { + StorageDead(_7); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_6); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_1); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_23); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_26); // scope 0 at $DIR/issue-99325.rs:+2:16: +2:70 + _26 = function_with_bytes::<&*b"AAAA">() -> [return: bb10, unwind: bb19]; // scope 0 at $DIR/issue-99325.rs:+2:16: +2:70 + // mir::Constant + // + span: $DIR/issue-99325.rs:11:16: 11:68 + // + user_ty: UserType(1) + // + literal: Const { ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}, val: Value(<ZST>) } + } + + bb10: { + _25 = &_26; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_28); // scope 0 at $DIR/issue-99325.rs:+2:72: +2:79 + _28 = const b"AAAA"; // scope 0 at $DIR/issue-99325.rs:+2:72: +2:79 + // mir::Constant + // + span: $DIR/issue-99325.rs:11:72: 11:79 + // + literal: Const { ty: &[u8; 4], val: Value(Scalar(alloc4)) } + _27 = &_28; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = (move _25, move _27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_25); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + FakeRead(ForMatchedPlace(None), _24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_29); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _29 = (_24.0: &&[u8]); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_30); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _30 = (_24.1: &&[u8; 4]); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_31); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_33); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _33 = &(*_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_34); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _34 = &(*_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _32 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _33, move _34) -> [return: bb11, unwind: bb19]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's> fn(&'r &[u8], &'s &[u8; 4]) -> bool {<&[u8] as PartialEq<&[u8; 4]>>::eq}, val: Value(<ZST>) } + } + + bb11: { + StorageDead(_34); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_33); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _31 = Not(move _32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _31) -> [false: bb13, otherwise: bb12]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb12: { + StorageLive(_36); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _36 = core::panicking::AssertKind::Eq; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + FakeRead(ForLet(None), _36); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_37); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_38); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _38 = move _36; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_40); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _40 = &(*_29); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _39 = &(*_40); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_41); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_42); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _42 = &(*_30); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _41 = &(*_42); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_43); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _43 = Option::<Arguments>::None; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _37 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _38, move _39, move _41, move _43) -> bb19; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r &[u8], &'s &[u8; 4], Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<&[u8], &[u8; 4]>}, val: Value(<ZST>) } + } + + bb13: { + goto -> bb16; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb14: { + StorageDead(_43); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_41); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_38); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_42); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_40); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_37); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_36); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + unreachable; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb15: { + goto -> bb17; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb16: { + _23 = const (); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + goto -> bb17; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb17: { + StorageDead(_31); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_30); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_29); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + goto -> bb18; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb18: { + StorageDead(_28); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_26); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_23); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _0 = const (); // scope 0 at $DIR/issue-99325.rs:+0:15: +3:2 + return; // scope 0 at $DIR/issue-99325.rs:+3:2: +3:2 + } + + bb19 (cleanup): { + resume; // scope 0 at $DIR/issue-99325.rs:+0:1: +3:2 + } +} + +alloc4 (size: 4, align: 1) { + 41 41 41 41 │ AAAA +} diff --git a/src/test/mir-opt/issues/issue-59352.rs b/src/test/mir-opt/issues/issue-59352.rs new file mode 100644 index 000000000..1e0045555 --- /dev/null +++ b/src/test/mir-opt/issues/issue-59352.rs @@ -0,0 +1,19 @@ +// This test is a mirror of codegen/issue-59352.rs. +// The LLVM inliner doesn't inline `char::method::is_digit()` and so it doesn't recognize this case +// as effectively `if x.is_some() { x.unwrap() } else { 0 }`. +// +// Currently, the MIR optimizer isn't capable of removing the unreachable panic in this test case. +// Once the optimizer can do that, this test case will need to be updated and codegen/issue-59352.rs +// removed. + +// EMIT_MIR issue_59352.num_to_digit.PreCodegen.after.mir +// compile-flags: -Z mir-opt-level=3 -Z span_free_formats + +pub fn num_to_digit(num: char) -> u32 { + // CHECK-NOT: panic + if num.is_digit(8) { num.to_digit(8).unwrap() } else { 0 } +} + +pub fn main() { + num_to_digit('2'); +} diff --git a/src/test/mir-opt/issues/issue-75439.rs b/src/test/mir-opt/issues/issue-75439.rs new file mode 100644 index 000000000..ae2e03631 --- /dev/null +++ b/src/test/mir-opt/issues/issue-75439.rs @@ -0,0 +1,18 @@ +// EMIT_MIR issue_75439.foo.MatchBranchSimplification.diff + +use std::mem::transmute; + +pub fn foo(bytes: [u8; 16]) -> Option<[u8; 4]> { + // big endian `u32`s + let dwords: [u32; 4] = unsafe { transmute(bytes) }; + const FF: u32 = 0x0000_ffff_u32.to_be(); + if let [0, 0, 0 | FF, ip] = dwords { + Some(unsafe { transmute(ip) }) + } else { + None + } +} + +fn main() { + let _ = foo([0; 16]); +} diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir new file mode 100644 index 000000000..86b38d4b7 --- /dev/null +++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -0,0 +1,109 @@ +// MIR for `num_to_digit` after PreCodegen + +fn num_to_digit(_1: char) -> u32 { + debug num => _1; // in scope 0 at $DIR/issue-59352.rs:+0:21: +0:24 + let mut _0: u32; // return place in scope 0 at $DIR/issue-59352.rs:+0:35: +0:38 + let mut _2: char; // in scope 0 at $DIR/issue-59352.rs:+2:8: +2:11 + let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/issue-59352.rs:+2:26: +2:41 + let mut _4: char; // in scope 0 at $DIR/issue-59352.rs:+2:26: +2:29 + let mut _5: u32; // in scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + let mut _12: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 1 (inlined char::methods::<impl char>::is_digit) { // at $DIR/issue-59352.rs:14:8: 14:23 + debug self => _2; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + debug radix => _5; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let mut _6: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let _7: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let mut _8: char; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + scope 2 (inlined Option::<u32>::is_some) { // at $SRC_DIR/core/src/char/methods.rs:LL:COL + debug self => _6; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _9: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + scope 3 (inlined #[track_caller] Option::<u32>::unwrap) { // at $DIR/issue-59352.rs:14:26: 14:50 + debug self => _3; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _10: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _11: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + scope 4 { + debug val => _0; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:11 + _2 = _1; // scope 0 at $DIR/issue-59352.rs:+2:8: +2:11 + StorageLive(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + StorageLive(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageLive(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageLive(_8); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _8 = _2; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _7 = char::methods::<impl char>::to_digit(move _8, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL + // + literal: Const { ty: fn(char, u32) -> Option<u32> {char::methods::<impl char>::to_digit}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_12); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + StorageLive(_3); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:41 + StorageLive(_4); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:29 + _4 = _1; // scope 0 at $DIR/issue-59352.rs:+2:26: +2:29 + _3 = char::methods::<impl char>::to_digit(move _4, const 8_u32) -> bb2; // scope 0 at $DIR/issue-59352.rs:+2:26: +2:41 + // mir::Constant + // + span: $DIR/issue-59352.rs:14:30: 14:38 + // + literal: Const { ty: fn(char, u32) -> Option<u32> {char::methods::<impl char>::to_digit}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_4); // scope 0 at $DIR/issue-59352.rs:+2:40: +2:41 + StorageLive(_10); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:50 + _10 = discriminant(_3); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _10) -> [0_isize: bb6, 1_isize: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb3: { + StorageDead(_12); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + _0 = const 0_u32; // scope 0 at $DIR/issue-59352.rs:+2:60: +2:61 + goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63 + } + + bb4: { + return; // scope 0 at $DIR/issue-59352.rs:+3:2: +3:2 + } + + bb5: { + _6 = &_7; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageDead(_8); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageLive(_9); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _9 = discriminant((*_6)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + StorageLive(_12); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _12 = move _9; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageDead(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageDead(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageDead(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + StorageDead(_2); // scope 0 at $DIR/issue-59352.rs:+2:22: +2:23 + switchInt(move _12) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23 + } + + bb6: { + StorageLive(_11); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + _11 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/option.rs:LL:COL + // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(<ZST>) } + // mir::Constant + // + span: $SRC_DIR/core/src/option.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb7: { + unreachable; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb8: { + _0 = move ((_3 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_10); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:50 + StorageDead(_3); // scope 0 at $DIR/issue-59352.rs:+2:49: +2:50 + goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63 + } +} diff --git a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff new file mode 100644 index 000000000..2ee4332ad --- /dev/null +++ b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff @@ -0,0 +1,89 @@ +- // MIR for `foo` before MatchBranchSimplification ++ // MIR for `foo` after MatchBranchSimplification + + fn foo(_1: [u8; 16]) -> Option<[u8; 4]> { + debug bytes => _1; // in scope 0 at $DIR/issue-75439.rs:+0:12: +0:17 + let mut _0: std::option::Option<[u8; 4]>; // return place in scope 0 at $DIR/issue-75439.rs:+0:32: +0:47 + let _2: [u32; 4]; // in scope 0 at $DIR/issue-75439.rs:+2:9: +2:15 + let mut _3: [u8; 16]; // in scope 0 at $DIR/issue-75439.rs:+2:47: +2:52 + let mut _5: [u8; 4]; // in scope 0 at $DIR/issue-75439.rs:+5:14: +5:38 + let mut _6: u32; // in scope 0 at $DIR/issue-75439.rs:+5:33: +5:35 + scope 1 { + debug dwords => _2; // in scope 1 at $DIR/issue-75439.rs:+2:9: +2:15 + scope 3 { + debug ip => _4; // in scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 + let _4: u32; // in scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 + scope 4 { + } + } + } + scope 2 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue-75439.rs:+2:9: +2:15 + StorageLive(_3); // scope 2 at $DIR/issue-75439.rs:+2:47: +2:52 + _3 = _1; // scope 2 at $DIR/issue-75439.rs:+2:47: +2:52 + _2 = transmute::<[u8; 16], [u32; 4]>(move _3) -> bb1; // scope 2 at $DIR/issue-75439.rs:+2:37: +2:53 + // mir::Constant + // + span: $DIR/issue-75439.rs:7:37: 7:46 + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn([u8; 16]) -> [u32; 4] {transmute::<[u8; 16], [u32; 4]>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 2 at $DIR/issue-75439.rs:+2:52: +2:53 + switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + } + + bb2: { + switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + } + + bb3: { + switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + } + + bb4: { + StorageLive(_5); // scope 3 at $DIR/issue-75439.rs:+5:14: +5:38 + StorageLive(_6); // scope 4 at $DIR/issue-75439.rs:+5:33: +5:35 + _6 = _4; // scope 4 at $DIR/issue-75439.rs:+5:33: +5:35 + _5 = transmute::<u32, [u8; 4]>(move _6) -> bb7; // scope 4 at $DIR/issue-75439.rs:+5:23: +5:36 + // mir::Constant + // + span: $DIR/issue-75439.rs:10:23: 10:32 + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u32) -> [u8; 4] {transmute::<u32, [u8; 4]>}, val: Value(<ZST>) } + } + + bb5: { + StorageLive(_4); // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 + _4 = _2[3 of 4]; // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 + goto -> bb4; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + } + + bb6: { + StorageLive(_4); // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 + _4 = _2[3 of 4]; // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29 + goto -> bb4; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30 + } + + bb7: { + StorageDead(_6); // scope 4 at $DIR/issue-75439.rs:+5:35: +5:36 + Deinit(_0); // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39 + ((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39 + discriminant(_0) = 1; // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39 + StorageDead(_5); // scope 3 at $DIR/issue-75439.rs:+5:38: +5:39 + StorageDead(_4); // scope 1 at $DIR/issue-75439.rs:+6:5: +6:6 + goto -> bb9; // scope 1 at $DIR/issue-75439.rs:+4:5: +8:6 + } + + bb8: { + Deinit(_0); // scope 1 at $DIR/issue-75439.rs:+7:9: +7:13 + discriminant(_0) = 0; // scope 1 at $DIR/issue-75439.rs:+7:9: +7:13 + goto -> bb9; // scope 1 at $DIR/issue-75439.rs:+4:5: +8:6 + } + + bb9: { + StorageDead(_2); // scope 0 at $DIR/issue-75439.rs:+9:1: +9:2 + return; // scope 0 at $DIR/issue-75439.rs:+9:2: +9:2 + } + } + diff --git a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir new file mode 100644 index 000000000..5981ab885 --- /dev/null +++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir @@ -0,0 +1,52 @@ +// MIR for `main` after SimplifyCfg-promote-consts + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/loop_test.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/loop_test.rs:+4:5: +6:6 + let mut _2: bool; // in scope 0 at $DIR/loop_test.rs:+4:8: +4:12 + let mut _3: !; // in scope 0 at $DIR/loop_test.rs:+4:13: +6:6 + let mut _4: !; // in scope 0 at $DIR/loop_test.rs:+7:5: +10:6 + let mut _5: (); // in scope 0 at $DIR/loop_test.rs:+0:1: +11:2 + let _6: i32; // in scope 0 at $DIR/loop_test.rs:+8:13: +8:14 + scope 1 { + debug x => _6; // in scope 1 at $DIR/loop_test.rs:+8:13: +8:14 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/loop_test.rs:+4:5: +6:6 + StorageLive(_2); // scope 0 at $DIR/loop_test.rs:+4:8: +4:12 + _2 = const true; // scope 0 at $DIR/loop_test.rs:+4:8: +4:12 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/loop_test.rs:+4:8: +4:12 + } + + bb1: { + _0 = const (); // scope 0 at $DIR/loop_test.rs:+5:9: +5:15 + StorageDead(_2); // scope 0 at $DIR/loop_test.rs:+6:5: +6:6 + StorageDead(_1); // scope 0 at $DIR/loop_test.rs:+6:5: +6:6 + return; // scope 0 at $DIR/loop_test.rs:+11:2: +11:2 + } + + bb2: { + _1 = const (); // scope 0 at $DIR/loop_test.rs:+6:6: +6:6 + StorageDead(_2); // scope 0 at $DIR/loop_test.rs:+6:5: +6:6 + StorageDead(_1); // scope 0 at $DIR/loop_test.rs:+6:5: +6:6 + StorageLive(_4); // scope 0 at $DIR/loop_test.rs:+7:5: +10:6 + goto -> bb3; // scope 0 at $DIR/loop_test.rs:+7:5: +10:6 + } + + bb3: { + falseUnwind -> [real: bb4, cleanup: bb5]; // scope 0 at $DIR/loop_test.rs:+7:5: +10:6 + } + + bb4: { + StorageLive(_6); // scope 0 at $DIR/loop_test.rs:+8:13: +8:14 + _6 = const 1_i32; // scope 0 at $DIR/loop_test.rs:+8:17: +8:18 + FakeRead(ForLet(None), _6); // scope 0 at $DIR/loop_test.rs:+8:13: +8:14 + StorageDead(_6); // scope 0 at $DIR/loop_test.rs:+10:5: +10:6 + goto -> bb3; // scope 0 at no-location + } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/loop_test.rs:+0:1: +11:2 + } +} diff --git a/src/test/mir-opt/loop_test.rs b/src/test/mir-opt/loop_test.rs new file mode 100644 index 000000000..7ded5b575 --- /dev/null +++ b/src/test/mir-opt/loop_test.rs @@ -0,0 +1,17 @@ +// compile-flags: -Z identify_regions + +// Tests to make sure we correctly generate falseUnwind edges in loops + +// EMIT_MIR loop_test.main.SimplifyCfg-promote-consts.after.mir +fn main() { + // Exit early at runtime. Since only care about the generated MIR + // and not the runtime behavior (which is exercised by other tests) + // we just bail early. Without this the test just loops infinitely. + if true { + return; + } + loop { + let x = 1; + continue; + } +} diff --git a/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff new file mode 100644 index 000000000..2589c9f28 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_bound.InstCombine.diff @@ -0,0 +1,66 @@ +- // MIR for `array_bound` before InstCombine ++ // MIR for `array_bound` after InstCombine + + fn array_bound(_1: usize, _2: &[u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41 + debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _7 = _2; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _11 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21 +- _5 = Len((*_11)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + } + + bb1: { + StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 +- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + } + + bb2: { + _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 + goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6 + } + + bb3: { + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11 + goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6 + } + + bb4: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6 + return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff new file mode 100644 index 000000000..049bbeac8 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff @@ -0,0 +1,68 @@ +- // MIR for `array_bound` before NormalizeArrayLen ++ // MIR for `array_bound` after NormalizeArrayLen + + fn array_bound(_1: usize, _2: &[u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41 + debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _11 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21 +- _5 = Len((*_6)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _5 = Len((*_11)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + } + + bb1: { + StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + } + + bb2: { + StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb3; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + } + + bb3: { + _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 + goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6 + } + + bb4: { + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11 + goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6 + } + + bb5: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6 + return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff new file mode 100644 index 000000000..8312db6b3 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_bound.SimplifyLocals.diff @@ -0,0 +1,70 @@ +- // MIR for `array_bound` before SimplifyLocals ++ // MIR for `array_bound` after SimplifyLocals + + fn array_bound(_1: usize, _2: &[u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41 + debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 +- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 ++ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21 + _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + } + + bb1: { +- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 +- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 +- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 ++ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 ++ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + } + + bb2: { +- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 ++ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 + goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6 + } + + bb3: { + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11 + goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6 + } + + bb4: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6 + return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff new file mode 100644 index 000000000..401d4bac6 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_bound_mut.InstCombine.diff @@ -0,0 +1,79 @@ +- // MIR for `array_bound_mut` before InstCombine ++ // MIR for `array_bound_mut` after InstCombine + + fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45 + debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 + let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _14 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21 +- _5 = Len((*_14)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + } + + bb1: { + StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 +- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + } + + bb2: { + _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 + goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6 + } + + bb3: { + StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 + _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 +- _12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 ++ _12 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + _13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + } + + bb4: { + (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22 + StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23 + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11 + goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6 + } + + bb5: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6 + return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff new file mode 100644 index 000000000..40ec01eeb --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff @@ -0,0 +1,81 @@ +- // MIR for `array_bound_mut` before NormalizeArrayLen ++ // MIR for `array_bound_mut` after NormalizeArrayLen + + fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45 + debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 + let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 ++ let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _14 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21 +- _5 = Len((*_6)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ _5 = Len((*_14)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 + } + + bb1: { + StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + } + + bb2: { + StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 + _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb3; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + } + + bb3: { + _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 + goto -> bb6; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6 + } + + bb4: { + StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 + _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 + _12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + _13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb5; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + } + + bb5: { + (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22 + StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23 + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11 + goto -> bb6; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6 + } + + bb6: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6 + return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff new file mode 100644 index 000000000..4f241d7c9 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_bound_mut.SimplifyLocals.diff @@ -0,0 +1,93 @@ +- // MIR for `array_bound_mut` before SimplifyLocals ++ // MIR for `array_bound_mut` after SimplifyLocals + + fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45 + debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 +- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 +- let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 +- let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 +- let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 ++ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 ++ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ let _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 ++ let mut _10: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 ++ let mut _11: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21 + _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27 +- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 + switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + } + + bb1: { +- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 +- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 +- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 ++ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20 ++ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 + } + + bb2: { +- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 +- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 ++ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21 ++ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6 + goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6 + } + + bb3: { +- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 +- _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 +- _12 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 +- _13 = Lt(const 0_usize, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 ++ StorageLive(_9); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 ++ _9 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16 ++ _10 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 ++ _11 = Lt(const 0_usize, _10); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 ++ assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17 + } + + bb4: { +- (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22 +- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23 ++ (*_2)[_9] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22 ++ StorageDead(_9); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23 + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11 + goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6 + } + + bb5: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6 + return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff new file mode 100644 index 000000000..26f45be17 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_len.InstCombine.diff @@ -0,0 +1,27 @@ +- // MIR for `array_len` before InstCombine ++ // MIR for `array_len` after InstCombine + + fn array_len(_1: &[u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57 + let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- _3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _3 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8 +- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14 + return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff new file mode 100644 index 000000000..3ed68f5f7 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff @@ -0,0 +1,30 @@ +- // MIR for `array_len` before NormalizeArrayLen ++ // MIR for `array_len` after NormalizeArrayLen + + fn array_len(_1: &[u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57 + let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8 +- _0 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14 + return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff new file mode 100644 index 000000000..09d571d20 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_len.SimplifyLocals.diff @@ -0,0 +1,22 @@ +- // MIR for `array_len` before SimplifyLocals ++ // MIR for `array_len` after SimplifyLocals + + fn array_len(_1: &[u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57 +- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8 + _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14 + return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff new file mode 100644 index 000000000..843da758d --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_len_by_value.InstCombine.diff @@ -0,0 +1,26 @@ +- // MIR for `array_len_by_value` before InstCombine ++ // MIR for `array_len_by_value` after InstCombine + + fn array_len_by_value(_1: [u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65 + let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _3 = &_1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8 +- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14 + return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff new file mode 100644 index 000000000..f0e0cdcfd --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff @@ -0,0 +1,30 @@ +- // MIR for `array_len_by_value` before NormalizeArrayLen ++ // MIR for `array_len_by_value` after NormalizeArrayLen + + fn array_len_by_value(_1: [u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65 + let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _3 = &_1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8 +- _0 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 ++ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14 + return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff new file mode 100644 index 000000000..dc1c00b69 --- /dev/null +++ b/src/test/mir-opt/lower_array_len.array_len_by_value.SimplifyLocals.diff @@ -0,0 +1,22 @@ +- // MIR for `array_len_by_value` before SimplifyLocals ++ // MIR for `array_len_by_value` after SimplifyLocals + + fn array_len_by_value(_1: [u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65 +- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8 + _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14 +- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14 + return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_array_len.rs b/src/test/mir-opt/lower_array_len.rs new file mode 100644 index 000000000..fc12ee75f --- /dev/null +++ b/src/test/mir-opt/lower_array_len.rs @@ -0,0 +1,47 @@ +// compile-flags: -Z mir-opt-level=4 + +// EMIT_MIR lower_array_len.array_bound.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_bound.SimplifyLocals.diff +// EMIT_MIR lower_array_len.array_bound.InstCombine.diff +pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 { + if index < slice.len() { + slice[index] + } else { + 42 + } +} + +// EMIT_MIR lower_array_len.array_bound_mut.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_bound_mut.SimplifyLocals.diff +// EMIT_MIR lower_array_len.array_bound_mut.InstCombine.diff +pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 { + if index < slice.len() { + slice[index] + } else { + slice[0] = 42; + + 42 + } +} + +// EMIT_MIR lower_array_len.array_len.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_len.SimplifyLocals.diff +// EMIT_MIR lower_array_len.array_len.InstCombine.diff +pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize { + arr.len() +} + +// EMIT_MIR lower_array_len.array_len_by_value.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_len_by_value.SimplifyLocals.diff +// EMIT_MIR lower_array_len.array_len_by_value.InstCombine.diff +pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize { + arr.len() +} + +fn main() { + let _ = array_bound(3, &[0, 1, 2, 3]); + let mut tmp = [0, 1, 2, 3, 4]; + let _ = array_bound_mut(3, &mut [0, 1, 2, 3]); + let _ = array_len(&[0]); + let _ = array_len_by_value([0, 2]); +} diff --git a/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff new file mode 100644 index 000000000..5c635e222 --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff @@ -0,0 +1,20 @@ +- // MIR for `align_of` before LowerIntrinsics ++ // MIR for `align_of` after LowerIntrinsics + + fn align_of() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:30 + + bb0: { +- _0 = std::intrinsics::min_align_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:19:5: 19:40 +- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::<T>}, val: Value(<ZST>) } ++ _0 = AlignOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 + } + + bb1: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff new file mode 100644 index 000000000..8a80de32f --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -0,0 +1,115 @@ +- // MIR for `discriminant` before LowerIntrinsics ++ // MIR for `discriminant` after LowerIntrinsics + + fn discriminant(_1: T) -> () { + debug t => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:25 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:30: +0:30 + let _2: <T as std::marker::DiscriminantKind>::Discriminant; // in scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 + let mut _3: &T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + let _4: &T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + let _5: u8; // in scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 + let mut _6: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + let _7: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + let _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:43: +2:44 + let _9: u8; // in scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 + let mut _10: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + let _11: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + let _12: (); // in scope 0 at $DIR/lower_intrinsics.rs:+3:43: +3:45 + let _13: isize; // in scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 + let mut _14: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + let _15: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + let _16: E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:43: +4:47 + let mut _17: &E; // in scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + let mut _18: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + let mut _19: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 + StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + _4 = &_1; // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 + _3 = &(*_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 +- _2 = discriminant_value::<T>(move _3) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:74:5: 74:41 +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r T) -> <T as DiscriminantKind>::Discriminant {discriminant_value::<T>}, val: Value(<ZST>) } ++ _2 = discriminant((*_3)); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:44: +1:45 + StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 + StorageLive(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + _19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:75:42: 75:44 + // + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) } + _7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + _6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 +- _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:75:5: 75:41 +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r i32) -> <i32 as DiscriminantKind>::Discriminant {discriminant_value::<i32>}, val: Value(<ZST>) } ++ _5 = discriminant((*_6)); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 ++ goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 + } + + bb2: { + StorageDead(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:44: +2:45 + StorageDead(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + StorageLive(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 + StorageLive(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + _18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:76:42: 76:45 + // + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) } + _11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + _10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 +- _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:76:5: 76:41 +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r ()) -> <() as DiscriminantKind>::Discriminant {discriminant_value::<()>}, val: Value(<ZST>) } ++ _9 = discriminant((*_10)); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 ++ goto -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 + } + + bb3: { + StorageDead(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:45: +3:46 + StorageDead(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:46: +3:47 + StorageDead(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:46: +3:47 + StorageLive(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 + StorageLive(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + _17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:77:42: 77:47 + // + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) } + _15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + _14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 +- _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:77:5: 77:41 +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r E) -> <E as DiscriminantKind>::Discriminant {discriminant_value::<E>}, val: Value(<ZST>) } ++ _13 = discriminant((*_14)); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 ++ goto -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 + } + + bb4: { + StorageDead(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:47: +4:48 + StorageDead(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49 + StorageDead(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:30: +5:2 + drop(_1) -> bb5; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2 + } + + bb5: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir b/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir new file mode 100644 index 000000000..9e4de2ac0 --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir @@ -0,0 +1,32 @@ +// MIR for `f_u64` before PreCodegen + +fn f_u64() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:16: +0:16 + let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21 + scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics.rs:40:5: 40:21 + debug t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+5:22: +5:23 + let _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21 + let mut _3: u64; // in scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20 + scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21 + _1 = const 0_u64; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21 + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21 + StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20 + _3 = move _1; // scope 1 at $DIR/lower_intrinsics.rs:+9:19: +9:20 + _2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+9:9: +9:21 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:48:9: 48:18 + // + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+9:20: +9:21 + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+9:21: +9:22 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21 + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir b/src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir new file mode 100644 index 000000000..9a6c0457f --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir @@ -0,0 +1,30 @@ +// MIR for `f_unit` before PreCodegen + +fn f_unit() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17 + let mut _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:16: +1:18 + scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics.rs:34:5: 34:19 + debug t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+11:22: +11:23 + let _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17 + let mut _3: (); // in scope 1 at $DIR/lower_intrinsics.rs:+13:15: +13:16 + scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:16: +1:18 + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17 + StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+13:15: +13:16 + _2 = f_zst::<()>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+13:9: +13:17 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:46:9: 46:14 + // + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+13:16: +13:17 + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+13:17: +13:18 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:18: +1:19 + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff new file mode 100644 index 000000000..e6a2f6512 --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff @@ -0,0 +1,29 @@ +- // MIR for `forget` before LowerIntrinsics ++ // MIR for `forget` after LowerIntrinsics + + fn forget(_1: T) -> () { + debug t => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:18: +0:19 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:24 + let mut _2: T; // in scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 + _2 = move _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 +- _0 = std::intrinsics::forget::<T>(move _2) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:24:5: 24:29 +- // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::<T>}, val: Value(<ZST>) } ++ _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:31: +1:32 + goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:1: +2:2 + } + + bb2: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff new file mode 100644 index 000000000..1ab2f2a0a --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff @@ -0,0 +1,31 @@ +- // MIR for `non_const` before LowerIntrinsics ++ // MIR for `non_const` after LowerIntrinsics + + fn non_const() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:26: +0:31 + let _1: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18 + let mut _2: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; // in scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:14 + scope 1 { + debug size_of_t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:18 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18 + _1 = std::intrinsics::size_of::<T>; // scope 0 at $DIR/lower_intrinsics.rs:+2:21: +2:51 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:62:21: 62:51 + // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) } + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14 + _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14 +- _0 = move _2() -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16 ++ _0 = SizeOf(T); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:16 + } + + bb1: { + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:15: +3:16 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.rs b/src/test/mir-opt/lower_intrinsics.rs new file mode 100644 index 000000000..eab51b65f --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.rs @@ -0,0 +1,78 @@ +// compile-flags: -Cpanic=abort +#![feature(core_intrinsics)] +#![crate_type = "lib"] + +// EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff +pub fn wrapping(a: i32, b: i32) { + let _x = core::intrinsics::wrapping_add(a, b); + let _y = core::intrinsics::wrapping_sub(a, b); + let _z = core::intrinsics::wrapping_mul(a, b); +} + +// EMIT_MIR lower_intrinsics.size_of.LowerIntrinsics.diff +pub fn size_of<T>() -> usize { + core::intrinsics::size_of::<T>() +} + +// EMIT_MIR lower_intrinsics.align_of.LowerIntrinsics.diff +pub fn align_of<T>() -> usize { + core::intrinsics::min_align_of::<T>() +} + +// EMIT_MIR lower_intrinsics.forget.LowerIntrinsics.diff +pub fn forget<T>(t: T) { + core::intrinsics::forget(t) +} + +// EMIT_MIR lower_intrinsics.unreachable.LowerIntrinsics.diff +pub fn unreachable() -> ! { + unsafe { core::intrinsics::unreachable() }; +} + +// EMIT_MIR lower_intrinsics.f_unit.PreCodegen.before.mir +pub fn f_unit() { + f_dispatch(()); +} + + +// EMIT_MIR lower_intrinsics.f_u64.PreCodegen.before.mir +pub fn f_u64() { + f_dispatch(0u64); +} + +#[inline(always)] +pub fn f_dispatch<T>(t: T) { + if std::mem::size_of::<T>() == 0 { + f_zst(t); + } else { + f_non_zst(t); + } +} + +#[inline(never)] +pub fn f_zst<T>(_t: T) { +} + +#[inline(never)] +pub fn f_non_zst<T>(_t: T) {} + +// EMIT_MIR lower_intrinsics.non_const.LowerIntrinsics.diff +pub fn non_const<T>() -> usize { + // Check that lowering works with non-const operand as a func. + let size_of_t = core::intrinsics::size_of::<T>; + size_of_t() +} + +pub enum E { + A, + B, + C, +} + +// EMIT_MIR lower_intrinsics.discriminant.LowerIntrinsics.diff +pub fn discriminant<T>(t: T) { + core::intrinsics::discriminant_value(&t); + core::intrinsics::discriminant_value(&0); + core::intrinsics::discriminant_value(&()); + core::intrinsics::discriminant_value(&E::B); +} diff --git a/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff new file mode 100644 index 000000000..11b27976b --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff @@ -0,0 +1,20 @@ +- // MIR for `size_of` before LowerIntrinsics ++ // MIR for `size_of` after LowerIntrinsics + + fn size_of() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:24: +0:29 + + bb0: { +- _0 = std::intrinsics::size_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:14:5: 14:35 +- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) } ++ _0 = SizeOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 + } + + bb1: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff new file mode 100644 index 000000000..ac077e85b --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff @@ -0,0 +1,22 @@ +- // MIR for `unreachable` before LowerIntrinsics ++ // MIR for `unreachable` after LowerIntrinsics + + fn unreachable() -> ! { + let mut _0: !; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:26 + let mut _1: !; // in scope 0 at $DIR/lower_intrinsics.rs:+0:27: +2:2 + let _2: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45 + let mut _3: !; // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:47 + StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 +- _3 = std::intrinsics::unreachable(); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:29:14: 29:43 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(<ZST>) } ++ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff new file mode 100644 index 000000000..e0a5416b2 --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff @@ -0,0 +1,83 @@ +- // MIR for `wrapping` before LowerIntrinsics ++ // MIR for `wrapping` after LowerIntrinsics + + fn wrapping(_1: i32, _2: i32) -> () { + debug a => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:18 + debug b => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:26 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:33: +0:33 + let _3: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + let mut _4: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + let mut _5: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49 + let mut _7: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + let mut _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:48: +2:49 + let mut _10: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:45: +3:46 + let mut _11: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:48: +3:49 + scope 1 { + debug _x => _3; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + let _6: i32; // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + scope 2 { + debug _y => _6; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + let _9: i32; // in scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + scope 3 { + debug _z => _9; // in scope 3 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + } + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + _4 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 + StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49 + _5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49 +- _3 = wrapping_add::<i32>(move _4, move _5) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:7:14: 7:44 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_add::<i32>}, val: Value(<ZST>) } ++ _3 = Add(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 + } + + bb1: { + StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 + StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 + StorageLive(_6); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + StorageLive(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + _7 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+2:45: +2:46 + StorageLive(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49 + _8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49 +- _6 = wrapping_sub::<i32>(move _7, move _8) -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:8:14: 8:44 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_sub::<i32>}, val: Value(<ZST>) } ++ _6 = Sub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 ++ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 + } + + bb2: { + StorageDead(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50 + StorageDead(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50 + StorageLive(_9); // scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + StorageLive(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:45: +3:46 + _10 = _1; // scope 2 at $DIR/lower_intrinsics.rs:+3:45: +3:46 + StorageLive(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:48: +3:49 + _11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:48: +3:49 +- _9 = wrapping_mul::<i32>(move _10, move _11) -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:9:14: 9:44 +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_mul::<i32>}, val: Value(<ZST>) } ++ _9 = Mul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50 ++ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50 + } + + bb3: { + StorageDead(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:49: +3:50 + StorageDead(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:49: +3:50 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:33: +4:2 + StorageDead(_9); // scope 2 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + StorageDead(_6); // scope 1 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+4:1: +4:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff b/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff new file mode 100644 index 000000000..46fccba56 --- /dev/null +++ b/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff @@ -0,0 +1,63 @@ +- // MIR for `bound` before LowerSliceLenCalls ++ // MIR for `bound` after LowerSliceLenCalls + + fn bound(_1: usize, _2: &[u8]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_slice_len.rs:+0:14: +0:19 + debug slice => _2; // in scope 0 at $DIR/lower_slice_len.rs:+0:28: +0:33 + let mut _0: u8; // return place in scope 0 at $DIR/lower_slice_len.rs:+0:45: +0:47 + let mut _3: bool; // in scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + let mut _6: &[u8]; // in scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + let _7: usize; // in scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20 + let mut _8: usize; // in scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + let mut _9: bool; // in scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + StorageLive(_6); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + _6 = &(*_2); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 +- _5 = core::slice::<impl [u8]>::len(move _6) -> bb1; // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 +- // mir::Constant +- // + span: $DIR/lower_slice_len.rs:5:22: 5:25 +- // + literal: Const { ty: for<'r> fn(&'r [u8]) -> usize {core::slice::<impl [u8]>::len}, val: Value(<ZST>) } ++ _5 = Len((*_6)); // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 ++ goto -> bb1; // scope 0 at $DIR/lower_slice_len.rs:+1:16: +1:27 + } + + bb1: { + StorageDead(_6); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27 + switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + } + + bb2: { + StorageLive(_7); // scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20 + _7 = _1; // scope 0 at $DIR/lower_slice_len.rs:+2:15: +2:20 + _8 = Len((*_2)); // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + _9 = Lt(_7, _8); // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb3; // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + } + + bb3: { + _0 = (*_2)[_7]; // scope 0 at $DIR/lower_slice_len.rs:+2:9: +2:21 + StorageDead(_7); // scope 0 at $DIR/lower_slice_len.rs:+3:5: +3:6 + goto -> bb5; // scope 0 at $DIR/lower_slice_len.rs:+1:5: +5:6 + } + + bb4: { + _0 = const 42_u8; // scope 0 at $DIR/lower_slice_len.rs:+4:9: +4:11 + goto -> bb5; // scope 0 at $DIR/lower_slice_len.rs:+1:5: +5:6 + } + + bb5: { + StorageDead(_3); // scope 0 at $DIR/lower_slice_len.rs:+5:5: +5:6 + return; // scope 0 at $DIR/lower_slice_len.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/lower_slice_len.rs b/src/test/mir-opt/lower_slice_len.rs new file mode 100644 index 000000000..12955aed1 --- /dev/null +++ b/src/test/mir-opt/lower_slice_len.rs @@ -0,0 +1,14 @@ +// unit-test: LowerSliceLenCalls + +// EMIT_MIR lower_slice_len.bound.LowerSliceLenCalls.diff +pub fn bound(index: usize, slice: &[u8]) -> u8 { + if index < slice.len() { + slice[index] + } else { + 42 + } +} + +fn main() { + let _ = bound(1, &[1, 2, 3]); +} diff --git a/src/test/mir-opt/match-arm-scopes.rs b/src/test/mir-opt/match-arm-scopes.rs new file mode 100644 index 000000000..7b7de7788 --- /dev/null +++ b/src/test/mir-opt/match-arm-scopes.rs @@ -0,0 +1,35 @@ +// ignore-wasm32-bare compiled with panic=abort by default +// Test that StorageDead and Drops are generated properly for bindings in +// matches: +// * The MIR should only contain a single drop of `s` and `t`: at the end +// of their respective arms. +// * StorageDead and StorageLive statements are correctly matched up on +// non-unwind paths. +// * The visibility scopes of the match arms should be disjoint, and contain. +// all of the bindings for that scope. +// * No drop flags are used. + +// EMIT_MIR match_arm_scopes.complicated_match SimplifyCfg-initial.after ElaborateDrops.after +fn complicated_match(cond: bool, items: (bool, bool, String)) -> i32 { + match items { + (false, a, s) | (a, false, s) if if cond { return 3 } else { a } => 1, + (true, b, t) | (false, b, t) => 2, + } +} + +const CASES: &[(bool, bool, bool, i32)] = &[ + (false, false, false, 2), + (false, false, true, 1), + (false, true, false, 1), + (false, true, true, 2), + (true, false, false, 3), + (true, false, true, 3), + (true, true, false, 3), + (true, true, true, 2), +]; + +fn main() { + for &(cond, items_1, items_2, result) in CASES { + assert_eq!(complicated_match(cond, (items_1, items_2, String::new())), result,); + } +} diff --git a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff new file mode 100644 index 000000000..25ab0c9f7 --- /dev/null +++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -0,0 +1,272 @@ +- // MIR for `complicated_match` after SimplifyCfg-initial ++ // MIR for `complicated_match` after ElaborateDrops + + fn complicated_match(_1: bool, _2: (bool, bool, String)) -> i32 { + debug cond => _1; // in scope 0 at $DIR/match-arm-scopes.rs:+0:22: +0:26 + debug items => _2; // in scope 0 at $DIR/match-arm-scopes.rs:+0:34: +0:39 + let mut _0: i32; // return place in scope 0 at $DIR/match-arm-scopes.rs:+0:66: +0:69 + let mut _3: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 + let mut _4: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 + let _5: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 + let _6: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 + let _7: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 + let _8: &std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 + let mut _9: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + let mut _10: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 + let mut _11: !; // in scope 0 at $DIR/match-arm-scopes.rs:+2:52: +2:60 + let mut _12: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + let mut _13: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 + let mut _14: !; // in scope 0 at $DIR/match-arm-scopes.rs:+2:52: +2:60 + let _15: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17 + let _16: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20 + scope 1 { + debug a => _5; // in scope 1 at $DIR/match-arm-scopes.rs:+2:17: +2:18 + debug a => _6; // in scope 1 at $DIR/match-arm-scopes.rs:+2:17: +2:18 + debug s => _7; // in scope 1 at $DIR/match-arm-scopes.rs:+2:20: +2:21 + debug s => _8; // in scope 1 at $DIR/match-arm-scopes.rs:+2:20: +2:21 + } + scope 2 { + debug b => _15; // in scope 2 at $DIR/match-arm-scopes.rs:+3:16: +3:17 + debug t => _16; // in scope 2 at $DIR/match-arm-scopes.rs:+3:19: +3:20 + } + + bb0: { +- FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 +- switchInt((_2.0: bool)) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 + } + + bb1: { +- falseEdge -> [real: bb8, imaginary: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:+2:9: +2:22 ++ switchInt((_2.1: bool)) -> [false: bb10, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 + } + + bb2: { +- switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [false: bb3, otherwise: bb17]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 + } + + bb3: { +- falseEdge -> [real: bb13, imaginary: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+2:25: +2:38 +- } +- +- bb4: { +- switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16 +- } +- +- bb5: { +- falseEdge -> [real: bb20, imaginary: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:+3:9: +3:21 +- } +- +- bb6: { + StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:32: +3:33 + _15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+3:32: +3:33 + StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:35: +3:36 + _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+3:35: +3:36 +- goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 ++ goto -> bb16; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 + } + +- bb7: { ++ bb4: { + _0 = const 1_i32; // scope 1 at $DIR/match-arm-scopes.rs:+2:77: +2:78 +- drop(_7) -> [return: bb18, unwind: bb25]; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 ++ drop(_7) -> [return: bb15, unwind: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + } + +- bb8: { ++ bb5: { + StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 + _6 = &(_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 + StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 + _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 +- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 +- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 + StorageLive(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + StorageLive(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 + _10 = _1; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 +- switchInt(move _10) -> [false: bb10, otherwise: bb9]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 ++ switchInt(move _10) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 + } + +- bb9: { ++ bb6: { + _0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:+2:59: +2:60 + StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- goto -> bb23; // scope 0 at no-location ++ goto -> bb20; // scope 0 at no-location + } + +- bb10: { ++ bb7: { + _9 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:70: +2:71 +- switchInt(move _9) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 ++ switchInt(move _9) -> [false: bb9, otherwise: bb8]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + } + +- bb11: { ++ bb8: { + StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 + _5 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18 + StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 + _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21 +- goto -> bb7; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 ++ goto -> bb4; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 + } + +- bb12: { ++ bb9: { + StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 +- falseEdge -> [real: bb2, imaginary: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 ++ goto -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + } + +- bb13: { ++ bb10: { + StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27 + _6 = &(_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27 + StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37 + _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37 +- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 +- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16 + StorageLive(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + StorageLive(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 + _13 = _1; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 +- switchInt(move _13) -> [false: bb15, otherwise: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 ++ switchInt(move _13) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49 + } + +- bb14: { ++ bb11: { + _0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:+2:59: +2:60 + StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- goto -> bb23; // scope 0 at no-location ++ goto -> bb20; // scope 0 at no-location + } + +- bb15: { ++ bb12: { + _12 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:70: +2:71 +- switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 ++ switchInt(move _12) -> [false: bb14, otherwise: bb13]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + } + +- bb16: { ++ bb13: { + StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 +- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27 + _5 = (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27 + StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37 + _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37 +- goto -> bb7; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 ++ goto -> bb4; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 + } + +- bb17: { ++ bb14: { + StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73 + StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 +- falseEdge -> [real: bb4, imaginary: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 ++ goto -> bb2; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73 + } + +- bb18: { ++ bb15: { + StorageDead(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + StorageDead(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 +- goto -> bb22; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 ++ goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + } + +- bb19: { ++ bb16: { + _0 = const 2_i32; // scope 2 at $DIR/match-arm-scopes.rs:+3:41: +3:42 +- drop(_16) -> [return: bb21, unwind: bb25]; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 ++ drop(_16) -> [return: bb18, unwind: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 + } + +- bb20: { ++ bb17: { + StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17 + _15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17 + StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20 + _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20 +- goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 ++ goto -> bb16; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6 + } + +- bb21: { ++ bb18: { + StorageDead(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 + StorageDead(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 +- goto -> bb22; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 ++ goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42 + } + +- bb22: { +- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ bb19: { ++ goto -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 + } + +- bb23: { ++ bb20: { + StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 + StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78 +- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ drop(_2) -> [return: bb21, unwind: bb23]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 + } + +- bb24: { ++ bb21: { + return; // scope 0 at $DIR/match-arm-scopes.rs:+5:2: +5:2 + } + +- bb25 (cleanup): { +- drop(_2) -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ bb22 (cleanup): { ++ goto -> bb27; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 + } + +- bb26 (cleanup): { ++ bb23 (cleanup): { + resume; // scope 0 at $DIR/match-arm-scopes.rs:+0:1: +5:2 ++ } ++ ++ bb24: { ++ goto -> bb21; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ } ++ ++ bb25 (cleanup): { ++ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ } ++ ++ bb26: { ++ goto -> bb24; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 ++ } ++ ++ bb27 (cleanup): { ++ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2 + } + } + diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir new file mode 100644 index 000000000..c05ed00f7 --- /dev/null +++ b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir @@ -0,0 +1,113 @@ +// MIR for `full_tested_match` after PromoteTemps + +fn full_tested_match() -> () { + let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:28: +0:28 + let mut _1: (i32, i32); // in scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6 + let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:+2:9: +2:16 + let mut _4: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + let _5: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + let _6: &i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + let mut _7: bool; // in scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:35: +2:36 + let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15 + let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:+3:24: +3:25 + let mut _11: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + scope 1 { + } + scope 2 { + debug x => _5; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:15 + debug x => _6; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:15 + } + scope 3 { + debug y => _9; // in scope 3 at $DIR/match_false_edges.rs:+3:14: +3:15 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6 + StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + _2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27 + } + + bb1: { + _1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23 + goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23 + } + + bb2: { + falseEdge -> [real: bb5, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:16 + } + + bb3: { + falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:16 + } + + bb4: { + unreachable; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + } + + bb5: { + StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + _11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + // mir::Constant + // + span: $DIR/match_false_edges.rs:14:14: 14:15 + // + literal: Const { ty: &Option<i32>, val: Unevaluated(full_tested_match, [], Some(promoted[0])) } + _6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + _4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + _7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + // mir::Constant + // + span: $DIR/match_false_edges.rs:14:20: 14:25 + // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) } + } + + bb6: { + switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + } + + bb7: { + StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27 + FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27 + FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27 + StorageLive(_5); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + _5 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:+2:35: +2:36 + _8 = _5; // scope 2 at $DIR/match_false_edges.rs:+2:35: +2:36 + _1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:+2:31: +2:37 + StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:+2:36: +2:37 + StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + } + + bb8: { + StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27 + StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + goto -> bb3; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + } + + bb9: { + StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15 + _9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15 + StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:+3:24: +3:25 + _10 = _9; // scope 3 at $DIR/match_false_edges.rs:+3:24: +3:25 + _1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:+3:20: +3:26 + StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:+3:25: +3:26 + StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26 + goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26 + } + + bb10: { + StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7 + StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7 + _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:28: +6:2 + return; // scope 0 at $DIR/match_false_edges.rs:+6:2: +6:2 + } + + bb11 (cleanup): { + resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2 + } +} diff --git a/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir new file mode 100644 index 000000000..145ed878f --- /dev/null +++ b/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir @@ -0,0 +1,108 @@ +// MIR for `full_tested_match2` before PromoteTemps + +fn full_tested_match2() -> () { + let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:29: +0:29 + let mut _1: (i32, i32); // in scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6 + let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:+2:9: +2:16 + let mut _4: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + let _5: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + let _6: &i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + let mut _7: bool; // in scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:35: +2:36 + let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:+4:24: +4:25 + scope 1 { + } + scope 2 { + debug x => _5; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:15 + debug x => _6; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:15 + } + scope 3 { + debug y => _9; // in scope 3 at $DIR/match_false_edges.rs:+4:14: +4:15 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6 + StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + _2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27 + } + + bb1: { + falseEdge -> [real: bb9, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:13 + } + + bb2: { + falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:16 + } + + bb3: { + StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + _9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:+4:24: +4:25 + _10 = _9; // scope 3 at $DIR/match_false_edges.rs:+4:24: +4:25 + _1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:+4:20: +4:26 + StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:+4:25: +4:26 + StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26 + goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26 + } + + bb4: { + unreachable; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + } + + bb5: { + StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + _6 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + _4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 + StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + _7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + // mir::Constant + // + span: $DIR/match_false_edges.rs:25:20: 25:25 + // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) } + } + + bb6: { + switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + } + + bb7: { + StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27 + FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27 + FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27 + StorageLive(_5); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + _5 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:+2:35: +2:36 + _8 = _5; // scope 2 at $DIR/match_false_edges.rs:+2:35: +2:36 + _1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:+2:31: +2:37 + StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:+2:36: +2:37 + StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + } + + bb8: { + StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27 + StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + falseEdge -> [real: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + } + + bb9: { + _1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23 + goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23 + } + + bb10: { + StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7 + StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7 + _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:29: +6:2 + return; // scope 0 at $DIR/match_false_edges.rs:+6:2: +6:2 + } + + bb11 (cleanup): { + resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2 + } +} diff --git a/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir new file mode 100644 index 000000000..8f40e8a88 --- /dev/null +++ b/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir @@ -0,0 +1,153 @@ +// MIR for `main` before PromoteTemps + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/match_false_edges.rs:+1:13: +6:6 + let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16 + let mut _4: isize; // in scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17 + let mut _5: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + let _6: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16 + let _7: &i32; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16 + let mut _8: bool; // in scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + let _9: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11 + let _10: i32; // in scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + let _11: &i32; // in scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + let mut _12: bool; // in scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + let mut _13: i32; // in scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28 + let _14: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11 + scope 1 { + } + scope 2 { + debug _w => _6; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:16 + debug _w => _7; // in scope 2 at $DIR/match_false_edges.rs:+2:14: +2:16 + } + scope 3 { + debug _x => _9; // in scope 3 at $DIR/match_false_edges.rs:+3:9: +3:11 + } + scope 4 { + debug y => _10; // in scope 4 at $DIR/match_false_edges.rs:+4:14: +4:15 + debug y => _11; // in scope 4 at $DIR/match_false_edges.rs:+4:14: +4:15 + } + scope 5 { + debug _z => _14; // in scope 5 at $DIR/match_false_edges.rs:+5:9: +5:11 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +6:6 + StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + _2 = Option::<i32>::Some(const 1_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + _4 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 + } + + bb1: { + falseEdge -> [real: bb9, imaginary: bb4]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11 + } + + bb2: { + falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17 + } + + bb3: { + StorageLive(_14); // scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11 + _14 = _2; // scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11 + _1 = const 4_i32; // scope 5 at $DIR/match_false_edges.rs:+5:15: +5:16 + StorageDead(_14); // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16 + goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16 + } + + bb4: { + falseEdge -> [real: bb10, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16 + } + + bb5: { + StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16 + _7 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16 + _5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + StorageLive(_8); // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + _8 = guard() -> [return: bb6, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + // mir::Constant + // + span: $DIR/match_false_edges.rs:34:21: 34:26 + // + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) } + } + + bb6: { + switchInt(move _8) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + } + + bb7: { + StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28 + FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28 + FakeRead(ForGuardBinding, _7); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28 + StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16 + _6 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16 + _1 = const 1_i32; // scope 2 at $DIR/match_false_edges.rs:+2:32: +2:33 + StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33 + StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33 + goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33 + } + + bb8: { + StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28 + StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33 + falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + } + + bb9: { + StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11 + _9 = _2; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11 + _1 = const 2_i32; // scope 3 at $DIR/match_false_edges.rs:+3:15: +3:16 + StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16 + goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16 + } + + bb10: { + StorageLive(_11); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + _11 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + _5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + StorageLive(_12); // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + StorageLive(_13); // scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28 + _13 = (*_11); // scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28 + _12 = guard2(move _13) -> [return: bb11, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + // mir::Constant + // + span: $DIR/match_false_edges.rs:36:20: 36:26 + // + literal: Const { ty: fn(i32) -> bool {guard2}, val: Value(<ZST>) } + } + + bb11: { + switchInt(move _12) -> [false: bb13, otherwise: bb12]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + } + + bb12: { + StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29 + StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29 + FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29 + FakeRead(ForGuardBinding, _11); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29 + StorageLive(_10); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + _10 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15 + _1 = const 3_i32; // scope 4 at $DIR/match_false_edges.rs:+4:33: +4:34 + StorageDead(_10); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34 + StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34 + goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34 + } + + bb13: { + StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29 + StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29 + StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34 + falseEdge -> [real: bb3, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + } + + bb14: { + StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7 + StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7 + _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:11: +7:2 + return; // scope 0 at $DIR/match_false_edges.rs:+7:2: +7:2 + } + + bb15 (cleanup): { + resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +7:2 + } +} diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs new file mode 100644 index 000000000..3603253da --- /dev/null +++ b/src/test/mir-opt/match_false_edges.rs @@ -0,0 +1,39 @@ +fn guard() -> bool { + false +} + +fn guard2(_: i32) -> bool { + true +} + +// no_mangle to make sure this gets instantiated even in an executable. +#[no_mangle] +// EMIT_MIR match_false_edges.full_tested_match.PromoteTemps.after.mir +pub fn full_tested_match() { + let _ = match Some(42) { + Some(x) if guard() => (1, x), + Some(y) => (2, y), + None => (3, 3), + }; +} + +// no_mangle to make sure this gets instantiated even in an executable. +#[no_mangle] +// EMIT_MIR match_false_edges.full_tested_match2.PromoteTemps.before.mir +pub fn full_tested_match2() { + let _ = match Some(42) { + Some(x) if guard() => (1, x), + None => (3, 3), + Some(y) => (2, y), + }; +} + +// EMIT_MIR match_false_edges.main.PromoteTemps.before.mir +fn main() { + let _ = match Some(1) { + Some(_w) if guard() => 1, + _x => 2, + Some(y) if guard2(y) => 3, + _z => 4, + }; +} diff --git a/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..b184ffc40 --- /dev/null +++ b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir @@ -0,0 +1,106 @@ +// MIR for `main` after SimplifyCfg-initial + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/match_test.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/match_test.rs:+1:9: +1:10 + let _3: i32; // in scope 0 at $DIR/match_test.rs:+6:5: +11:6 + let mut _4: bool; // in scope 0 at $DIR/match_test.rs:+8:9: +8:16 + let mut _5: bool; // in scope 0 at $DIR/match_test.rs:+8:9: +8:16 + let mut _6: bool; // in scope 0 at $DIR/match_test.rs:+7:9: +7:14 + let mut _7: bool; // in scope 0 at $DIR/match_test.rs:+7:9: +7:14 + let mut _8: &i32; // in scope 0 at $DIR/match_test.rs:+6:11: +6:12 + let mut _9: bool; // in scope 0 at $DIR/match_test.rs:+7:18: +7:19 + scope 1 { + debug x => _1; // in scope 1 at $DIR/match_test.rs:+1:9: +1:10 + let _2: bool; // in scope 1 at $DIR/match_test.rs:+2:9: +2:10 + scope 2 { + debug b => _2; // in scope 2 at $DIR/match_test.rs:+2:9: +2:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/match_test.rs:+1:9: +1:10 + _1 = const 3_i32; // scope 0 at $DIR/match_test.rs:+1:13: +1:14 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/match_test.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/match_test.rs:+2:9: +2:10 + _2 = const true; // scope 1 at $DIR/match_test.rs:+2:13: +2:17 + FakeRead(ForLet(None), _2); // scope 1 at $DIR/match_test.rs:+2:9: +2:10 + StorageLive(_3); // scope 2 at $DIR/match_test.rs:+6:5: +11:6 + FakeRead(ForMatchedPlace(None), _1); // scope 2 at $DIR/match_test.rs:+6:11: +6:12 + _6 = Le(const 0_i32, _1); // scope 2 at $DIR/match_test.rs:+7:9: +7:14 + switchInt(move _6) -> [false: bb4, otherwise: bb1]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14 + } + + bb1: { + _7 = Lt(_1, const 10_i32); // scope 2 at $DIR/match_test.rs:+7:9: +7:14 + switchInt(move _7) -> [false: bb4, otherwise: bb2]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14 + } + + bb2: { + falseEdge -> [real: bb9, imaginary: bb6]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14 + } + + bb3: { + _3 = const 3_i32; // scope 2 at $DIR/match_test.rs:+10:14: +10:15 + goto -> bb14; // scope 2 at $DIR/match_test.rs:+10:14: +10:15 + } + + bb4: { + _4 = Le(const 10_i32, _1); // scope 2 at $DIR/match_test.rs:+8:9: +8:16 + switchInt(move _4) -> [false: bb7, otherwise: bb5]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16 + } + + bb5: { + _5 = Le(_1, const 20_i32); // scope 2 at $DIR/match_test.rs:+8:9: +8:16 + switchInt(move _5) -> [false: bb7, otherwise: bb6]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16 + } + + bb6: { + falseEdge -> [real: bb12, imaginary: bb8]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16 + } + + bb7: { + switchInt(_1) -> [-1_i32: bb8, otherwise: bb3]; // scope 2 at $DIR/match_test.rs:+6:5: +6:12 + } + + bb8: { + falseEdge -> [real: bb13, imaginary: bb3]; // scope 2 at $DIR/match_test.rs:+9:9: +9:11 + } + + bb9: { + _8 = &shallow _1; // scope 2 at $DIR/match_test.rs:+6:11: +6:12 + StorageLive(_9); // scope 2 at $DIR/match_test.rs:+7:18: +7:19 + _9 = _2; // scope 2 at $DIR/match_test.rs:+7:18: +7:19 + switchInt(move _9) -> [false: bb11, otherwise: bb10]; // scope 2 at $DIR/match_test.rs:+7:18: +7:19 + } + + bb10: { + StorageDead(_9); // scope 2 at $DIR/match_test.rs:+7:18: +7:19 + FakeRead(ForMatchGuard, _8); // scope 2 at $DIR/match_test.rs:+7:18: +7:19 + _3 = const 0_i32; // scope 2 at $DIR/match_test.rs:+7:23: +7:24 + goto -> bb14; // scope 2 at $DIR/match_test.rs:+7:23: +7:24 + } + + bb11: { + StorageDead(_9); // scope 2 at $DIR/match_test.rs:+7:18: +7:19 + falseEdge -> [real: bb3, imaginary: bb6]; // scope 2 at $DIR/match_test.rs:+7:18: +7:19 + } + + bb12: { + _3 = const 1_i32; // scope 2 at $DIR/match_test.rs:+8:20: +8:21 + goto -> bb14; // scope 2 at $DIR/match_test.rs:+8:20: +8:21 + } + + bb13: { + _3 = const 2_i32; // scope 2 at $DIR/match_test.rs:+9:15: +9:16 + goto -> bb14; // scope 2 at $DIR/match_test.rs:+9:15: +9:16 + } + + bb14: { + StorageDead(_3); // scope 2 at $DIR/match_test.rs:+11:6: +11:7 + _0 = const (); // scope 0 at $DIR/match_test.rs:+0:11: +12:2 + StorageDead(_2); // scope 1 at $DIR/match_test.rs:+12:1: +12:2 + StorageDead(_1); // scope 0 at $DIR/match_test.rs:+12:1: +12:2 + return; // scope 0 at $DIR/match_test.rs:+12:2: +12:2 + } +} diff --git a/src/test/mir-opt/match_test.rs b/src/test/mir-opt/match_test.rs new file mode 100644 index 000000000..3a2107790 --- /dev/null +++ b/src/test/mir-opt/match_test.rs @@ -0,0 +1,18 @@ +// Make sure redundant testing paths in `match` expressions are sorted out. + +#![feature(exclusive_range_pattern)] + +// EMIT_MIR match_test.main.SimplifyCfg-initial.after.mir +fn main() { + let x = 3; + let b = true; + + // When `(0..=10).contains(x) && !b`, we should jump to the last arm + // without testing two other candidates. + match x { + 0..10 if b => 0, + 10..=20 => 1, + -1 => 2, + _ => 3, + }; +} diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff new file mode 100644 index 000000000..2005c10ef --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff @@ -0,0 +1,88 @@ +- // MIR for `bar` before MatchBranchSimplification ++ // MIR for `bar` after MatchBranchSimplification + + fn bar(_1: i32) -> (bool, bool, bool, bool) { + debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:9 + let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:19: +0:43 + let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10 + let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +21:6 + let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:6: +23:7 + let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:9: +23:10 + let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:12: +23:13 + let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:15: +23:16 ++ let mut _11: i32; // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 + scope 1 { + debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:10 + let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10 + scope 2 { + debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:+2:9: +2:10 + let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10 + scope 3 { + debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:+3:9: +3:10 + let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10 + scope 4 { + debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:+4:9: +4:10 + } + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10 + StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10 + StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10 + StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10 + StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6 +- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 +- } +- +- bb1: { +- _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+15:13: +15:21 +- _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22 +- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22 +- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21 +- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15 +- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15 +- } +- +- bb2: { +- _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22 +- _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21 ++ StorageLive(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 ++ _11 = _1; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 ++ _2 = Ne(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22 ++ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21 + _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+10:13: +10:22 + _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+11:13: +11:21 +- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15 +- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15 +- } +- +- bb3: { ++ StorageDead(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 + StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+21:6: +21:7 + StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7 + _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7 + StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10 + _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10 + StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13 + _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13 + StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16 + _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16 + Deinit(_0); // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17 + StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17 + StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17 + StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17 + StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+24:1: +24:2 + StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+24:1: +24:2 + StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+24:1: +24:2 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+24:1: +24:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:+24:2: +24:2 + } + } + diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff new file mode 100644 index 000000000..2005c10ef --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff @@ -0,0 +1,88 @@ +- // MIR for `bar` before MatchBranchSimplification ++ // MIR for `bar` after MatchBranchSimplification + + fn bar(_1: i32) -> (bool, bool, bool, bool) { + debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:9 + let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:19: +0:43 + let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10 + let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +21:6 + let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:6: +23:7 + let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:9: +23:10 + let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:12: +23:13 + let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+23:15: +23:16 ++ let mut _11: i32; // in scope 0 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 + scope 1 { + debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:10 + let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10 + scope 2 { + debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:+2:9: +2:10 + let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10 + scope 3 { + debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:+3:9: +3:10 + let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10 + scope 4 { + debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:+4:9: +4:10 + } + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:10 + StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+2:9: +2:10 + StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10 + StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10 + StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6 +- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 +- } +- +- bb1: { +- _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+15:13: +15:21 +- _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22 +- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22 +- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21 +- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15 +- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15 +- } +- +- bb2: { +- _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22 +- _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21 ++ StorageLive(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 ++ _11 = _1; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 ++ _2 = Ne(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+8:13: +8:22 ++ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21 + _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+10:13: +10:22 + _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+11:13: +11:21 +- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15 +- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15 +- } +- +- bb3: { ++ StorageDead(_11); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 + StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+21:6: +21:7 + StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7 + _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:+23:6: +23:7 + StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10 + _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:+23:9: +23:10 + StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13 + _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:+23:12: +23:13 + StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16 + _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:+23:15: +23:16 + Deinit(_0); // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:+23:5: +23:17 + StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17 + StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17 + StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17 + StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:+23:16: +23:17 + StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+24:1: +24:2 + StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+24:1: +24:2 + StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:+24:1: +24:2 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+24:1: +24:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:+24:2: +24:2 + } + } + diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff new file mode 100644 index 000000000..b7862e567 --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff @@ -0,0 +1,30 @@ +- // MIR for `foo` before MatchBranchSimplification ++ // MIR for `foo` after MatchBranchSimplification + + fn foo(_1: Option<()>) -> () { + debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11 + let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25 + let mut _2: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26 ++ let mut _3: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20 +- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb1: { +- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb2: { +- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb3: { ++ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ _3 = move _2; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff new file mode 100644 index 000000000..b7862e567 --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff @@ -0,0 +1,30 @@ +- // MIR for `foo` before MatchBranchSimplification ++ // MIR for `foo` after MatchBranchSimplification + + fn foo(_1: Option<()>) -> () { + debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11 + let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25 + let mut _2: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26 ++ let mut _3: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20 +- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb1: { +- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb2: { +- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb3: { ++ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ _3 = move _2; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir new file mode 100644 index 000000000..a36ec8de4 --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.32bit.mir @@ -0,0 +1,10 @@ +// MIR for `foo` before PreCodegen + +fn foo(_1: Option<()>) -> () { + debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11 + let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25 + + bb0: { + return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir new file mode 100644 index 000000000..a36ec8de4 --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.foo.PreCodegen.before.64bit.mir @@ -0,0 +1,10 @@ +// MIR for `foo` before PreCodegen + +fn foo(_1: Option<()>) -> () { + debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11 + let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25 + + bb0: { + return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff new file mode 100644 index 000000000..672c6b34e --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff @@ -0,0 +1,42 @@ +- // MIR for `match_nested_if` before MatchBranchSimplification ++ // MIR for `match_nested_if` after MatchBranchSimplification + + fn match_nested_if() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29 + let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12 + let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 ++ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + scope 1 { + debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12 + StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 +- } +- +- bb1: { ++ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 ++ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52 +- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17 +- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17 +- } +- +- bb2: { +- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52 +- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 +- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 +- } +- +- bb3: { ++ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 ++ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8 + StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2 + } + } + diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff new file mode 100644 index 000000000..672c6b34e --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff @@ -0,0 +1,42 @@ +- // MIR for `match_nested_if` before MatchBranchSimplification ++ // MIR for `match_nested_if` after MatchBranchSimplification + + fn match_nested_if() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29 + let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12 + let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 ++ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + scope 1 { + debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12 + StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 +- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 +- } +- +- bb1: { ++ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 ++ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52 +- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17 +- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17 +- } +- +- bb2: { +- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52 +- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 +- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 +- } +- +- bb3: { ++ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 ++ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8 + StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2 + } + } + diff --git a/src/test/mir-opt/matches_reduce_branches.rs b/src/test/mir-opt/matches_reduce_branches.rs new file mode 100644 index 000000000..51be3884d --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.rs @@ -0,0 +1,59 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR matches_reduce_branches.foo.MatchBranchSimplification.diff +// EMIT_MIR matches_reduce_branches.foo.PreCodegen.before.mir +// EMIT_MIR matches_reduce_branches.bar.MatchBranchSimplification.diff +// EMIT_MIR matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff + +fn foo(bar: Option<()>) { + if matches!(bar, None) { + () + } +} + +fn bar(i: i32) -> (bool, bool, bool, bool) { + let a; + let b; + let c; + let d; + + match i { + 7 => { + a = false; + b = true; + c = false; + d = true; + () + } + _ => { + a = true; + b = false; + c = false; + d = true; + () + } + }; + + (a, b, c, d) +} + +fn match_nested_if() -> bool { + let val = match () { + () if if if if true { true } else { false } { true } else { false } { + true + } else { + false + } => + { + true + } + _ => false, + }; + val +} + +fn main() { + let _ = foo(None); + let _ = foo(Some(())); + let _ = bar(0); + let _ = match_nested_if(); +} diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff new file mode 100644 index 000000000..c42657b38 --- /dev/null +++ b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.32bit.diff @@ -0,0 +1,28 @@ +- // MIR for `exhaustive_match` before MatchBranchSimplification ++ // MIR for `exhaustive_match` after MatchBranchSimplification + + fn exhaustive_match(_1: E) -> u8 { + debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:25: +0:26 + let mut _0: u8; // return place in scope 0 at $DIR/matches_u8.rs:+0:34: +0:36 + let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + } + + bb2: { + _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + } + + bb3: { + return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff new file mode 100644 index 000000000..c42657b38 --- /dev/null +++ b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.64bit.diff @@ -0,0 +1,28 @@ +- // MIR for `exhaustive_match` before MatchBranchSimplification ++ // MIR for `exhaustive_match` after MatchBranchSimplification + + fn exhaustive_match(_1: E) -> u8 { + debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:25: +0:26 + let mut _0: u8; // return place in scope 0 at $DIR/matches_u8.rs:+0:34: +0:36 + let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 1_u8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + } + + bb2: { + _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + } + + bb3: { + return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff new file mode 100644 index 000000000..a4ff2e437 --- /dev/null +++ b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.32bit.diff @@ -0,0 +1,28 @@ +- // MIR for `exhaustive_match_i8` before MatchBranchSimplification ++ // MIR for `exhaustive_match_i8` after MatchBranchSimplification + + fn exhaustive_match_i8(_1: E) -> i8 { + debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:28: +0:29 + let mut _0: i8; // return place in scope 0 at $DIR/matches_u8.rs:+0:37: +0:39 + let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + } + + bb2: { + _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + } + + bb3: { + return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff new file mode 100644 index 000000000..a4ff2e437 --- /dev/null +++ b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.64bit.diff @@ -0,0 +1,28 @@ +- // MIR for `exhaustive_match_i8` before MatchBranchSimplification ++ // MIR for `exhaustive_match_i8` after MatchBranchSimplification + + fn exhaustive_match_i8(_1: E) -> i8 { + debug e => _1; // in scope 0 at $DIR/matches_u8.rs:+0:28: +0:29 + let mut _0: i8; // return place in scope 0 at $DIR/matches_u8.rs:+0:37: +0:39 + let mut _2: isize; // in scope 0 at $DIR/matches_u8.rs:+2:9: +2:13 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 1_i8; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + } + + bb2: { + _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + goto -> bb3; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + } + + bb3: { + return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/matches_u8.rs b/src/test/mir-opt/matches_u8.rs new file mode 100644 index 000000000..78373be48 --- /dev/null +++ b/src/test/mir-opt/matches_u8.rs @@ -0,0 +1,32 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff +// EMIT_MIR matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff + +pub enum E { + A, + B, +} + +#[no_mangle] +pub fn exhaustive_match(e: E) -> u8 { + match e { + E::A => 0, + E::B => 1, + } +} + +#[no_mangle] +pub fn exhaustive_match_i8(e: E) -> i8 { + match e { + E::A => 0, + E::B => 1, + } +} + +fn main() { + assert_eq!(exhaustive_match(E::A), 0); + assert_eq!(exhaustive_match(E::B), 1); + + assert_eq!(exhaustive_match_i8(E::A), 0); + assert_eq!(exhaustive_match_i8(E::B), 1); +} diff --git a/src/test/mir-opt/multiple_return_terminators.rs b/src/test/mir-opt/multiple_return_terminators.rs new file mode 100644 index 000000000..a2b902d14 --- /dev/null +++ b/src/test/mir-opt/multiple_return_terminators.rs @@ -0,0 +1,14 @@ +// compile-flags: -Z mir-opt-level=4 +// EMIT_MIR multiple_return_terminators.test.MultipleReturnTerminators.diff + +fn test(x: bool) { + if x { + // test + } else { + // test + } +} + +fn main() { + test(true) +} diff --git a/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff b/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff new file mode 100644 index 000000000..48a11c950 --- /dev/null +++ b/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff @@ -0,0 +1,12 @@ +- // MIR for `test` before MultipleReturnTerminators ++ // MIR for `test` after MultipleReturnTerminators + + fn test(_1: bool) -> () { + debug x => _1; // in scope 0 at $DIR/multiple_return_terminators.rs:+0:9: +0:10 + let mut _0: (); // return place in scope 0 at $DIR/multiple_return_terminators.rs:+0:18: +0:18 + + bb0: { + return; // scope 0 at $DIR/multiple_return_terminators.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/nll/named-lifetimes-basic.rs b/src/test/mir-opt/nll/named-lifetimes-basic.rs new file mode 100644 index 000000000..843716033 --- /dev/null +++ b/src/test/mir-opt/nll/named-lifetimes-basic.rs @@ -0,0 +1,15 @@ +// Basic test for named lifetime translation. Check that we +// instantiate the types that appear in function arguments with +// suitable variables and that we setup the outlives relationship +// between R0 and R1 properly. + +// compile-flags: -Zverbose +// ^^^^^^^^^ force compiler to dump more region information + +#![allow(warnings)] + +// EMIT_MIR named_lifetimes_basic.use_x.nll.0.mir +fn use_x<'a, 'b: 'a, 'c>(w: &'a mut i32, x: &'b u32, y: &'a u32, z: &'c u32) -> bool { true } + +fn main() { +} diff --git a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir new file mode 100644 index 000000000..cbfdf8c5d --- /dev/null +++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir @@ -0,0 +1,48 @@ +// MIR for `use_x` 0 nll + +| Free Region Mapping +| '_#0r | Global | ['_#2r, '_#1r, '_#0r, '_#4r, '_#3r] +| '_#1r | Local | ['_#1r, '_#4r] +| '_#2r | Local | ['_#2r, '_#1r, '_#4r] +| '_#3r | Local | ['_#4r, '_#3r] +| '_#4r | Local | ['_#4r] +| +| Inferred Region Values +| '_#0r | U0 | {bb0[0..=1], '_#0r, '_#1r, '_#2r, '_#3r, '_#4r} +| '_#1r | U0 | {bb0[0..=1], '_#1r} +| '_#2r | U0 | {bb0[0..=1], '_#2r} +| '_#3r | U0 | {bb0[0..=1], '_#3r} +| '_#4r | U0 | {bb0[0..=1], '_#4r} +| '_#5r | U0 | {} +| '_#6r | U0 | {bb0[0..=1], '_#1r} +| '_#7r | U0 | {bb0[0..=1], '_#2r} +| '_#8r | U0 | {bb0[0..=1], '_#1r} +| '_#9r | U0 | {bb0[0..=1], '_#3r} +| +| Inference Constraints +| '_#0r live at {bb0[0..=1]} +| '_#1r live at {bb0[0..=1]} +| '_#2r live at {bb0[0..=1]} +| '_#3r live at {bb0[0..=1]} +| '_#4r live at {bb0[0..=1]} +| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) +| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) +| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) +| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) +| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) +| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) +| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) +| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) +| +fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool { + debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:26: +0:27 + debug x => _2; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:42: +0:43 + debug y => _3; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:54: +0:55 + debug z => _4; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:66: +0:67 + let mut _0: bool; // return place in scope 0 at $DIR/named-lifetimes-basic.rs:+0:81: +0:85 + + bb0: { + _0 = const ConstValue(Scalar(0x01): bool); // bb0[0]: scope 0 at $DIR/named-lifetimes-basic.rs:+0:88: +0:92 + return; // bb0[1]: scope 0 at $DIR/named-lifetimes-basic.rs:+0:94: +0:94 + } +} diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs new file mode 100644 index 000000000..64332f302 --- /dev/null +++ b/src/test/mir-opt/nll/region-subtyping-basic.rs @@ -0,0 +1,25 @@ +// Basic test for liveness constraints: the region (`R1`) that appears +// in the type of `p` includes the points after `&v[0]` up to (but not +// including) the call to `use_x`. The `else` branch is not included. + +// compile-flags:-Zverbose +// ^^^^^^^^^ force compiler to dump more region information + +#![allow(warnings)] + +fn use_x(_: usize) -> bool { + true +} + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR region_subtyping_basic.main.nll.0.mir +fn main() { + let mut v = [1, 2, 3]; + let p = &v[0]; + let q = p; + if true { + use_x(*q); + } else { + use_x(22); + } +} diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir new file mode 100644 index 000000000..55e7faf9e --- /dev/null +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -0,0 +1,112 @@ +// MIR for `main` 0 nll + +| Free Region Mapping +| '_#0r | Global | ['_#0r, '_#1r] +| '_#1r | Local | ['_#1r] +| +| Inferred Region Values +| '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r} +| '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r} +| '_#2r | U0 | {} +| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]} +| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]} +| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]} +| +| Inference Constraints +| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} +| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} +| '_#3r live at {bb1[0]} +| '_#4r live at {bb1[1..=3]} +| '_#5r live at {bb1[4..=7], bb2[0..=2]} +| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) +| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) +| +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11 + let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x00000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 + let _3: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 + let mut _4: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + let mut _5: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + let mut _7: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + let _8: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 + let mut _9: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 + let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + scope 1 { + debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 + let _2: &'_#4r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + scope 2 { + debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + let _6: &'_#5r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + scope 3 { + debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 + _1 = [const ConstValue(Scalar(0x00000001): usize), const ConstValue(Scalar(0x00000002): usize), const ConstValue(Scalar(0x00000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:+1:17: +1:26 + FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 + StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 + _3 = const ConstValue(Scalar(0x00000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 + _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + } + + bb1: { + _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18 + FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14 + FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + } + + bb2: { + StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 + StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 + _9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 + _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 + // mir::Constant + // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14 + // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:17: +5:18 + StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:18: +5:19 + _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:13: +6:6 + goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6 + } + + bb4: { + StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + // mir::Constant + // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14 + // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:18: +7:19 + _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:+6:12: +8:6 + goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6 + } + + bb6: { + StorageDead(_7); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:+8:5: +8:6 + StorageDead(_6); // bb6[1]: scope 2 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 + StorageDead(_3); // bb6[2]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 + StorageDead(_2); // bb6[3]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 + StorageDead(_1); // bb6[4]: scope 0 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 + return; // bb6[5]: scope 0 at $DIR/region-subtyping-basic.rs:+9:2: +9:2 + } + + bb7 (cleanup): { + resume; // bb7[0]: scope 0 at $DIR/region-subtyping-basic.rs:+0:1: +9:2 + } +} diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir new file mode 100644 index 000000000..2647c9433 --- /dev/null +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -0,0 +1,112 @@ +// MIR for `main` 0 nll + +| Free Region Mapping +| '_#0r | Global | ['_#0r, '_#1r] +| '_#1r | Local | ['_#1r] +| +| Inferred Region Values +| '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r} +| '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r} +| '_#2r | U0 | {} +| '_#3r | U0 | {bb1[0..=7], bb2[0..=2]} +| '_#4r | U0 | {bb1[1..=7], bb2[0..=2]} +| '_#5r | U0 | {bb1[4..=7], bb2[0..=2]} +| +| Inference Constraints +| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} +| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} +| '_#3r live at {bb1[0]} +| '_#4r live at {bb1[1..=3]} +| '_#5r live at {bb1[4..=7], bb2[0..=2]} +| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) +| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) +| +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11 + let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x0000000000000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 + let _3: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 + let mut _4: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + let mut _5: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + let mut _7: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + let _8: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 + let mut _9: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 + let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + scope 1 { + debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 + let _2: &'_#4r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + scope 2 { + debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + let _6: &'_#5r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + scope 3 { + debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 + _1 = [const ConstValue(Scalar(0x0000000000000001): usize), const ConstValue(Scalar(0x0000000000000002): usize), const ConstValue(Scalar(0x0000000000000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:+1:17: +1:26 + FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14 + StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 + _3 = const ConstValue(Scalar(0x0000000000000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17 + _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18 + } + + bb1: { + _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18 + FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10 + StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14 + FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10 + StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12 + } + + bb2: { + StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 + StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 + _9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17 + _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18 + // mir::Constant + // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14 + // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:17: +5:18 + StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:18: +5:19 + _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:13: +6:6 + goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6 + } + + bb4: { + StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18 + // mir::Constant + // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14 + // + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:18: +7:19 + _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:+6:12: +8:6 + goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6 + } + + bb6: { + StorageDead(_7); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:+8:5: +8:6 + StorageDead(_6); // bb6[1]: scope 2 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 + StorageDead(_3); // bb6[2]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 + StorageDead(_2); // bb6[3]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 + StorageDead(_1); // bb6[4]: scope 0 at $DIR/region-subtyping-basic.rs:+9:1: +9:2 + return; // bb6[5]: scope 0 at $DIR/region-subtyping-basic.rs:+9:2: +9:2 + } + + bb7 (cleanup): { + resume; // bb7[0]: scope 0 at $DIR/region-subtyping-basic.rs:+0:1: +9:2 + } +} diff --git a/src/test/mir-opt/no-drop-for-inactive-variant.rs b/src/test/mir-opt/no-drop-for-inactive-variant.rs new file mode 100644 index 000000000..34e2b1a13 --- /dev/null +++ b/src/test/mir-opt/no-drop-for-inactive-variant.rs @@ -0,0 +1,16 @@ +// ignore-wasm32-bare compiled with panic=abort by default + +// Ensure that there are no drop terminators in `unwrap<T>` (except the one along the cleanup +// path). + +// EMIT_MIR no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir +fn unwrap<T>(opt: Option<T>) -> T { + match opt { + Some(x) => x, + None => panic!(), + } +} + +fn main() { + let _ = unwrap(Some(1i32)); +} diff --git a/src/test/mir-opt/no-spurious-drop-after-call.rs b/src/test/mir-opt/no-spurious-drop-after-call.rs new file mode 100644 index 000000000..bb5bb9aa4 --- /dev/null +++ b/src/test/mir-opt/no-spurious-drop-after-call.rs @@ -0,0 +1,10 @@ +// ignore-wasm32-bare compiled with panic=abort by default + +// Test that after the call to `std::mem::drop` we do not generate a +// MIR drop of the argument. (We used to have a `DROP(_2)` in the code +// below, as part of bb3.) + +// EMIT_MIR no_spurious_drop_after_call.main.ElaborateDrops.before.mir +fn main() { + std::mem::drop("".to_string()); +} diff --git a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..50fd98ff1 --- /dev/null +++ b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,49 @@ +// MIR for `unwrap` after SimplifyCfg-elaborate-drops + +fn unwrap(_1: Option<T>) -> T { + debug opt => _1; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:14: +0:17 + let mut _0: T; // return place in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:33: +0:34 + let mut _2: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:9: +2:16 + let _3: T; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15 + let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + let mut _5: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 + let mut _6: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 + let mut _7: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 + scope 1 { + debug x => _3; // in scope 1 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:11: +1:14 + switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:5: +1:14 + } + + bb1: { + StorageLive(_4); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + _4 = begin_panic::<&str>(const "explicit panic") -> bb4; // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) } + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb2: { + unreachable; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:11: +1:14 + } + + bb3: { + StorageLive(_3); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15 + _3 = move ((_1 as Some).0: T); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15 + _0 = move _3; // scope 1 at $DIR/no-drop-for-inactive-variant.rs:+2:20: +2:21 + StorageDead(_3); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:20: +2:21 + _5 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 + return; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:2: +5:2 + } + + bb4 (cleanup): { + _7 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2 + resume; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:1: +5:2 + } +} diff --git a/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir new file mode 100644 index 000000000..25c6e3060 --- /dev/null +++ b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir @@ -0,0 +1,49 @@ +// MIR for `main` before ElaborateDrops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35 + let mut _2: std::string::String; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 + let mut _3: &str; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 + let _4: &str; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35 + StorageLive(_2); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 + StorageLive(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 + StorageLive(_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22 + _4 = const ""; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22 + // mir::Constant + // + span: $DIR/no-spurious-drop-after-call.rs:9:20: 9:22 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _3 = &(*_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 + _2 = <str as ToString>::to_string(move _3) -> bb1; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34 + // mir::Constant + // + span: $DIR/no-spurious-drop-after-call.rs:9:23: 9:32 + // + literal: Const { ty: for<'r> fn(&'r str) -> String {<str as ToString>::to_string}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:33: +1:34 + _1 = std::mem::drop::<String>(move _2) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35 + // mir::Constant + // + span: $DIR/no-spurious-drop-after-call.rs:9:5: 9:19 + // + literal: Const { ty: fn(String) {std::mem::drop::<String>}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_2); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:34: +1:35 + StorageDead(_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:35: +1:36 + StorageDead(_1); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:35: +1:36 + _0 = const (); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:11: +2:2 + return; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+2:2: +2:2 + } + + bb3 (cleanup): { + drop(_2) -> bb4; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:34: +1:35 + } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:1: +2:2 + } +} diff --git a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff new file mode 100644 index 000000000..5009d0906 --- /dev/null +++ b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff @@ -0,0 +1,35 @@ +- // MIR for `opt` before InstCombine ++ // MIR for `opt` after InstCombine + + fn opt(_1: bool) -> u32 { + debug x => _1; // in scope 0 at $DIR/not_equal_false.rs:+0:8: +0:9 + let mut _0: u32; // return place in scope 0 at $DIR/not_equal_false.rs:+0:20: +0:23 + let mut _2: bool; // in scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 + let mut _3: bool; // in scope 0 at $DIR/not_equal_false.rs:+1:8: +1:9 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 + StorageLive(_3); // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:9 + _3 = _1; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:9 +- _2 = Ne(move _3, const false); // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 ++ _2 = move _3; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 + StorageDead(_3); // scope 0 at $DIR/not_equal_false.rs:+1:17: +1:18 + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 + } + + bb1: { + _0 = const 0_u32; // scope 0 at $DIR/not_equal_false.rs:+1:21: +1:22 + goto -> bb3; // scope 0 at $DIR/not_equal_false.rs:+1:5: +1:35 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/not_equal_false.rs:+1:32: +1:33 + goto -> bb3; // scope 0 at $DIR/not_equal_false.rs:+1:5: +1:35 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/not_equal_false.rs:+1:34: +1:35 + return; // scope 0 at $DIR/not_equal_false.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/not_equal_false.rs b/src/test/mir-opt/not_equal_false.rs new file mode 100644 index 000000000..5fbb848dc --- /dev/null +++ b/src/test/mir-opt/not_equal_false.rs @@ -0,0 +1,9 @@ +// EMIT_MIR not_equal_false.opt.InstCombine.diff + +fn opt(x: bool) -> u32 { + if x != false { 0 } else { 1 } +} + +fn main() { + opt(false); +} diff --git a/src/test/mir-opt/nrvo-simple.rs b/src/test/mir-opt/nrvo-simple.rs new file mode 100644 index 000000000..5786ae621 --- /dev/null +++ b/src/test/mir-opt/nrvo-simple.rs @@ -0,0 +1,12 @@ +// unit-test: RenameReturnPlace + +// EMIT_MIR nrvo_simple.nrvo.RenameReturnPlace.diff +fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { + let mut buf = [0; 1024]; + init(&mut buf); + buf +} + +fn main() { + let _ = nrvo(|buf| { buf[4] = 4; }); +} diff --git a/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff new file mode 100644 index 000000000..9e89bd9fb --- /dev/null +++ b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff @@ -0,0 +1,43 @@ +- // MIR for `nrvo` before RenameReturnPlace ++ // MIR for `nrvo` after RenameReturnPlace + + fn nrvo(_1: for<'r> fn(&'r mut [u8; 1024])) -> [u8; 1024] { + debug init => _1; // in scope 0 at $DIR/nrvo-simple.rs:+0:9: +0:13 +- let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo-simple.rs:+0:39: +0:49 ++ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16 + let mut _2: [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16 + let _3: (); // in scope 0 at $DIR/nrvo-simple.rs:+2:5: +2:19 + let mut _4: for<'r> fn(&'r mut [u8; 1024]); // in scope 0 at $DIR/nrvo-simple.rs:+2:5: +2:9 + let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+2:10: +2:18 + let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+2:10: +2:18 + scope 1 { +- debug buf => _2; // in scope 1 at $DIR/nrvo-simple.rs:+1:9: +1:16 ++ debug buf => _0; // in scope 1 at $DIR/nrvo-simple.rs:+1:9: +1:16 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16 +- _2 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:+1:19: +1:28 ++ _0 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:+1:19: +1:28 + StorageLive(_3); // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:19 + StorageLive(_4); // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:9 + _4 = _1; // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:9 + StorageLive(_5); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 + StorageLive(_6); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 +- _6 = &mut _2; // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 ++ _6 = &mut _0; // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 + _5 = &mut (*_6); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18 + _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:19 + } + + bb1: { + StorageDead(_5); // scope 1 at $DIR/nrvo-simple.rs:+2:18: +2:19 + StorageDead(_4); // scope 1 at $DIR/nrvo-simple.rs:+2:18: +2:19 + StorageDead(_6); // scope 1 at $DIR/nrvo-simple.rs:+2:19: +2:20 + StorageDead(_3); // scope 1 at $DIR/nrvo-simple.rs:+2:19: +2:20 +- _0 = _2; // scope 1 at $DIR/nrvo-simple.rs:+3:5: +3:8 +- StorageDead(_2); // scope 0 at $DIR/nrvo-simple.rs:+4:1: +4:2 + return; // scope 0 at $DIR/nrvo-simple.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs new file mode 100644 index 000000000..6c2e265d5 --- /dev/null +++ b/src/test/mir-opt/packed-struct-drop-aligned.rs @@ -0,0 +1,17 @@ +// ignore-wasm32-bare compiled with panic=abort by default + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir +fn main() { + let mut x = Packed(Aligned(Droppy(0))); + x.0 = Aligned(Droppy(0)); +} + +struct Aligned(Droppy); +#[repr(packed)] +struct Packed(Aligned); + +struct Droppy(usize); +impl Drop for Droppy { + fn drop(&mut self) {} +} diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir new file mode 100644 index 000000000..c3874d3b3 --- /dev/null +++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.32bit.mir @@ -0,0 +1,55 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11 + let mut _1: Packed; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 + let mut _2: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 + let mut _3: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 + let mut _4: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 + let mut _5: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 + let mut _6: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + scope 1 { + debug x => _1; // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 + StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 + _3 = Droppy(const 0_usize); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 + _2 = Aligned(move _3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 + StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:41: +1:42 + _1 = Packed(move _2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43 + StorageDead(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:42: +1:43 + StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 + StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 + _5 = Droppy(const 0_usize); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 + _4 = Aligned(move _5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 + StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29 + StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 + return; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:2: +3:2 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:1: +3:2 + } + + bb3 (cleanup): { + (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + drop(_1) -> bb2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 + } + + bb4: { + StorageDead(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + StorageDead(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29 + _0 = const (); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +3:2 + drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 + } +} diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir new file mode 100644 index 000000000..c3874d3b3 --- /dev/null +++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.64bit.mir @@ -0,0 +1,55 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11 + let mut _1: Packed; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 + let mut _2: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 + let mut _3: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 + let mut _4: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 + let mut _5: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 + let mut _6: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + scope 1 { + debug x => _1; // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14 + StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 + StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 + _3 = Droppy(const 0_usize); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41 + _2 = Aligned(move _3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42 + StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:41: +1:42 + _1 = Packed(move _2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43 + StorageDead(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:42: +1:43 + StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 + StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 + _5 = Droppy(const 0_usize); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28 + _4 = Aligned(move _5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29 + StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29 + StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 + return; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:2: +3:2 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:1: +3:2 + } + + bb3 (cleanup): { + (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + drop(_1) -> bb2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 + } + + bb4: { + StorageDead(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8 + StorageDead(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29 + _0 = const (); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +3:2 + drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2 + } +} diff --git a/src/test/mir-opt/receiver-ptr-mutability.rs b/src/test/mir-opt/receiver-ptr-mutability.rs new file mode 100644 index 000000000..8e2ff0451 --- /dev/null +++ b/src/test/mir-opt/receiver-ptr-mutability.rs @@ -0,0 +1,20 @@ +// EMIT_MIR receiver_ptr_mutability.main.mir_map.0.mir + +#![feature(arbitrary_self_types)] + +struct Test {} + +impl Test { + fn x(self: *const Self) { + println!("x called"); + } +} + +fn main() { + let ptr: *mut Test = std::ptr::null_mut(); + ptr.x(); + + // Test autoderefs + let ptr_ref: &&&&*mut Test = &&&&ptr; + ptr_ref.x(); +} diff --git a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir b/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir new file mode 100644 index 000000000..45797ec06 --- /dev/null +++ b/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir @@ -0,0 +1,96 @@ +// MIR for `main` 0 mir_map + +| User Type Annotations +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test +| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test +| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test +| +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/receiver-ptr-mutability.rs:+0:11: +0:11 + let _1: *mut Test as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12 + let _2: (); // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 + let mut _3: *const Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 + let mut _4: *mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8 + let _6: &&&&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41 + let _7: &&&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41 + let _8: &&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41 + let _9: &*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41 + let _10: (); // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + let mut _11: *const Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + let mut _12: *mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + scope 1 { + debug ptr => _1; // in scope 1 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12 + let _5: &&&&*mut Test as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16 + scope 2 { + debug ptr_ref => _5; // in scope 2 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12 + _1 = null_mut::<Test>() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:26: +1:46 + // mir::Constant + // + span: $DIR/receiver-ptr-mutability.rs:14:26: 14:44 + // + literal: Const { ty: fn() -> *mut Test {null_mut::<Test>}, val: Value(<ZST>) } + } + + bb1: { + FakeRead(ForLet(None), _1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12 + AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:14: +1:23 + StorageLive(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 + StorageLive(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 + StorageLive(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8 + _4 = _1; // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8 + _3 = move _4 as *const Test (Pointer(MutToConstPointer)); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 + StorageDead(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:7: +2:8 + _2 = Test::x(move _3) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12 + // mir::Constant + // + span: $DIR/receiver-ptr-mutability.rs:15:9: 15:10 + // + literal: Const { ty: fn(*const Test) {Test::x}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:11: +2:12 + StorageDead(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:12: +2:13 + StorageLive(_5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16 + StorageLive(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41 + StorageLive(_7); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41 + StorageLive(_8); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41 + StorageLive(_9); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41 + _9 = &_1; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41 + _8 = &_9; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41 + _7 = &_8; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41 + _6 = &_7; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41 + _5 = &(*_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41 + FakeRead(ForLet(None), _5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16 + AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:18: +5:31 + StorageDead(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:41: +5:42 + StorageLive(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + StorageLive(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + StorageLive(_12); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + _12 = (*(*(*(*_5)))); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + _11 = move _12 as *const Test (Pointer(MutToConstPointer)); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + StorageDead(_12); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:11: +6:12 + _10 = Test::x(move _11) -> [return: bb3, unwind: bb4]; // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16 + // mir::Constant + // + span: $DIR/receiver-ptr-mutability.rs:19:13: 19:14 + // + literal: Const { ty: fn(*const Test) {Test::x}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:15: +6:16 + StorageDead(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:16: +6:17 + _0 = const (); // scope 0 at $DIR/receiver-ptr-mutability.rs:+0:11: +7:2 + StorageDead(_9); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 + StorageDead(_8); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 + StorageDead(_7); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 + StorageDead(_5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2 + return; // scope 0 at $DIR/receiver-ptr-mutability.rs:+7:2: +7:2 + } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/receiver-ptr-mutability.rs:+0:1: +7:2 + } +} diff --git a/src/test/mir-opt/remove-never-const.rs b/src/test/mir-opt/remove-never-const.rs new file mode 100644 index 000000000..017746647 --- /dev/null +++ b/src/test/mir-opt/remove-never-const.rs @@ -0,0 +1,22 @@ +// This was originally a regression test for #66975 - ensure that we do not generate never typed +// consts in codegen. We also have tests for this that catches the error, see +// src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs. + +// Force generation of optimized mir for functions that do not reach codegen. +// compile-flags: --emit mir,link + +#![feature(never_type)] +#![warn(const_err)] + +struct PrintName<T>(T); + +impl<T> PrintName<T> { + const VOID: ! = panic!(); +} + +// EMIT_MIR remove_never_const.no_codegen.PreCodegen.after.mir +fn no_codegen<T>() { + let _ = PrintName::<T>::VOID; +} + +fn main() {} diff --git a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff new file mode 100644 index 000000000..243a54b6a --- /dev/null +++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff @@ -0,0 +1,76 @@ +- // MIR for `match_guard` before CleanupNonCodegenStatements ++ // MIR for `match_guard` after CleanupNonCodegenStatements + + fn match_guard(_1: Option<&&i32>, _2: bool) -> i32 { + debug x => _1; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:16: +0:17 + debug c => _2; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:34: +0:35 + let mut _0: i32; // return place in scope 0 at $DIR/remove_fake_borrows.rs:+0:46: +0:49 + let mut _3: isize; // in scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 + let mut _4: &std::option::Option<&&i32>; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + let mut _5: &&i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + let mut _6: &&&i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + let mut _7: &i32; // in scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + let mut _8: bool; // in scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + + bb0: { +- FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + _3 = discriminant(_1); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + switchInt(move _3) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 1_i32; // scope 0 at $DIR/remove_fake_borrows.rs:+3:14: +3:15 + goto -> bb7; // scope 0 at $DIR/remove_fake_borrows.rs:+3:14: +3:15 + } + + bb2: { + switchInt((*(*((_1 as Some).0: &&i32)))) -> [0_i32: bb3, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 + } + + bb3: { + goto -> bb4; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 + } + + bb4: { +- _4 = &shallow _1; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 +- _5 = &shallow (*((_1 as Some).0: &&i32)); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 +- _6 = &shallow ((_1 as Some).0: &&i32); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 +- _7 = &shallow (*(*((_1 as Some).0: &&i32))); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + StorageLive(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + _8 = _2; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + switchInt(move _8) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + } + + bb5: { + StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- FakeRead(ForMatchGuard, _6); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- FakeRead(ForMatchGuard, _7); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ nop; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + _0 = const 0_i32; // scope 0 at $DIR/remove_fake_borrows.rs:+2:25: +2:26 + goto -> bb7; // scope 0 at $DIR/remove_fake_borrows.rs:+2:25: +2:26 + } + + bb6: { + StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + goto -> bb1; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + } + + bb7: { + return; // scope 0 at $DIR/remove_fake_borrows.rs:+5:2: +5:2 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/remove_fake_borrows.rs:+0:1: +5:2 + } + } + diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs new file mode 100644 index 000000000..a980f386b --- /dev/null +++ b/src/test/mir-opt/remove_fake_borrows.rs @@ -0,0 +1,15 @@ +// Test that the fake borrows for matches are removed after borrow checking. + +// ignore-wasm32-bare compiled with panic=abort by default + +// EMIT_MIR remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff +fn match_guard(x: Option<&&i32>, c: bool) -> i32 { + match x { + Some(0) if c => 0, + _ => 1, + } +} + +fn main() { + match_guard(None, true); +} diff --git a/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir new file mode 100644 index 000000000..76bdd23be --- /dev/null +++ b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir @@ -0,0 +1,11 @@ +// MIR for `no_codegen` after PreCodegen + +fn no_codegen() -> () { + let mut _0: (); // return place in scope 0 at $DIR/remove-never-const.rs:+0:20: +0:20 + scope 1 { + } + + bb0: { + unreachable; // scope 0 at $DIR/remove-never-const.rs:+1:13: +1:33 + } +} diff --git a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff new file mode 100644 index 000000000..750aaa88b --- /dev/null +++ b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff @@ -0,0 +1,100 @@ +- // MIR for `main` before RemoveStorageMarkers ++ // MIR for `main` after RemoveStorageMarkers + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/remove_storage_markers.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/remove_storage_markers.rs:+1:9: +1:16 + let mut _2: std::ops::Range<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _3: std::ops::Range<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _5: (); // in scope 0 at $DIR/remove_storage_markers.rs:+0:1: +5:2 + let _6: (); // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _7: std::option::Option<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _8: &mut std::ops::Range<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _9: &mut std::ops::Range<i32>; // in scope 0 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let mut _10: isize; // in scope 0 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + let mut _11: !; // in scope 0 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + let mut _13: i32; // in scope 0 at $DIR/remove_storage_markers.rs:+3:16: +3:17 + scope 1 { + debug sum => _1; // in scope 1 at $DIR/remove_storage_markers.rs:+1:9: +1:16 + let mut _4: std::ops::Range<i32>; // in scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + scope 2 { + debug iter => _4; // in scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + let _12: i32; // in scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10 + scope 3 { + debug i => _12; // in scope 3 at $DIR/remove_storage_markers.rs:+2:9: +2:10 + } + scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<i32>>::next) { // at $DIR/remove_storage_markers.rs:8:14: 8:19 + debug self => _8; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + let mut _14: &mut std::ops::Range<i32>; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + } + scope 4 (inlined <std::ops::Range<i32> as IntoIterator>::into_iter) { // at $DIR/remove_storage_markers.rs:8:14: 8:19 + debug self => _3; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/remove_storage_markers.rs:+1:9: +1:16 + _1 = const 0_i32; // scope 0 at $DIR/remove_storage_markers.rs:+1:19: +1:20 +- StorageLive(_2); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + Deinit(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + (_3.0: i32) = const 0_i32; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + (_3.1: i32) = const 10_i32; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _2 = move _3; // scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL +- StorageDead(_3); // scope 1 at $DIR/remove_storage_markers.rs:+2:18: +2:19 +- StorageLive(_4); // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _4 = move _2; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + goto -> bb1; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + } + + bb1: { +- StorageLive(_6); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _9 = &mut _4; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + _8 = &mut (*_9); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 +- StorageLive(_14); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _14 = &mut (*_8); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + _7 = <std::ops::Range<i32> as iter::range::RangeIteratorImpl>::spec_next(move _14) -> bb4; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: for<'r> fn(&'r mut std::ops::Range<i32>) -> Option<<std::ops::Range<i32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<i32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) } + } + + bb2: { +- StorageLive(_12); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10 + _12 = ((_7 as Some).0: i32); // scope 2 at $DIR/remove_storage_markers.rs:+2:9: +2:10 +- StorageLive(_13); // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17 + _13 = _12; // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17 + _1 = Add(_1, move _13); // scope 3 at $DIR/remove_storage_markers.rs:+3:9: +3:17 +- StorageDead(_13); // scope 3 at $DIR/remove_storage_markers.rs:+3:16: +3:17 + _6 = const (); // scope 3 at $DIR/remove_storage_markers.rs:+2:20: +4:6 +- StorageDead(_12); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_9); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_6); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 + _5 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + goto -> bb1; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + } + + bb3: { + _0 = const (); // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 +- StorageDead(_9); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_7); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_6); // scope 2 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_4); // scope 1 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_2); // scope 1 at $DIR/remove_storage_markers.rs:+4:5: +4:6 +- StorageDead(_1); // scope 0 at $DIR/remove_storage_markers.rs:+5:1: +5:2 + return; // scope 0 at $DIR/remove_storage_markers.rs:+5:2: +5:2 + } + + bb4: { +- StorageDead(_14); // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL +- StorageDead(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:18: +2:19 + _10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + switchInt(move _10) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + } + } + diff --git a/src/test/mir-opt/remove_storage_markers.rs b/src/test/mir-opt/remove_storage_markers.rs new file mode 100644 index 000000000..c144d3ff7 --- /dev/null +++ b/src/test/mir-opt/remove_storage_markers.rs @@ -0,0 +1,11 @@ +// Checks that storage markers are removed at opt-level=0. +// +// compile-flags: -C opt-level=0 -Coverflow-checks=off + +// EMIT_MIR remove_storage_markers.main.RemoveStorageMarkers.diff +fn main() { + let mut sum = 0; + for i in 0..10 { + sum += i; + } +} diff --git a/src/test/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff new file mode 100644 index 000000000..07e4dd418 --- /dev/null +++ b/src/test/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff @@ -0,0 +1,31 @@ +- // MIR for `cannot_opt_generic` before RemoveUnneededDrops ++ // MIR for `cannot_opt_generic` after RemoveUnneededDrops + + fn cannot_opt_generic(_1: T) -> () { + debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:26: +0:27 + let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:32: +0:32 + let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + let mut _3: T; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + scope 1 (inlined std::mem::drop::<T>) { // at $DIR/remove_unneeded_drops.rs:21:5: 21:12 + debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + _3 = move _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + drop(_3) -> [return: bb2, unwind: bb1]; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:1: +2:2 + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12 + StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13 + nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:32: +2:2 + return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff new file mode 100644 index 000000000..e809ca4e9 --- /dev/null +++ b/src/test/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff @@ -0,0 +1,31 @@ +- // MIR for `dont_opt` before RemoveUnneededDrops ++ // MIR for `dont_opt` after RemoveUnneededDrops + + fn dont_opt(_1: Vec<bool>) -> () { + debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:13: +0:14 + let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:27: +0:27 + let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + let mut _3: std::vec::Vec<bool>; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + scope 1 (inlined std::mem::drop::<Vec<bool>>) { // at $DIR/remove_unneeded_drops.rs:9:5: 9:12 + debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + _3 = move _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + drop(_3) -> [return: bb2, unwind: bb1]; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:1: +2:2 + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12 + StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13 + nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:27: +2:2 + return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff new file mode 100644 index 000000000..087f76dbd --- /dev/null +++ b/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff @@ -0,0 +1,27 @@ +- // MIR for `opt` before RemoveUnneededDrops ++ // MIR for `opt` after RemoveUnneededDrops + + fn opt(_1: bool) -> () { + debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:8: +0:9 + let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:17: +0:17 + let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + let mut _3: bool; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + scope 1 (inlined std::mem::drop::<bool>) { // at $DIR/remove_unneeded_drops.rs:4:5: 4:12 + debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + _3 = _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 +- drop(_3) -> bb1; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL +- } +- +- bb1: { + StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12 + StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13 +- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:17: +2:2 + return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff new file mode 100644 index 000000000..933d6895f --- /dev/null +++ b/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff @@ -0,0 +1,27 @@ +- // MIR for `opt_generic_copy` before RemoveUnneededDrops ++ // MIR for `opt_generic_copy` after RemoveUnneededDrops + + fn opt_generic_copy(_1: T) -> () { + debug x => _1; // in scope 0 at $DIR/remove_unneeded_drops.rs:+0:30: +0:31 + let mut _0: (); // return place in scope 0 at $DIR/remove_unneeded_drops.rs:+0:36: +0:36 + let _2: (); // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + let mut _3: T; // in scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + scope 1 (inlined std::mem::drop::<T>) { // at $DIR/remove_unneeded_drops.rs:14:5: 14:12 + debug _x => _3; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:5: +1:12 + StorageLive(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 + _3 = _1; // scope 0 at $DIR/remove_unneeded_drops.rs:+1:10: +1:11 +- drop(_3) -> bb1; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL +- } +- +- bb1: { + StorageDead(_3); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:11: +1:12 + StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:+1:12: +1:13 +- nop; // scope 0 at $DIR/remove_unneeded_drops.rs:+0:36: +2:2 + return; // scope 0 at $DIR/remove_unneeded_drops.rs:+2:2: +2:2 + } + } + diff --git a/src/test/mir-opt/remove_unneeded_drops.rs b/src/test/mir-opt/remove_unneeded_drops.rs new file mode 100644 index 000000000..1052f2886 --- /dev/null +++ b/src/test/mir-opt/remove_unneeded_drops.rs @@ -0,0 +1,29 @@ +// ignore-wasm32-bare compiled with panic=abort by default +// EMIT_MIR remove_unneeded_drops.opt.RemoveUnneededDrops.diff +fn opt(x: bool) { + drop(x); +} + +// EMIT_MIR remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff +fn dont_opt(x: Vec<bool>) { + drop(x); +} + +// EMIT_MIR remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff +fn opt_generic_copy<T: Copy>(x: T) { + drop(x); +} + +// EMIT_MIR remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff +// since the pass is not running on monomorphisized code, +// we can't (but probably should) optimize this +fn cannot_opt_generic<T>(x: T) { + drop(x); +} + +fn main() { + opt(true); + opt_generic_copy(42); + cannot_opt_generic(42); + dont_opt(vec![true]); +} diff --git a/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir b/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir new file mode 100644 index 000000000..7d9e60462 --- /dev/null +++ b/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir @@ -0,0 +1,15 @@ +// MIR for `get_union` after RemoveZsts + +fn get_union() -> Foo { + let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+0:19: +0:22 + let mut _1: (); // in scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16 + nop; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16 + Deinit(_0); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:5: +1:18 + (_0.0: ()) = move _1; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:5: +1:18 + StorageDead(_1); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:17: +1:18 + return; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/remove_zsts_dont_touch_unions.rs b/src/test/mir-opt/remove_zsts_dont_touch_unions.rs new file mode 100644 index 000000000..7a6f86b80 --- /dev/null +++ b/src/test/mir-opt/remove_zsts_dont_touch_unions.rs @@ -0,0 +1,19 @@ +// compile-flags: -Zmir-opt-level=3 + +// Ensure RemoveZsts doesn't remove ZST assignments to union fields, +// which causes problems in Miri. + +union Foo { + x: (), + y: u64, +} + +// EMIT_MIR remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir +fn get_union() -> Foo { + Foo { x: () } +} + + +fn main() { + get_union(); +} diff --git a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..451d0fe4c --- /dev/null +++ b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,198 @@ +// MIR for `array_casts` after SimplifyCfg-elaborate-drops + +fn array_casts() -> () { + let mut _0: (); // return place in scope 0 at $DIR/retag.rs:+0:18: +0:18 + let mut _1: [usize; 2]; // in scope 0 at $DIR/retag.rs:+1:9: +1:14 + let mut _3: *mut [usize; 2]; // in scope 0 at $DIR/retag.rs:+2:13: +2:19 + let mut _4: &mut [usize; 2]; // in scope 0 at $DIR/retag.rs:+2:13: +2:19 + let _5: (); // in scope 0 at $DIR/retag.rs:+3:5: +3:30 + let mut _6: *mut usize; // in scope 0 at $DIR/retag.rs:+3:15: +3:23 + let mut _7: *mut usize; // in scope 0 at $DIR/retag.rs:+3:15: +3:16 + let mut _10: *const [usize; 2]; // in scope 0 at $DIR/retag.rs:+6:13: +6:15 + let _11: &[usize; 2]; // in scope 0 at $DIR/retag.rs:+6:13: +6:15 + let _12: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _13: (&usize, &usize); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _14: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _15: usize; // in scope 0 at $DIR/retag.rs:+7:16: +7:36 + let mut _16: *const usize; // in scope 0 at $DIR/retag.rs:+7:26: +7:34 + let mut _17: *const usize; // in scope 0 at $DIR/retag.rs:+7:26: +7:27 + let mut _18: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _19: usize; // in scope 0 at $DIR/retag.rs:+7:38: +7:39 + let mut _22: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _24: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _25: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _26: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _28: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _29: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _30: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _31: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _33: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _34: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 1 { + debug x => _1; // in scope 1 at $DIR/retag.rs:+1:9: +1:14 + let _2: *mut usize; // in scope 1 at $DIR/retag.rs:+2:9: +2:10 + scope 2 { + debug p => _2; // in scope 2 at $DIR/retag.rs:+2:9: +2:10 + let _8: [usize; 2]; // in scope 2 at $DIR/retag.rs:+5:9: +5:10 + scope 3 { + } + scope 4 { + debug x => _8; // in scope 4 at $DIR/retag.rs:+5:9: +5:10 + let _9: *const usize; // in scope 4 at $DIR/retag.rs:+6:9: +6:10 + scope 5 { + debug p => _9; // in scope 5 at $DIR/retag.rs:+6:9: +6:10 + let _20: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _35: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 6 { + } + scope 7 { + debug left_val => _20; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _21; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _27: core::panicking::AssertKind; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 8 { + debug kind => _27; // in scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/retag.rs:+1:9: +1:14 + _1 = [const 0_usize, const 0_usize]; // scope 0 at $DIR/retag.rs:+1:29: +1:35 + StorageLive(_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10 + StorageLive(_3); // scope 1 at $DIR/retag.rs:+2:13: +2:19 + StorageLive(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19 + _4 = &mut _1; // scope 1 at $DIR/retag.rs:+2:13: +2:19 + Retag(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19 + _3 = &raw mut (*_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19 + Retag([raw] _3); // scope 1 at $DIR/retag.rs:+2:13: +2:19 + _2 = move _3 as *mut usize (Pointer(ArrayToPointer)); // scope 1 at $DIR/retag.rs:+2:13: +2:33 + StorageDead(_3); // scope 1 at $DIR/retag.rs:+2:32: +2:33 + StorageDead(_4); // scope 1 at $DIR/retag.rs:+2:33: +2:34 + StorageLive(_5); // scope 2 at $DIR/retag.rs:+3:5: +3:30 + StorageLive(_6); // scope 3 at $DIR/retag.rs:+3:15: +3:23 + StorageLive(_7); // scope 3 at $DIR/retag.rs:+3:15: +3:16 + _7 = _2; // scope 3 at $DIR/retag.rs:+3:15: +3:16 + _6 = ptr::mut_ptr::<impl *mut usize>::add(move _7, const 1_usize) -> bb1; // scope 3 at $DIR/retag.rs:+3:15: +3:23 + // mir::Constant + // + span: $DIR/retag.rs:60:17: 60:20 + // + literal: Const { ty: unsafe fn(*mut usize, usize) -> *mut usize {ptr::mut_ptr::<impl *mut usize>::add}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_7); // scope 3 at $DIR/retag.rs:+3:22: +3:23 + (*_6) = const 1_usize; // scope 3 at $DIR/retag.rs:+3:14: +3:27 + StorageDead(_6); // scope 3 at $DIR/retag.rs:+3:27: +3:28 + _5 = const (); // scope 3 at $DIR/retag.rs:+3:5: +3:30 + StorageDead(_5); // scope 2 at $DIR/retag.rs:+3:29: +3:30 + StorageLive(_8); // scope 2 at $DIR/retag.rs:+5:9: +5:10 + _8 = [const 0_usize, const 1_usize]; // scope 2 at $DIR/retag.rs:+5:25: +5:31 + StorageLive(_9); // scope 4 at $DIR/retag.rs:+6:9: +6:10 + StorageLive(_10); // scope 4 at $DIR/retag.rs:+6:13: +6:15 + StorageLive(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15 + _11 = &_8; // scope 4 at $DIR/retag.rs:+6:13: +6:15 + Retag(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15 + _10 = &raw const (*_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15 + Retag([raw] _10); // scope 4 at $DIR/retag.rs:+6:13: +6:15 + _9 = move _10 as *const usize (Pointer(ArrayToPointer)); // scope 4 at $DIR/retag.rs:+6:13: +6:31 + StorageDead(_10); // scope 4 at $DIR/retag.rs:+6:30: +6:31 + StorageDead(_11); // scope 4 at $DIR/retag.rs:+6:31: +6:32 + StorageLive(_12); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_15); // scope 5 at $DIR/retag.rs:+7:16: +7:36 + StorageLive(_16); // scope 6 at $DIR/retag.rs:+7:26: +7:34 + StorageLive(_17); // scope 6 at $DIR/retag.rs:+7:26: +7:27 + _17 = _9; // scope 6 at $DIR/retag.rs:+7:26: +7:27 + _16 = ptr::const_ptr::<impl *const usize>::add(move _17, const 1_usize) -> bb2; // scope 6 at $DIR/retag.rs:+7:26: +7:34 + // mir::Constant + // + span: $DIR/retag.rs:64:28: 64:31 + // + literal: Const { ty: unsafe fn(*const usize, usize) -> *const usize {ptr::const_ptr::<impl *const usize>::add}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_17); // scope 6 at $DIR/retag.rs:+7:33: +7:34 + _15 = (*_16); // scope 6 at $DIR/retag.rs:+7:25: +7:34 + _14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _35 = const array_casts::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) } + Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _20 = (_13.0: &usize); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = (_13.1: &usize); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = (*_20); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = (*_21); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _23 = Eq(move _24, move _25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = Not(move _23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _22) -> [false: bb4, otherwise: bb3]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb3: { + StorageLive(_27); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _27 = core::panicking::AssertKind::Eq; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_28); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_29); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _29 = move _27; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _31 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _30 = &(*_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _33 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _34 = Option::<Arguments>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r usize, &'s usize, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<usize, usize>}, val: Value(<ZST>) } + } + + bb4: { + _12 = const (); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_22); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_12); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _0 = const (); // scope 0 at $DIR/retag.rs:+0:18: +8:2 + StorageDead(_9); // scope 4 at $DIR/retag.rs:+8:1: +8:2 + StorageDead(_8); // scope 2 at $DIR/retag.rs:+8:1: +8:2 + StorageDead(_2); // scope 1 at $DIR/retag.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/retag.rs:+8:1: +8:2 + return; // scope 0 at $DIR/retag.rs:+8:2: +8:2 + } +} diff --git a/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir new file mode 100644 index 000000000..84f674db2 --- /dev/null +++ b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir @@ -0,0 +1,20 @@ +// MIR for `std::ptr::drop_in_place` after SimplifyCfg-make_shim + +fn std::ptr::drop_in_place(_1: *mut Test) -> () { + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _2: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + + bb0: { + Retag([raw] _1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _3 = <Test as Drop>::drop(move _2) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + // mir::Constant + // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL + // + literal: Const { ty: for<'r> fn(&'r mut Test) {<Test as Drop>::drop}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } +} diff --git a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..60c0f336e --- /dev/null +++ b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,22 @@ +// MIR for `main::{closure#0}` after SimplifyCfg-elaborate-drops + +fn main::{closure#0}(_1: &[closure@main::{closure#0}], _2: &i32) -> &i32 { + debug x => _2; // in scope 0 at $DIR/retag.rs:+0:32: +0:33 + let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:44: +0:48 + let _3: &i32; // in scope 0 at $DIR/retag.rs:+1:13: +1:15 + scope 1 { + debug _y => _3; // in scope 1 at $DIR/retag.rs:+1:13: +1:15 + } + + bb0: { + Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:31: +0:48 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:31: +0:48 + StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:13: +1:15 + _3 = _2; // scope 0 at $DIR/retag.rs:+1:18: +1:19 + Retag(_3); // scope 0 at $DIR/retag.rs:+1:18: +1:19 + _0 = _2; // scope 1 at $DIR/retag.rs:+2:9: +2:10 + Retag(_0); // scope 1 at $DIR/retag.rs:+2:9: +2:10 + StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6 + return; // scope 0 at $DIR/retag.rs:+0:48: +0:48 + } +} diff --git a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..ae6b5cfe2 --- /dev/null +++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,210 @@ +// MIR for `main` after SimplifyCfg-elaborate-drops + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/retag.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:14 + let _2: (); // in scope 0 at $DIR/retag.rs:+2:5: +8:6 + let mut _4: &Test; // in scope 0 at $DIR/retag.rs:+3:17: +3:36 + let _5: Test; // in scope 0 at $DIR/retag.rs:+3:17: +3:24 + let mut _6: &mut i32; // in scope 0 at $DIR/retag.rs:+3:29: +3:35 + let mut _7: &mut i32; // in scope 0 at $DIR/retag.rs:+3:29: +3:35 + let mut _9: &mut i32; // in scope 0 at $DIR/retag.rs:+4:19: +4:20 + let mut _12: *mut i32; // in scope 0 at $DIR/retag.rs:+7:18: +7:29 + let mut _14: [closure@main::{closure#0}]; // in scope 0 at $DIR/retag.rs:+11:31: +14:6 + let mut _16: for<'r> fn(&'r i32) -> &'r i32; // in scope 0 at $DIR/retag.rs:+15:14: +15:15 + let mut _17: &i32; // in scope 0 at $DIR/retag.rs:+15:16: +15:18 + let _18: &i32; // in scope 0 at $DIR/retag.rs:+15:16: +15:18 + let _19: &i32; // in scope 0 at $DIR/retag.rs:+18:5: +18:24 + let mut _20: &Test; // in scope 0 at $DIR/retag.rs:+18:5: +18:24 + let _21: Test; // in scope 0 at $DIR/retag.rs:+18:5: +18:12 + let mut _22: &i32; // in scope 0 at $DIR/retag.rs:+18:21: +18:23 + let _23: &i32; // in scope 0 at $DIR/retag.rs:+18:21: +18:23 + let _24: i32; // in scope 0 at $DIR/retag.rs:+18:22: +18:23 + let mut _26: *const i32; // in scope 0 at $DIR/retag.rs:+21:14: +21:28 + let _27: (); // in scope 0 at $DIR/retag.rs:+23:5: +23:18 + scope 1 { + debug x => _1; // in scope 1 at $DIR/retag.rs:+1:9: +1:14 + let _3: &mut i32; // in scope 1 at $DIR/retag.rs:+3:13: +3:14 + let _13: for<'r> fn(&'r i32) -> &'r i32; // in scope 1 at $DIR/retag.rs:+11:9: +11:10 + scope 2 { + debug v => _3; // in scope 2 at $DIR/retag.rs:+3:13: +3:14 + let _8: &mut i32; // in scope 2 at $DIR/retag.rs:+4:13: +4:14 + scope 3 { + debug w => _8; // in scope 3 at $DIR/retag.rs:+4:13: +4:14 + let _10: &mut i32; // in scope 3 at $DIR/retag.rs:+5:13: +5:14 + scope 4 { + debug w => _10; // in scope 4 at $DIR/retag.rs:+5:13: +5:14 + let _11: *mut i32; // in scope 4 at $DIR/retag.rs:+7:13: +7:15 + scope 5 { + debug _w => _11; // in scope 5 at $DIR/retag.rs:+7:13: +7:15 + } + } + } + } + scope 6 { + debug c => _13; // in scope 6 at $DIR/retag.rs:+11:9: +11:10 + let _15: &i32; // in scope 6 at $DIR/retag.rs:+15:9: +15:11 + scope 7 { + debug _w => _15; // in scope 7 at $DIR/retag.rs:+15:9: +15:11 + let _25: *const i32; // in scope 7 at $DIR/retag.rs:+21:9: +21:11 + let mut _28: &i32; // in scope 7 at $DIR/retag.rs:+18:21: +18:23 + scope 8 { + debug _w => _25; // in scope 8 at $DIR/retag.rs:+21:9: +21:11 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/retag.rs:+1:9: +1:14 + _1 = const 0_i32; // scope 0 at $DIR/retag.rs:+1:17: +1:18 + StorageLive(_2); // scope 1 at $DIR/retag.rs:+2:5: +8:6 + StorageLive(_3); // scope 1 at $DIR/retag.rs:+3:13: +3:14 + StorageLive(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36 + StorageLive(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24 + _5 = Test(const 0_i32); // scope 1 at $DIR/retag.rs:+3:17: +3:24 + _4 = &_5; // scope 1 at $DIR/retag.rs:+3:17: +3:36 + Retag(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36 + StorageLive(_6); // scope 1 at $DIR/retag.rs:+3:29: +3:35 + StorageLive(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35 + _7 = &mut _1; // scope 1 at $DIR/retag.rs:+3:29: +3:35 + Retag(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35 + _6 = &mut (*_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35 + Retag([2phase] _6); // scope 1 at $DIR/retag.rs:+3:29: +3:35 + _3 = Test::foo(move _4, move _6) -> [return: bb1, unwind: bb8]; // scope 1 at $DIR/retag.rs:+3:17: +3:36 + // mir::Constant + // + span: $DIR/retag.rs:32:25: 32:28 + // + literal: Const { ty: for<'r, 'x> fn(&'r Test, &'x mut i32) -> &'x mut i32 {Test::foo}, val: Value(<ZST>) } + } + + bb1: { + Retag(_3); // scope 1 at $DIR/retag.rs:+3:17: +3:36 + StorageDead(_6); // scope 1 at $DIR/retag.rs:+3:35: +3:36 + StorageDead(_4); // scope 1 at $DIR/retag.rs:+3:35: +3:36 + StorageDead(_7); // scope 1 at $DIR/retag.rs:+3:36: +3:37 + drop(_5) -> [return: bb2, unwind: bb9]; // scope 1 at $DIR/retag.rs:+3:36: +3:37 + } + + bb2: { + StorageDead(_5); // scope 1 at $DIR/retag.rs:+3:36: +3:37 + StorageLive(_8); // scope 2 at $DIR/retag.rs:+4:13: +4:14 + StorageLive(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20 + _9 = move _3; // scope 2 at $DIR/retag.rs:+4:19: +4:20 + Retag(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20 + _8 = &mut (*_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20 + Retag(_8); // scope 2 at $DIR/retag.rs:+4:19: +4:20 + StorageDead(_9); // scope 2 at $DIR/retag.rs:+4:22: +4:23 + StorageLive(_10); // scope 3 at $DIR/retag.rs:+5:13: +5:14 + _10 = move _8; // scope 3 at $DIR/retag.rs:+5:17: +5:18 + Retag(_10); // scope 3 at $DIR/retag.rs:+5:17: +5:18 + StorageLive(_11); // scope 4 at $DIR/retag.rs:+7:13: +7:15 + StorageLive(_12); // scope 4 at $DIR/retag.rs:+7:18: +7:29 + _12 = &raw mut (*_10); // scope 4 at $DIR/retag.rs:+7:18: +7:19 + Retag([raw] _12); // scope 4 at $DIR/retag.rs:+7:18: +7:19 + _11 = _12; // scope 4 at $DIR/retag.rs:+7:18: +7:29 + StorageDead(_12); // scope 4 at $DIR/retag.rs:+7:29: +7:30 + _2 = const (); // scope 1 at $DIR/retag.rs:+2:5: +8:6 + StorageDead(_11); // scope 4 at $DIR/retag.rs:+8:5: +8:6 + StorageDead(_10); // scope 3 at $DIR/retag.rs:+8:5: +8:6 + StorageDead(_8); // scope 2 at $DIR/retag.rs:+8:5: +8:6 + StorageDead(_3); // scope 1 at $DIR/retag.rs:+8:5: +8:6 + StorageDead(_2); // scope 1 at $DIR/retag.rs:+8:5: +8:6 + StorageLive(_13); // scope 1 at $DIR/retag.rs:+11:9: +11:10 + StorageLive(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6 + _14 = [closure@main::{closure#0}]; // scope 1 at $DIR/retag.rs:+11:31: +14:6 + // closure + // + def_id: DefId(0:14 ~ retag[4622]::main::{closure#0}) + // + substs: [ + // i8, + // for<'r> extern "rust-call" fn((&'r i32,)) -> &'r i32, + // (), + // ] + Retag(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6 + _13 = move _14 as for<'r> fn(&'r i32) -> &'r i32 (Pointer(ClosureFnPointer(Normal))); // scope 1 at $DIR/retag.rs:+11:31: +14:6 + StorageDead(_14); // scope 1 at $DIR/retag.rs:+11:47: +11:48 + StorageLive(_15); // scope 6 at $DIR/retag.rs:+15:9: +15:11 + StorageLive(_16); // scope 6 at $DIR/retag.rs:+15:14: +15:15 + _16 = _13; // scope 6 at $DIR/retag.rs:+15:14: +15:15 + StorageLive(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18 + StorageLive(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18 + _18 = &_1; // scope 6 at $DIR/retag.rs:+15:16: +15:18 + Retag(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18 + _17 = &(*_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18 + Retag(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18 + _15 = move _16(move _17) -> bb3; // scope 6 at $DIR/retag.rs:+15:14: +15:19 + } + + bb3: { + Retag(_15); // scope 6 at $DIR/retag.rs:+15:14: +15:19 + StorageDead(_17); // scope 6 at $DIR/retag.rs:+15:18: +15:19 + StorageDead(_16); // scope 6 at $DIR/retag.rs:+15:18: +15:19 + StorageDead(_18); // scope 6 at $DIR/retag.rs:+15:19: +15:20 + StorageLive(_19); // scope 7 at $DIR/retag.rs:+18:5: +18:24 + StorageLive(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24 + StorageLive(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12 + _21 = Test(const 0_i32); // scope 7 at $DIR/retag.rs:+18:5: +18:12 + _20 = &_21; // scope 7 at $DIR/retag.rs:+18:5: +18:24 + Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24 + StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _28 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:+18:21: +18:23 + // mir::Constant + // + span: $DIR/retag.rs:47:21: 47:23 + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + Retag(_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _23 = &(*_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + Retag(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _22 = &(*_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + Retag(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind: bb7]; // scope 7 at $DIR/retag.rs:+18:5: +18:24 + // mir::Constant + // + span: $DIR/retag.rs:47:13: 47:20 + // + literal: Const { ty: for<'r, 'x> fn(&'r Test, &'x i32) -> &'x i32 {Test::foo_shr}, val: Value(<ZST>) } + } + + bb4: { + Retag(_19); // scope 7 at $DIR/retag.rs:+18:5: +18:24 + StorageDead(_22); // scope 7 at $DIR/retag.rs:+18:23: +18:24 + StorageDead(_20); // scope 7 at $DIR/retag.rs:+18:23: +18:24 + StorageDead(_23); // scope 7 at $DIR/retag.rs:+18:24: +18:25 + drop(_21) -> [return: bb5, unwind: bb9]; // scope 7 at $DIR/retag.rs:+18:24: +18:25 + } + + bb5: { + StorageDead(_21); // scope 7 at $DIR/retag.rs:+18:24: +18:25 + StorageDead(_19); // scope 7 at $DIR/retag.rs:+18:24: +18:25 + StorageLive(_25); // scope 7 at $DIR/retag.rs:+21:9: +21:11 + StorageLive(_26); // scope 7 at $DIR/retag.rs:+21:14: +21:28 + _26 = &raw const (*_15); // scope 7 at $DIR/retag.rs:+21:14: +21:16 + Retag([raw] _26); // scope 7 at $DIR/retag.rs:+21:14: +21:16 + _25 = _26; // scope 7 at $DIR/retag.rs:+21:14: +21:28 + StorageDead(_26); // scope 7 at $DIR/retag.rs:+21:28: +21:29 + StorageLive(_27); // scope 8 at $DIR/retag.rs:+23:5: +23:18 + _27 = array_casts() -> bb6; // scope 8 at $DIR/retag.rs:+23:5: +23:18 + // mir::Constant + // + span: $DIR/retag.rs:52:5: 52:16 + // + literal: Const { ty: fn() {array_casts}, val: Value(<ZST>) } + } + + bb6: { + StorageDead(_27); // scope 8 at $DIR/retag.rs:+23:18: +23:19 + _0 = const (); // scope 0 at $DIR/retag.rs:+0:11: +24:2 + StorageDead(_25); // scope 7 at $DIR/retag.rs:+24:1: +24:2 + StorageDead(_15); // scope 6 at $DIR/retag.rs:+24:1: +24:2 + StorageDead(_13); // scope 1 at $DIR/retag.rs:+24:1: +24:2 + StorageDead(_1); // scope 0 at $DIR/retag.rs:+24:1: +24:2 + return; // scope 0 at $DIR/retag.rs:+24:2: +24:2 + } + + bb7 (cleanup): { + drop(_21) -> bb9; // scope 7 at $DIR/retag.rs:+18:24: +18:25 + } + + bb8 (cleanup): { + drop(_5) -> bb9; // scope 1 at $DIR/retag.rs:+3:36: +3:37 + } + + bb9 (cleanup): { + resume; // scope 0 at $DIR/retag.rs:+0:1: +24:2 + } +} diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs new file mode 100644 index 000000000..13568b822 --- /dev/null +++ b/src/test/mir-opt/retag.rs @@ -0,0 +1,65 @@ +// ignore-wasm32-bare compiled with panic=abort by default +// ignore-tidy-linelength +// compile-flags: -Z mir-emit-retag -Z mir-opt-level=0 -Z span_free_formats + +#![allow(unused)] + +struct Test(i32); + +// EMIT_MIR retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir +impl Test { + // Make sure we run the pass on a method, not just on bare functions. + fn foo<'x>(&self, x: &'x mut i32) -> &'x mut i32 { + x + } + fn foo_shr<'x>(&self, x: &'x i32) -> &'x i32 { + x + } +} + +// EMIT_MIR core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir + +impl Drop for Test { + fn drop(&mut self) {} +} + +// EMIT_MIR retag.main.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir +fn main() { + let mut x = 0; + { + let v = Test(0).foo(&mut x); // just making sure we do not panic when there is a tuple struct ctor + let w = { v }; // assignment + let w = w; // reborrow + // escape-to-raw (mut) + let _w = w as *mut _; + } + + // Also test closures + let c: fn(&i32) -> &i32 = |x: &i32| -> &i32 { + let _y = x; + x + }; + let _w = c(&x); + + // need to call `foo_shr` or it doesn't even get generated + Test(0).foo_shr(&0); + + // escape-to-raw (shr) + let _w = _w as *const _; + + array_casts(); +} + +/// Casting directly to an array should also go through `&raw` and thus add appropriate retags. +// EMIT_MIR retag.array_casts.SimplifyCfg-elaborate-drops.after.mir +fn array_casts() { + let mut x: [usize; 2] = [0, 0]; + let p = &mut x as *mut usize; + unsafe { *p.add(1) = 1; } + + let x: [usize; 2] = [0, 1]; + let p = &x as *const usize; + assert_eq!(unsafe { *p.add(1) }, 1); +} diff --git a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..e395fdb27 --- /dev/null +++ b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,20 @@ +// MIR for `<impl at $DIR/retag.rs:11:1: 11:10>::foo` after SimplifyCfg-elaborate-drops + +fn <impl at $DIR/retag.rs:11:1: 11:10>::foo(_1: &Test, _2: &mut i32) -> &mut i32 { + debug self => _1; // in scope 0 at $DIR/retag.rs:+0:16: +0:21 + debug x => _2; // in scope 0 at $DIR/retag.rs:+0:23: +0:24 + let mut _0: &mut i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:53 + let mut _3: &mut i32; // in scope 0 at $DIR/retag.rs:+1:9: +1:10 + + bb0: { + Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:5: +2:6 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:5: +2:6 + StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + _3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + Retag(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + _0 = &mut (*_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + StorageDead(_3); // scope 0 at $DIR/retag.rs:+2:5: +2:6 + return; // scope 0 at $DIR/retag.rs:+2:6: +2:6 + } +} diff --git a/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..e609166de --- /dev/null +++ b/src/test/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,15 @@ +// MIR for `<impl at $DIR/retag.rs:11:1: 11:10>::foo_shr` after SimplifyCfg-elaborate-drops + +fn <impl at $DIR/retag.rs:11:1: 11:10>::foo_shr(_1: &Test, _2: &i32) -> &i32 { + debug self => _1; // in scope 0 at $DIR/retag.rs:+0:20: +0:25 + debug x => _2; // in scope 0 at $DIR/retag.rs:+0:27: +0:28 + let mut _0: &i32; // return place in scope 0 at $DIR/retag.rs:+0:42: +0:49 + + bb0: { + Retag([fn entry] _1); // scope 0 at $DIR/retag.rs:+0:5: +2:6 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:5: +2:6 + _0 = _2; // scope 0 at $DIR/retag.rs:+1:9: +1:10 + Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10 + return; // scope 0 at $DIR/retag.rs:+2:6: +2:6 + } +} diff --git a/src/test/mir-opt/return_an_array.rs b/src/test/mir-opt/return_an_array.rs new file mode 100644 index 000000000..bea3c317c --- /dev/null +++ b/src/test/mir-opt/return_an_array.rs @@ -0,0 +1,8 @@ +// this tests move up progration, which is not yet implemented + +fn foo() -> [u8; 1024] { + let x = [0; 1024]; + return x; +} + +fn main() { } diff --git a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff new file mode 100644 index 000000000..c3e503bf2 --- /dev/null +++ b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff @@ -0,0 +1,72 @@ +- // MIR for `try_identity` before DestinationPropagation ++ // MIR for `try_identity` after DestinationPropagation + + fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> { + debug x => _1; // in scope 0 at $DIR/simplify_try.rs:6:17: 6:18 + let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:6:41: 6:57 + let _2: u32; // in scope 0 at $DIR/simplify_try.rs:7:9: 7:10 + let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15 + let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:14 + let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 + let _6: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 + let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 + let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 + let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 + let _10: u32; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15 + let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:8:8: 8:9 + scope 1 { + debug y => _2; // in scope 1 at $DIR/simplify_try.rs:7:9: 7:10 + } + scope 2 { + debug err => _6; // in scope 2 at $DIR/simplify_try.rs:7:14: 7:15 + scope 3 { + scope 7 { + debug t => _9; // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL + } + scope 8 { + debug v => _8; // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL + let mut _12: i32; // in scope 8 at $DIR/simplify_try.rs:7:14: 7:15 + } + } + } + scope 4 { + debug val => _10; // in scope 4 at $DIR/simplify_try.rs:7:13: 7:15 + scope 5 { + } + } + scope 6 { +- debug self => _4; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL ++ debug self => _0; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:7:9: 7:10 +- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:7:13: 7:15 +- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 +- _4 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 +- _3 = move _4; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL +- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 +- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 ++ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:15 ++ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 ++ _0 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 ++ nop; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL ++ nop; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 ++ _5 = discriminant(_0); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 + goto -> bb1; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 + } + + bb1: { +- _0 = move _3; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10 +- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:7:15: 7:16 ++ nop; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10 ++ nop; // scope 0 at $DIR/simplify_try.rs:7:15: 7:16 + StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:9:1: 9:2 + goto -> bb2; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2 + } + + bb2: { + return; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2 + } + } + diff --git a/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff b/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff new file mode 100644 index 000000000..3a11e45ca --- /dev/null +++ b/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff @@ -0,0 +1,145 @@ +- // MIR for `identity` before ConstProp ++ // MIR for `identity` after ConstProp + + fn identity(_1: Result<i32, i32>) -> Result<i32, i32> { + debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14 + let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53 + let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + let mut _5: isize; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + scope 1 { + debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10 + scope 2 { + scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10 + debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + scope 9 { + debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL + debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + } + } + } + } + scope 3 { + debug val => _9; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10 + scope 4 { + } + } + scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10 + debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _14: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _15: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + scope 6 { + debug v => _11; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + } + scope 7 { + debug e => _13; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + StorageLive(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _10) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb1: { + StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _9 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _2 = _9; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 + } + + bb2: { + StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageLive(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + _16 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 + } + + bb3: { + StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _15 = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + ((_14 as Err).0: i32) = move _15; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_14) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _14; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 +- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 +- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ _5 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ switchInt(const 1_isize) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + } + + bb4: { + unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { + StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + _12 = move _11; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + ((_3 as Continue).0: i32) = move _12; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 +- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 +- switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ _5 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ switchInt(const 0_isize) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + } + } + diff --git a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir new file mode 100644 index 000000000..952ef22d4 --- /dev/null +++ b/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir @@ -0,0 +1,127 @@ +// MIR for `identity` after PreCodegen + +fn identity(_1: Result<i32, i32>) -> Result<i32, i32> { + debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14 + let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53 + let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + let _5: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let mut _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + scope 1 { + debug residual => _5; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10 + scope 2 { + scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10 + debug residual => _6; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let _14: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _15: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + scope 9 { + debug e => _14; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL + debug t => _16; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + } + } + } + } + scope 3 { + debug val => _7; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10 + scope 4 { + } + } + scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10 + debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _8: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let _9: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _10: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _12: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + scope 6 { + debug v => _9; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + } + scope 7 { + debug e => _11; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + StorageLive(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _8 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _8) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb1: { + StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _11 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _13 = move _11; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + ((_12 as Err).0: i32) = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_12) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _12; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageLive(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + _5 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageLive(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + _6 = _5; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageLive(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + _14 = move ((_6 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _16 = move _14; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _15 = move _16; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + ((_0 as Err).0: i32) = move _15; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageDead(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 + } + + bb2: { + unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb3: { + StorageLive(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _9 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + _10 = move _9; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + ((_3 as Continue).0: i32) = move _10; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _7 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _2 = _7; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 + } +} diff --git a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff new file mode 100644 index 000000000..8453d5341 --- /dev/null +++ b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -0,0 +1,155 @@ +- // MIR for `identity` before SeparateConstSwitch ++ // MIR for `identity` after SeparateConstSwitch + + fn identity(_1: Result<i32, i32>) -> Result<i32, i32> { + debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14 + let mut _0: std::result::Result<i32, i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53 + let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + let mut _5: isize; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + scope 1 { + debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10 + scope 2 { + scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10 + debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + scope 9 { + debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL + debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + } + } + } + } + scope 3 { + debug val => _9; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10 + scope 4 { + } + } + scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10 + debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _14: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _15: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + scope 6 { + debug v => _11; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + } + scope 7 { + debug e => _13; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + StorageLive(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL +- switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _10) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb1: { +- StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 +- StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 +- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 +- switchInt(move _5) -> [0_isize: bb2, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 +- } +- +- bb2: { + StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _9 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _2 = _9; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 + } + +- bb3: { ++ bb2: { + StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageLive(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + _16 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 + StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 + } + +- bb4: { ++ bb3: { + StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _15 = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + ((_14 as Err).0: i32) = move _15; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_14) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>) = move _14; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL +- goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 ++ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + } + +- bb5: { ++ bb4: { + unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + +- bb6: { ++ bb5: { + StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + _12 = move _11; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + ((_3 as Continue).0: i32) = move _12; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL +- goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 ++ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + } + } + diff --git a/src/test/mir-opt/separate_const_switch.rs b/src/test/mir-opt/separate_const_switch.rs new file mode 100644 index 000000000..5d82acf4d --- /dev/null +++ b/src/test/mir-opt/separate_const_switch.rs @@ -0,0 +1,35 @@ +#![feature(control_flow_enum)] +#![feature(try_trait_v2)] + +use std::ops::ControlFlow; + +// EMIT_MIR separate_const_switch.too_complex.SeparateConstSwitch.diff +// EMIT_MIR separate_const_switch.too_complex.ConstProp.diff +// EMIT_MIR separate_const_switch.too_complex.PreCodegen.after.mir +fn too_complex(x: Result<i32, usize>) -> Option<i32> { + // The pass should break the outer match into + // two blocks that only have one parent each. + // Parents are one of the two branches of the first + // match, so a later pass can propagate constants. + match { + match x { + Ok(v) => ControlFlow::Continue(v), + Err(r) => ControlFlow::Break(r), + } + } { + ControlFlow::Continue(v) => Some(v), + ControlFlow::Break(r) => None, + } +} + +// EMIT_MIR separate_const_switch.identity.SeparateConstSwitch.diff +// EMIT_MIR separate_const_switch.identity.ConstProp.diff +// EMIT_MIR separate_const_switch.identity.PreCodegen.after.mir +fn identity(x: Result<i32, i32>) -> Result<i32, i32> { + Ok(x?) +} + +fn main() { + too_complex(Ok(0)); + identity(Ok(0)); +} diff --git a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff b/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff new file mode 100644 index 000000000..de9f45c3d --- /dev/null +++ b/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff @@ -0,0 +1,95 @@ +- // MIR for `too_complex` before ConstProp ++ // MIR for `too_complex` after ConstProp + + fn too_complex(_1: Result<i32, usize>) -> Option<i32> { + debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17 + let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53 + let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 + let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18 + let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45 + let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 + let mut _7: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:42: +8:43 + let mut _8: isize; // in scope 0 at $DIR/separate_const_switch.rs:+11:9: +11:33 + let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + let mut _10: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43 + let _11: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 + scope 1 { + debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17 + } + scope 2 { + debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18 + } + scope 3 { + debug v => _9; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32 + } + scope 4 { + debug r => _11; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 + _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 + switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 + } + + bb1: { + StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 + _6 = ((_1 as Err).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 + StorageLive(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43 + _7 = _6; // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43 + Deinit(_2); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 + ((_2 as Break).0: usize) = move _7; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 + discriminant(_2) = 1; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 + StorageDead(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44 + StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 +- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 +- switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 ++ _8 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 ++ switchInt(const 1_isize) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 + } + + bb2: { + StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 + _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 + Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46 + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 +- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 +- switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 ++ _8 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 ++ switchInt(const 0_isize) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 + } + + bb3: { + StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 + _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 + Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 + discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 + StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 + goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 + } + + bb4: { + StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 + _10 = _9; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 + Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + ((_0 as Some).0: i32) = move _10; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44 + StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 + goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 + } + + bb5: { + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2 + } + } + diff --git a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir new file mode 100644 index 000000000..1009225b7 --- /dev/null +++ b/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir @@ -0,0 +1,69 @@ +// MIR for `too_complex` after PreCodegen + +fn too_complex(_1: Result<i32, usize>) -> Option<i32> { + debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17 + let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53 + let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 + let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18 + let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45 + let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 + let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + let mut _8: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43 + let _9: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 + scope 1 { + debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17 + } + scope 2 { + debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18 + } + scope 3 { + debug v => _7; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32 + } + scope 4 { + debug r => _9; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 + _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 + switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 + } + + bb1: { + StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 + StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 + StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 + Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 + discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 + StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 + goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 + } + + bb2: { + StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 + _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 + Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46 + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 + StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + _7 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + StorageLive(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 + _8 = _7; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 + Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + ((_0 as Some).0: i32) = move _8; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + StorageDead(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44 + StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 + goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2 + } +} diff --git a/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff new file mode 100644 index 000000000..3ab1c572a --- /dev/null +++ b/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff @@ -0,0 +1,102 @@ +- // MIR for `too_complex` before SeparateConstSwitch ++ // MIR for `too_complex` after SeparateConstSwitch + + fn too_complex(_1: Result<i32, usize>) -> Option<i32> { + debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17 + let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53 + let mut _2: std::ops::ControlFlow<usize, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 + let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18 + let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45 + let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 + let mut _7: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:42: +8:43 + let mut _8: isize; // in scope 0 at $DIR/separate_const_switch.rs:+11:9: +11:33 + let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + let mut _10: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43 + let _11: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 + scope 1 { + debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17 + } + scope 2 { + debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18 + } + scope 3 { + debug v => _9; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32 + } + scope 4 { + debug r => _11; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 + _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 + switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 + } + + bb1: { + StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 + _6 = ((_1 as Err).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 + StorageLive(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43 + _7 = _6; // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43 + Deinit(_2); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 + ((_2 as Break).0: usize) = move _7; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 + discriminant(_2) = 1; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 + StorageDead(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44 + StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 +- goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 ++ _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 ++ switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 + } + + bb2: { + StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 + StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 + _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 + Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 + StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46 + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 +- goto -> bb3; // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 +- } +- +- bb3: { + _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 +- switchInt(move _8) -> [0_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 ++ switchInt(move _8) -> [0_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 + } + +- bb4: { ++ bb3: { + StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 + _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 + Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 + discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 + StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 +- goto -> bb6; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 ++ goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 + } + +- bb5: { ++ bb4: { + StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 + StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 + _10 = _9; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 + Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + ((_0 as Some).0: i32) = move _10; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 + StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44 + StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 +- goto -> bb6; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 ++ goto -> bb5; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 + } + +- bb6: { ++ bb5: { + StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2 + return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2 + } + } + diff --git a/src/test/mir-opt/simple-match.rs b/src/test/mir-opt/simple-match.rs new file mode 100644 index 000000000..44adc55b6 --- /dev/null +++ b/src/test/mir-opt/simple-match.rs @@ -0,0 +1,12 @@ +// Test that we don't generate unnecessarily large MIR for very simple matches + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR simple_match.match_bool.mir_map.0.mir +fn match_bool(x: bool) -> usize { + match x { + true => 10, + _ => 20, + } +} + +fn main() {} diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir new file mode 100644 index 000000000..3bef6aa05 --- /dev/null +++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir @@ -0,0 +1,29 @@ +// MIR for `match_bool` 0 mir_map + +fn match_bool(_1: bool) -> usize { + debug x => _1; // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16 + let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32 + + bb0: { + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12 + switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12 + } + + bb1: { + falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13 + } + + bb2: { + _0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16 + goto -> bb4; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16 + } + + bb3: { + _0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19 + goto -> bb4; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19 + } + + bb4: { + return; // scope 0 at $DIR/simple-match.rs:+5:2: +5:2 + } +} diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir new file mode 100644 index 000000000..3bef6aa05 --- /dev/null +++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir @@ -0,0 +1,29 @@ +// MIR for `match_bool` 0 mir_map + +fn match_bool(_1: bool) -> usize { + debug x => _1; // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16 + let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32 + + bb0: { + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12 + switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12 + } + + bb1: { + falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13 + } + + bb2: { + _0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16 + goto -> bb4; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16 + } + + bb3: { + _0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19 + goto -> bb4; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19 + } + + bb4: { + return; // scope 0 at $DIR/simple-match.rs:+5:2: +5:2 + } +} diff --git a/src/test/mir-opt/simplify-arm-identity.rs b/src/test/mir-opt/simplify-arm-identity.rs new file mode 100644 index 000000000..bedc86bba --- /dev/null +++ b/src/test/mir-opt/simplify-arm-identity.rs @@ -0,0 +1,23 @@ +// Checks that `SimplifyArmIdentity` is not applied if enums have incompatible layouts. +// Regression test for issue #66856. +// +// compile-flags: -Zmir-opt-level=3 +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +enum Src { + Foo(u8), + Bar, +} + +enum Dst { + Foo(u8), +} + +// EMIT_MIR simplify_arm_identity.main.SimplifyArmIdentity.diff +fn main() { + let e: Src = Src::Foo(0); + let _: Dst = match e { + Src::Foo(x) => Dst::Foo(x), + Src::Bar => Dst::Foo(0), + }; +} diff --git a/src/test/mir-opt/simplify-arm.rs b/src/test/mir-opt/simplify-arm.rs new file mode 100644 index 000000000..f7dcaa134 --- /dev/null +++ b/src/test/mir-opt/simplify-arm.rs @@ -0,0 +1,47 @@ +// compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts +// EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff +// EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff +// EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff +// EMIT_MIR simplify_arm.id_result.SimplifyBranchSame.diff +// EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff +// EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff + +fn id(o: Option<u8>) -> Option<u8> { + match o { + Some(v) => Some(v), + None => None, + } +} + +fn id_result(r: Result<u8, i32>) -> Result<u8, i32> { + match r { + Ok(x) => Ok(x), + Err(y) => Err(y), + } +} + +fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> { + r +} + +fn from_error<T, E>(e: E) -> Result<T, E> { + Err(e) +} + +// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure, +// so the relevant desugar is copied inline in order to keep the test testing the same thing. +// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR +// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not. +fn id_try(r: Result<u8, i32>) -> Result<u8, i32> { + let x = match into_result(r) { + Err(e) => return from_error(From::from(e)), + Ok(v) => v, + }; + Ok(x) +} + +fn main() { + id(None); + id_result(Ok(4)); + id_try(Ok(4)); +} diff --git a/src/test/mir-opt/simplify-locals-fixedpoint.rs b/src/test/mir-opt/simplify-locals-fixedpoint.rs new file mode 100644 index 000000000..78b1f9f55 --- /dev/null +++ b/src/test/mir-opt/simplify-locals-fixedpoint.rs @@ -0,0 +1,15 @@ +// compile-flags: -Zmir-opt-level=1 + +fn foo<T>() { + if let (Some(a), None) = (Option::<u8>::None, Option::<T>::None) { + if a > 42u8 { + + } + } +} + +fn main() { + foo::<()>(); +} + +// EMIT_MIR simplify_locals_fixedpoint.foo.SimplifyLocals.diff diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs new file mode 100644 index 000000000..179994544 --- /dev/null +++ b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs @@ -0,0 +1,17 @@ +// compile-flags: -C overflow-checks=no + +fn use_zst(_: ((), ())) {} + +struct Temp { + x: u8, +} + +fn use_u8(_: u8) {} + +// EMIT_MIR simplify_locals_removes_unused_consts.main.SimplifyLocals.diff +fn main() { + let ((), ()) = ((), ()); + use_zst(((), ())); + + use_u8((Temp { x: 40 }).x + 2); +} diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs new file mode 100644 index 000000000..84f57decc --- /dev/null +++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs @@ -0,0 +1,15 @@ +// compile-flags: -Zunsound-mir-opts + +fn map(x: Option<Box<()>>) -> Option<Box<()>> { + match x { + None => None, + Some(x) => Some(x), + } +} + +fn main() { + map(None); +} + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff diff --git a/src/test/mir-opt/simplify-locals.rs b/src/test/mir-opt/simplify-locals.rs new file mode 100644 index 000000000..f6bf396cd --- /dev/null +++ b/src/test/mir-opt/simplify-locals.rs @@ -0,0 +1,81 @@ +// unit-test: SimplifyLocals + +#![feature(box_syntax)] +#![feature(thread_local)] + +#[derive(Copy, Clone)] +enum E { + A, + B, +} + +// EMIT_MIR simplify_locals.c.SimplifyLocals.diff +fn c() { + let bytes = [0u8; 10]; + // Unused cast + let _: &[u8] = &bytes; +} + +// EMIT_MIR simplify_locals.d1.SimplifyLocals.diff +fn d1() { + // Unused set discriminant + let _ = E::A; +} + +// EMIT_MIR simplify_locals.d2.SimplifyLocals.diff +fn d2() { + // Unused set discriminant + {(10, E::A)}.1 = E::B; +} + +// EMIT_MIR simplify_locals.r.SimplifyLocals.diff +fn r() { + let mut a = 1; + // Unused references + let _ = &a; + let _ = &mut a; +} + +#[thread_local] static mut X: u32 = 0; + +// EMIT_MIR simplify_locals.t1.SimplifyLocals.diff +fn t1() { + // Unused thread local + unsafe { X }; +} + +// EMIT_MIR simplify_locals.t2.SimplifyLocals.diff +fn t2() { + // Unused thread local + unsafe { &mut X }; +} + +// EMIT_MIR simplify_locals.t3.SimplifyLocals.diff +fn t3() { + // Unused thread local + unsafe { *&mut X }; +} + +// EMIT_MIR simplify_locals.t4.SimplifyLocals.diff +fn t4() -> u32 { + // Used thread local + unsafe { X + 1 } +} + +// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals.diff +fn expose_addr(p: *const usize) { + // Used pointer to address cast. Has a side effect of exposing the provenance. + p as usize; +} + +fn main() { + c(); + d1(); + d2(); + r(); + t1(); + t2(); + t3(); + t4(); + expose_addr(&0); +} diff --git a/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff new file mode 100644 index 000000000..9c3ad4b4d --- /dev/null +++ b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff @@ -0,0 +1,46 @@ +- // MIR for `id` before SimplifyArmIdentity ++ // MIR for `id` after SimplifyArmIdentity + + fn id(_1: Option<u8>) -> Option<u8> { + debug o => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:7: +0:8 + let mut _0: std::option::Option<u8>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:25: +0:35 + let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:16 + let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15 + let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:25: +2:26 + scope 1 { + debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:14: +2:15 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12 + } + + bb1: { + Deinit(_0); // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21 + discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21 + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12 + } + + bb3: { + StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15 + _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15 + StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26 + _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26 + Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27 + ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27 + discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27 + StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:26: +2:27 + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27 + } + + bb4: { + return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff new file mode 100644 index 000000000..7b3a69936 --- /dev/null +++ b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff @@ -0,0 +1,46 @@ +- // MIR for `id` before SimplifyBranchSame ++ // MIR for `id` after SimplifyBranchSame + + fn id(_1: Option<u8>) -> Option<u8> { + debug o => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:7: +0:8 + let mut _0: std::option::Option<u8>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:25: +0:35 + let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:16 + let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15 + let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:25: +2:26 + scope 1 { + debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:14: +2:15 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12 + } + + bb1: { + Deinit(_0); // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21 + discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21 + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12 + } + + bb3: { + StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15 + _3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15 + StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26 + _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26 + Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27 + ((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27 + discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27 + StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:26: +2:27 + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27 + } + + bb4: { + return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff new file mode 100644 index 000000000..31d8453ce --- /dev/null +++ b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff @@ -0,0 +1,58 @@ +- // MIR for `id_result` before SimplifyArmIdentity ++ // MIR for `id_result` after SimplifyArmIdentity + + fn id_result(_1: Result<u8, i32>) -> Result<u8, i32> { + debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:14: +0:15 + let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:37: +0:52 + let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:14 + let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13 + let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:21: +2:22 + let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14 + let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:23: +3:24 + scope 1 { + debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:12: +2:13 + } + scope 2 { + debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:+3:13: +3:14 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12 + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14 + _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14 + StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24 + _6 = _5; // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24 + Deinit(_0); // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25 + ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25 + discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25 + StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:+3:24: +3:25 + StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25 + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12 + } + + bb3: { + StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13 + _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13 + StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22 + _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22 + Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23 + ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23 + discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23 + StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:22: +2:23 + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23 + } + + bb4: { + return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff new file mode 100644 index 000000000..3692ebf74 --- /dev/null +++ b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff @@ -0,0 +1,58 @@ +- // MIR for `id_result` before SimplifyBranchSame ++ // MIR for `id_result` after SimplifyBranchSame + + fn id_result(_1: Result<u8, i32>) -> Result<u8, i32> { + debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:14: +0:15 + let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:37: +0:52 + let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:14 + let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13 + let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:21: +2:22 + let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14 + let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:23: +3:24 + scope 1 { + debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:12: +2:13 + } + scope 2 { + debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:+3:13: +3:14 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12 + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14 + _5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14 + StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24 + _6 = _5; // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24 + Deinit(_0); // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25 + ((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25 + discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25 + StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:+3:24: +3:25 + StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25 + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12 + } + + bb3: { + StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13 + _3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13 + StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22 + _4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22 + Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23 + ((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23 + discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23 + StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:22: +2:23 + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23 + } + + bb4: { + return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff new file mode 100644 index 000000000..452cc8a9c --- /dev/null +++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff @@ -0,0 +1,89 @@ +- // MIR for `id_try` before SimplifyArmIdentity ++ // MIR for `id_try` after SimplifyArmIdentity + + fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> { + debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12 + let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49 + let _2: u8; // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10 + let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 + let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 + let mut _5: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15 + let _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 + let mut _7: !; // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51 + let mut _8: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50 + let mut _9: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49 + let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 + let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9 + scope 1 { + debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10 + } + scope 2 { + debug e => _6; // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14 + scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50 + debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51 + debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:+0:21: +0:22 + } + } + scope 3 { + debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13 + } + scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33 + debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:+0:22: +0:23 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 + StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 + _4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 + _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:+0:5: +0:6 + StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33 + _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 + switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33 + } + + bb1: { + StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 + _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 + _2 = _10; // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19 + StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19 + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7 + StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9 + _11 = _2; // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9 + Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 + ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 + discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 + StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10 + StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 + } + + bb3: { + StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 + _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 + StorageLive(_8); // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50 + StorageLive(_9); // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49 + _9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49 + _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50 + ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:+0:9: +0:10 + Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11 + discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11 + StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51 + StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51 + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7 + StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 + } + + bb4: { + return; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff new file mode 100644 index 000000000..5d7d4ba7c --- /dev/null +++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff @@ -0,0 +1,89 @@ +- // MIR for `id_try` before SimplifyBranchSame ++ // MIR for `id_try` after SimplifyBranchSame + + fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> { + debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12 + let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49 + let _2: u8; // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10 + let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 + let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 + let mut _5: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15 + let _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 + let mut _7: !; // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51 + let mut _8: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50 + let mut _9: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49 + let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 + let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9 + scope 1 { + debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10 + } + scope 2 { + debug e => _6; // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14 + scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50 + debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51 + debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:+0:21: +0:22 + } + } + scope 3 { + debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13 + } + scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33 + debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:+0:22: +0:23 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 + StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 + _4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 + _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:+0:5: +0:6 + StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33 + _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 + switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33 + } + + bb1: { + StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 + _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 + _2 = _10; // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19 + StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19 + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7 + StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9 + _11 = _2; // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9 + Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 + ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 + discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 + StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10 + StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 + } + + bb3: { + StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 + _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 + StorageLive(_8); // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50 + StorageLive(_9); // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49 + _9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49 + _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50 + ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:+0:9: +0:10 + Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11 + discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:+0:5: +0:11 + StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51 + StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51 + StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7 + StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2 + goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 + } + + bb4: { + return; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff new file mode 100644 index 000000000..118f5dd0a --- /dev/null +++ b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.32bit.diff @@ -0,0 +1,61 @@ +- // MIR for `main` before SimplifyArmIdentity ++ // MIR for `main` after SimplifyArmIdentity + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +0:11 + let _1: Src; // in scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10 + let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:+2:18: +5:6 + let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:9: +3:20 + let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:33: +3:34 + scope 1 { + debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:+1:9: +1:10 + let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19 + scope 2 { + } + scope 3 { + debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:+3:18: +3:19 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10 + Deinit(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29 + ((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29 + discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29 + StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +5:6 + _3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25 + goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +2:25 + } + + bb1: { + Deinit(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32 + ((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32 + discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32 + goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32 + } + + bb2: { + unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25 + } + + bb3: { + StorageLive(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19 + _4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19 + StorageLive(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34 + _5 = _4; // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34 + Deinit(_2); // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35 + ((_2 as Foo).0: u8) = move _5; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35 + discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35 + StorageDead(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:34: +3:35 + StorageDead(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35 + goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35 + } + + bb4: { + StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+5:6: +5:7 + nop; // scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +6:2 + StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify-arm-identity.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff new file mode 100644 index 000000000..118f5dd0a --- /dev/null +++ b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.64bit.diff @@ -0,0 +1,61 @@ +- // MIR for `main` before SimplifyArmIdentity ++ // MIR for `main` after SimplifyArmIdentity + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +0:11 + let _1: Src; // in scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10 + let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:+2:18: +5:6 + let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:9: +3:20 + let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:33: +3:34 + scope 1 { + debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:+1:9: +1:10 + let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19 + scope 2 { + } + scope 3 { + debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:+3:18: +3:19 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10 + Deinit(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29 + ((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29 + discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29 + StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +5:6 + _3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25 + goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +2:25 + } + + bb1: { + Deinit(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32 + ((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32 + discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32 + goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32 + } + + bb2: { + unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25 + } + + bb3: { + StorageLive(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19 + _4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19 + StorageLive(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34 + _5 = _4; // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34 + Deinit(_2); // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35 + ((_2 as Foo).0: u8) = move _5; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35 + discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35 + StorageDead(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:34: +3:35 + StorageDead(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35 + goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35 + } + + bb4: { + StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+5:6: +5:7 + nop; // scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +6:2 + StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify-arm-identity.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff new file mode 100644 index 000000000..e068b81bc --- /dev/null +++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff @@ -0,0 +1,52 @@ +- // MIR for `main` before SimplifyCfg-early-opt ++ // MIR for `main` after SimplifyCfg-early-opt + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_cfg.rs:+0:11: +0:11 + let mut _1: (); // in scope 0 at $DIR/simplify_cfg.rs:+0:1: +6:2 + let mut _2: bool; // in scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 + let mut _3: !; // in scope 0 at $DIR/simplify_cfg.rs:+2:18: +4:10 + + bb0: { + goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6 + } + + bb1: { +- goto -> bb2; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6 +- } +- +- bb2: { + StorageLive(_2); // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 +- _2 = bar() -> [return: bb3, unwind: bb6]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 ++ _2 = bar() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 + // mir::Constant + // + span: $DIR/simplify_cfg.rs:9:12: 9:15 + // + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) } + } + +- bb3: { +- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 ++ bb2: { ++ switchInt(move _2) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 + } + +- bb4: { ++ bb3: { + _0 = const (); // scope 0 at $DIR/simplify_cfg.rs:+3:13: +3:18 + StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10 + return; // scope 0 at $DIR/simplify_cfg.rs:+6:2: +6:2 + } + +- bb5: { ++ bb4: { + _1 = const (); // scope 0 at $DIR/simplify_cfg.rs:+4:10: +4:10 + StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10 + goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6 + } + +- bb6 (cleanup): { ++ bb5 (cleanup): { + resume; // scope 0 at $DIR/simplify_cfg.rs:+0:1: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff new file mode 100644 index 000000000..f693798eb --- /dev/null +++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff @@ -0,0 +1,71 @@ +- // MIR for `main` before SimplifyCfg-initial ++ // MIR for `main` after SimplifyCfg-initial + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_cfg.rs:+0:11: +0:11 + let mut _1: (); // in scope 0 at $DIR/simplify_cfg.rs:+0:1: +6:2 + let mut _2: bool; // in scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 + let mut _3: !; // in scope 0 at $DIR/simplify_cfg.rs:+2:18: +4:10 + + bb0: { + goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6 + } + + bb1: { +- falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6 ++ falseUnwind -> [real: bb2, cleanup: bb6]; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6 + } + + bb2: { + StorageLive(_2); // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 +- _2 = bar() -> [return: bb3, unwind: bb11]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 ++ _2 = bar() -> [return: bb3, unwind: bb6]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 + // mir::Constant + // + span: $DIR/simplify_cfg.rs:9:12: 9:15 + // + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) } + } + + bb3: { + switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 + } + + bb4: { + _0 = const (); // scope 0 at $DIR/simplify_cfg.rs:+3:13: +3:18 +- goto -> bb10; // scope 0 at $DIR/simplify_cfg.rs:+3:13: +3:18 ++ StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10 ++ return; // scope 0 at $DIR/simplify_cfg.rs:+6:2: +6:2 + } + + bb5: { +- goto -> bb8; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 +- } +- +- bb6: { +- unreachable; // scope 0 at $DIR/simplify_cfg.rs:+2:18: +4:10 +- } +- +- bb7: { +- goto -> bb9; // scope 0 at $DIR/simplify_cfg.rs:+2:9: +4:10 +- } +- +- bb8: { + _1 = const (); // scope 0 at $DIR/simplify_cfg.rs:+4:10: +4:10 +- goto -> bb9; // scope 0 at $DIR/simplify_cfg.rs:+2:9: +4:10 +- } +- +- bb9: { + StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10 + goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:+1:5: +5:6 + } + +- bb10: { +- StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:+4:9: +4:10 +- return; // scope 0 at $DIR/simplify_cfg.rs:+6:2: +6:2 +- } +- +- bb11 (cleanup): { ++ bb6 (cleanup): { + resume; // scope 0 at $DIR/simplify_cfg.rs:+0:1: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_cfg.rs b/src/test/mir-opt/simplify_cfg.rs new file mode 100644 index 000000000..cf7eac440 --- /dev/null +++ b/src/test/mir-opt/simplify_cfg.rs @@ -0,0 +1,18 @@ +// Test that the goto chain starting from bb0 is collapsed. +// compile-flags: -Cpanic=abort +// no-prefer-dynamic + +// EMIT_MIR simplify_cfg.main.SimplifyCfg-initial.diff +// EMIT_MIR simplify_cfg.main.SimplifyCfg-early-opt.diff +fn main() { + loop { + if bar() { + break; + } + } +} + +#[inline(never)] +fn bar() -> bool { + true +} diff --git a/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff b/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff new file mode 100644 index 000000000..9b1bea270 --- /dev/null +++ b/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff @@ -0,0 +1,40 @@ +- // MIR for `main` before SimplifyConstCondition-after-const-prop ++ // MIR for `main` after SimplifyConstCondition-after-const-prop + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_if.rs:+0:11: +0:11 + let mut _1: bool; // in scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 + let _2: (); // in scope 0 at $DIR/simplify_if.rs:+2:9: +2:15 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 + _1 = const false; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 +- switchInt(const false) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 ++ goto -> bb3; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 + } + + bb1: { + StorageLive(_2); // scope 0 at $DIR/simplify_if.rs:+2:9: +2:15 + _2 = noop() -> bb2; // scope 0 at $DIR/simplify_if.rs:+2:9: +2:15 + // mir::Constant + // + span: $DIR/simplify_if.rs:7:9: 7:13 + // + literal: Const { ty: fn() {noop}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_2); // scope 0 at $DIR/simplify_if.rs:+2:15: +2:16 + nop; // scope 0 at $DIR/simplify_if.rs:+1:14: +3:6 + goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6 + } + + bb3: { + nop; // scope 0 at $DIR/simplify_if.rs:+3:6: +3:6 + goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6 + } + + bb4: { + StorageDead(_1); // scope 0 at $DIR/simplify_if.rs:+3:5: +3:6 + return; // scope 0 at $DIR/simplify_if.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/simplify_if.rs b/src/test/mir-opt/simplify_if.rs new file mode 100644 index 000000000..2d093d926 --- /dev/null +++ b/src/test/mir-opt/simplify_if.rs @@ -0,0 +1,9 @@ +#[inline(never)] +fn noop() {} + +// EMIT_MIR simplify_if.main.SimplifyConstCondition-after-const-prop.diff +fn main() { + if false { + noop(); + } +} diff --git a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff new file mode 100644 index 000000000..5d7517e4e --- /dev/null +++ b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff @@ -0,0 +1,33 @@ +- // MIR for `c` before SimplifyLocals ++ // MIR for `c` after SimplifyLocals + + fn c() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:8: +0:8 + let _1: [u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14 +- let mut _2: &[u8]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26 +- let mut _3: &[u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26 +- let _4: &[u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26 + scope 1 { + debug bytes => _1; // in scope 1 at $DIR/simplify-locals.rs:+1:9: +1:14 + scope 2 { + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14 + _1 = [const 0_u8; 10]; // scope 0 at $DIR/simplify-locals.rs:+1:17: +1:26 +- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 +- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 +- StorageLive(_4); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 +- _4 = &_1; // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 +- _3 = &(*_4); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 +- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26 +- StorageDead(_3); // scope 1 at $DIR/simplify-locals.rs:+3:25: +3:26 +- StorageDead(_4); // scope 1 at $DIR/simplify-locals.rs:+3:26: +3:27 +- StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:+3:26: +3:27 + _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:8: +4:2 + StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+4:1: +4:2 + return; // scope 0 at $DIR/simplify-locals.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff new file mode 100644 index 000000000..a9ea8869a --- /dev/null +++ b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff @@ -0,0 +1,19 @@ +- // MIR for `d1` before SimplifyLocals ++ // MIR for `d1` after SimplifyLocals + + fn d1() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 +- let mut _1: E; // in scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17 +- Deinit(_1); // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17 +- discriminant(_1) = 0; // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17 +- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18 + _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff new file mode 100644 index 000000000..6a89e4584 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff @@ -0,0 +1,29 @@ +- // MIR for `d2` before SimplifyLocals ++ // MIR for `d2` after SimplifyLocals + + fn d2() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 +- let mut _1: E; // in scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26 +- let mut _2: (i32, E); // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17 +- let mut _3: E; // in scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15 + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26 +- Deinit(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26 +- discriminant(_1) = 1; // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26 +- StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17 +- StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15 +- Deinit(_3); // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15 +- discriminant(_3) = 0; // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15 +- Deinit(_2); // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16 +- (_2.0: i32) = const 10_i32; // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16 +- (_2.1: E) = move _3; // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16 +- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:15: +2:16 +- (_2.1: E) = move _1; // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:26 +- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:25: +2:26 +- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:26: +2:27 + _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff new file mode 100644 index 000000000..204a1bffc --- /dev/null +++ b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff @@ -0,0 +1,21 @@ +- // MIR for `expose_addr` before SimplifyLocals ++ // MIR for `expose_addr` after SimplifyLocals + + fn expose_addr(_1: *const usize) -> () { + debug p => _1; // in scope 0 at $DIR/simplify-locals.rs:+0:16: +0:17 + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:33: +0:33 + let _2: usize; // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15 + let mut _3: *const usize; // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15 + StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6 + _3 = _1; // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6 + _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15 + StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 + StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:15: +2:16 + _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:33: +3:2 + return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff new file mode 100644 index 000000000..329e2a65a --- /dev/null +++ b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff @@ -0,0 +1,31 @@ +- // MIR for `r` before SimplifyLocals ++ // MIR for `r` after SimplifyLocals + + fn r() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:8: +0:8 + let mut _1: i32; // in scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14 +- let mut _2: &i32; // in scope 0 at $DIR/simplify-locals.rs:+3:13: +3:15 +- let mut _3: &mut i32; // in scope 0 at $DIR/simplify-locals.rs:+4:13: +4:19 + scope 1 { + debug a => _1; // in scope 1 at $DIR/simplify-locals.rs:+1:9: +1:14 + scope 2 { + scope 3 { + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14 + _1 = const 1_i32; // scope 0 at $DIR/simplify-locals.rs:+1:17: +1:18 +- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+3:13: +3:15 +- _2 = &_1; // scope 1 at $DIR/simplify-locals.rs:+3:13: +3:15 +- StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:+3:15: +3:16 +- StorageLive(_3); // scope 2 at $DIR/simplify-locals.rs:+4:13: +4:19 +- _3 = &mut _1; // scope 2 at $DIR/simplify-locals.rs:+4:13: +4:19 +- StorageDead(_3); // scope 2 at $DIR/simplify-locals.rs:+4:19: +4:20 + _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:8: +5:2 + StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+5:1: +5:2 + return; // scope 0 at $DIR/simplify-locals.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff new file mode 100644 index 000000000..b31156ad6 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff @@ -0,0 +1,22 @@ +- // MIR for `t1` before SimplifyLocals ++ // MIR for `t1` after SimplifyLocals + + fn t1() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 +- let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 +- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17 +- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 +- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 +- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 +- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18 +- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18 + _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff new file mode 100644 index 000000000..66b6d8d64 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff @@ -0,0 +1,22 @@ +- // MIR for `t2` before SimplifyLocals ++ // MIR for `t2` after SimplifyLocals + + fn t2() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 +- let _1: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:20 +- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:19: +2:20 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:22 +- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:19: +2:20 +- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:19: +2:20 +- _1 = &mut (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:20 +- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:23 +- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:23 + _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff new file mode 100644 index 000000000..f6b6b78cd --- /dev/null +++ b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff @@ -0,0 +1,26 @@ +- // MIR for `t3` before SimplifyLocals ++ // MIR for `t3` after SimplifyLocals + + fn t3() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9 +- let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:21 +- let mut _2: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:15: +2:21 +- let mut _3: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:20: +2:21 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:23 +- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:15: +2:21 +- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:+2:20: +2:21 +- _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:20: +2:21 +- _2 = &mut (*_3); // scope 1 at $DIR/simplify-locals.rs:+2:15: +2:21 +- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:21 +- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24 +- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24 +- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24 + _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff new file mode 100644 index 000000000..1c1da29aa --- /dev/null +++ b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff @@ -0,0 +1,22 @@ +- // MIR for `t4` before SimplifyLocals ++ // MIR for `t4` after SimplifyLocals + + fn t4() -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/simplify-locals.rs:+0:12: +0:15 + let mut _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 + let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 + StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 + _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 + _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15 + _0 = Add(move _1, const 1_u32); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:19 + StorageDead(_1); // scope 1 at $DIR/simplify-locals.rs:+2:18: +2:19 + StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+3:1: +3:2 + return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff new file mode 100644 index 000000000..ac7a47ba5 --- /dev/null +++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff @@ -0,0 +1,62 @@ +- // MIR for `foo` before SimplifyLocals ++ // MIR for `foo` after SimplifyLocals + + fn foo() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+0:13: +0:13 + let mut _1: (std::option::Option<u8>, std::option::Option<T>); // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 + let mut _2: std::option::Option<u8>; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49 + let mut _3: std::option::Option<T>; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68 + let mut _4: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:22: +1:26 + let mut _5: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:13: +1:20 +- let mut _7: bool; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20 +- let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13 + scope 1 { + debug a => _6; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19 + let _6: u8; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19 + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 + StorageLive(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49 + Deinit(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49 + discriminant(_2) = 0; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49 + StorageLive(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68 + Deinit(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68 + discriminant(_3) = 0; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68 + Deinit(_1); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 + (_1.0: std::option::Option<u8>) = move _2; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 + (_1.1: std::option::Option<T>) = move _3; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69 + StorageDead(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:68: +1:69 + StorageDead(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:68: +1:69 + _5 = discriminant((_1.0: std::option::Option<u8>)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27 + switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27 + } + + bb1: { + _4 = discriminant((_1.1: std::option::Option<T>)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27 + switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27 + } + + bb2: { + StorageLive(_6); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19 + _6 = (((_1.0: std::option::Option<u8>) as Some).0: u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19 +- StorageLive(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20 +- StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13 +- _8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13 +- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20 +- StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:19: +2:20 +- StorageDead(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+4:9: +4:10 + StorageDead(_6); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+5:5: +5:6 + goto -> bb3; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:5: +5:6 + } + + bb3: { + drop(_1) -> bb4; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:1: +6:2 + } + + bb4: { + StorageDead(_1); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff new file mode 100644 index 000000000..da2f6fc44 --- /dev/null +++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff @@ -0,0 +1,71 @@ +- // MIR for `main` before SimplifyLocals ++ // MIR for `main` after SimplifyLocals + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+0:11: +0:11 +- let mut _1: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28 +- let mut _2: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23 +- let mut _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27 +- let _4: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 +- let mut _5: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 +- let mut _6: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16 +- let mut _7: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20 +- let _8: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 +- let mut _9: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34 +- let mut _10: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30 +- let mut _11: Temp; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 ++ let _1: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 ++ let mut _2: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 ++ let _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28 +- StorageLive(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23 +- StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27 +- StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28 +- StorageDead(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28 +- StorageDead(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:28: +1:29 +- StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 +- StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 +- StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16 +- StorageLive(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20 +- StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21 +- StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21 +- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 ++ StorageLive(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 ++ StorageLive(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21 ++ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22 + // mir::Constant + // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:12 + // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(<ZST>) } + } + + bb1: { +- StorageDead(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22 +- StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23 +- StorageLive(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 +- StorageLive(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34 +- StorageLive(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30 +- StorageLive(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28 +- StorageDead(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:33: +4:34 +- _8 = use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 ++ StorageDead(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22 ++ StorageDead(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23 ++ StorageLive(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 ++ _3 = use_u8(const 42_u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35 + // mir::Constant + // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:11 + // + literal: Const { ty: fn(u8) {use_u8}, val: Value(<ZST>) } + } + + bb2: { +- StorageDead(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:34: +4:35 +- StorageDead(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36 +- StorageDead(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36 ++ StorageDead(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36 + return; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff new file mode 100644 index 000000000..c6895fa41 --- /dev/null +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.32bit.diff @@ -0,0 +1,39 @@ +- // MIR for `map` before SimplifyLocals ++ // MIR for `map` after SimplifyLocals + + fn map(_1: Option<Box<()>>) -> Option<Box<()>> { + debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9 + let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46 + let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13 +- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 +- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26 +- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 +- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 +- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 + scope 1 { + debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12 + } + + bb1: { + ((_0 as Some).0: std::boxed::Box<()>) = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 + Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27 + discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27 + goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27 + } + + bb2: { + Deinit(_0); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 + discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 + goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 + } + + bb3: { + return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff new file mode 100644 index 000000000..c6895fa41 --- /dev/null +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.64bit.diff @@ -0,0 +1,39 @@ +- // MIR for `map` before SimplifyLocals ++ // MIR for `map` after SimplifyLocals + + fn map(_1: Option<Box<()>>) -> Option<Box<()>> { + debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9 + let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46 + let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13 +- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 +- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26 +- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 +- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 +- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2 + scope 1 { + debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12 + switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12 + } + + bb1: { + ((_0 as Some).0: std::boxed::Box<()>) = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15 + Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27 + discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27 + goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27 + } + + bb2: { + Deinit(_0); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 + discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 + goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21 + } + + bb3: { + return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_match.main.ConstProp.diff b/src/test/mir-opt/simplify_match.main.ConstProp.diff new file mode 100644 index 000000000..e4f9a4c12 --- /dev/null +++ b/src/test/mir-opt/simplify_match.main.ConstProp.diff @@ -0,0 +1,40 @@ +- // MIR for `main` before ConstProp ++ // MIR for `main` after ConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_match.rs:+0:11: +0:11 + let mut _1: bool; // in scope 0 at $DIR/simplify_match.rs:+1:11: +1:31 + let _2: bool; // in scope 0 at $DIR/simplify_match.rs:+1:17: +1:18 + scope 1 { + debug x => _2; // in scope 1 at $DIR/simplify_match.rs:+1:17: +1:18 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify_match.rs:+1:11: +1:31 + StorageLive(_2); // scope 0 at $DIR/simplify_match.rs:+1:17: +1:18 + _2 = const false; // scope 0 at $DIR/simplify_match.rs:+1:21: +1:26 +- _1 = _2; // scope 1 at $DIR/simplify_match.rs:+1:28: +1:29 ++ _1 = const false; // scope 1 at $DIR/simplify_match.rs:+1:28: +1:29 + StorageDead(_2); // scope 0 at $DIR/simplify_match.rs:+1:30: +1:31 +- switchInt(_1) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 ++ switchInt(const false) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 + } + + bb1: { + nop; // scope 0 at $DIR/simplify_match.rs:+3:18: +3:20 + goto -> bb3; // scope 0 at $DIR/simplify_match.rs:+3:18: +3:20 + } + + bb2: { + _0 = noop() -> bb3; // scope 0 at $DIR/simplify_match.rs:+2:17: +2:23 + // mir::Constant + // + span: $DIR/simplify_match.rs:7:17: 7:21 + // + literal: Const { ty: fn() {noop}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_1); // scope 0 at $DIR/simplify_match.rs:+5:1: +5:2 + return; // scope 0 at $DIR/simplify_match.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_match.rs b/src/test/mir-opt/simplify_match.rs new file mode 100644 index 000000000..216203f9f --- /dev/null +++ b/src/test/mir-opt/simplify_match.rs @@ -0,0 +1,10 @@ +#[inline(never)] +fn noop() {} + +// EMIT_MIR simplify_match.main.ConstProp.diff +fn main() { + match { let x = false; x } { + true => noop(), + false => {}, + } +} diff --git a/src/test/mir-opt/simplify_try.rs b/src/test/mir-opt/simplify_try.rs new file mode 100644 index 000000000..15e351e7d --- /dev/null +++ b/src/test/mir-opt/simplify_try.rs @@ -0,0 +1,30 @@ +// compile-flags: -Zunsound-mir-opts +// EMIT_MIR simplify_try.try_identity.SimplifyArmIdentity.diff +// EMIT_MIR simplify_try.try_identity.SimplifyBranchSame.after.mir +// EMIT_MIR simplify_try.try_identity.SimplifyLocals.after.mir +// EMIT_MIR simplify_try.try_identity.DestinationPropagation.diff + + +fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> { + r +} + +fn from_error<T, E>(e: E) -> Result<T, E> { + Err(e) +} + +// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure, +// so the relevant desugar is copied inline in order to keep the test testing the same thing. +// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR +// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not. +fn try_identity(x: Result<u32, i32>) -> Result<u32, i32> { + let y = match into_result(x) { + Err(e) => return from_error(From::from(e)), + Ok(v) => v, + }; + Ok(y) +} + +fn main() { + let _ = try_identity(Ok(0)); +} diff --git a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff new file mode 100644 index 000000000..d81d23c1c --- /dev/null +++ b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff @@ -0,0 +1,102 @@ +- // MIR for `try_identity` before DestinationPropagation ++ // MIR for `try_identity` after DestinationPropagation + + fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> { + debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18 + let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57 + let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 + let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 + let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15 + let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51 + let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50 + let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49 + let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 + let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9 + scope 1 { +- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 ++ debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 + } + scope 2 { + debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14 + scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50 + debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51 + debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22 + } + } + scope 3 { +- debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 ++ debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 + } + scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33 +- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23 ++ debug r => _3; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 +- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 +- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 +- _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 +- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6 +- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33 ++ nop; // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 ++ nop; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 ++ nop; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 ++ _3 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 ++ nop; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6 ++ nop; // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33 + _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33 + } + + bb1: { +- StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 +- _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 +- _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19 +- StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19 +- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 +- StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 +- _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 ++ nop; // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 ++ ((_0 as Ok).0: u32) = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 ++ nop; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19 ++ nop; // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19 ++ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 ++ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 ++ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 + Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 +- ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 ++ nop; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 +- StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10 +- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 ++ nop; // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10 ++ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 + } + + bb2: { + StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + nop; // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50 + StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 + nop; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 + nop; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50 + nop; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10 + Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11 + discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11 + StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51 + StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51 +- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 +- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 ++ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 ++ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff new file mode 100644 index 000000000..853b95cc6 --- /dev/null +++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff @@ -0,0 +1,81 @@ +- // MIR for `try_identity` before SimplifyArmIdentity ++ // MIR for `try_identity` after SimplifyArmIdentity + + fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> { + debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18 + let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57 + let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 + let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 + let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15 + let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51 + let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50 + let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49 + let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 + let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9 + scope 1 { + debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 + } + scope 2 { + debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14 + scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50 + debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51 + debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22 + } + } + scope 3 { + debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 + } + scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33 + debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 + _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 + _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6 + StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33 + _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33 + } + + bb1: { + StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 + _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 + _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19 + StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19 + StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 + StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 + _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 + Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10 + StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 + } + + bb2: { + StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50 + StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 + _9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 + _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50 + ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10 + Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11 + discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11 + StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51 + StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51 + StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 + StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir new file mode 100644 index 000000000..10799cd92 --- /dev/null +++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir @@ -0,0 +1,79 @@ +// MIR for `try_identity` after SimplifyBranchSame + +fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> { + debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18 + let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57 + let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 + let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 + let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15 + let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51 + let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50 + let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49 + let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 + let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9 + scope 1 { + debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 + } + scope 2 { + debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14 + scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50 + debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51 + debug e => _8; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22 + } + } + scope 3 { + debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 + } + scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33 + debug r => _4; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10 + StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 + _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 + _3 = move _4; // scope 4 at $DIR/simplify_try.rs:+0:5: +0:6 + StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33 + _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33 + } + + bb1: { + StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 + _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 + _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19 + StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19 + StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 + StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 + _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9 + Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10 + StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 + } + + bb2: { + StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50 + StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 + _9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 + _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50 + ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:+0:9: +0:10 + Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11 + discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11 + StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51 + StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51 + StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7 + StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 + } +} diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir new file mode 100644 index 000000000..f8c9034f7 --- /dev/null +++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir @@ -0,0 +1,54 @@ +// MIR for `try_identity` after SimplifyLocals + +fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> { + debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18 + let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57 + let mut _2: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + let mut _3: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15 + let _4: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + let mut _5: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50 + let mut _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49 + scope 1 { + debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10 + } + scope 2 { + debug e => _4; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14 + scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50 + debug t => _6; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + } + scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51 + debug e => _5; // in scope 6 at $DIR/simplify_try.rs:+0:21: +0:22 + } + } + scope 3 { + debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13 + } + scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33 + debug r => _2; // in scope 4 at $DIR/simplify_try.rs:+0:22: +0:23 + } + + bb0: { + _2 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32 + _3 = discriminant(_2); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33 + switchInt(move _3) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33 + } + + bb1: { + ((_0 as Ok).0: u32) = ((_2 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13 + Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10 + return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 + } + + bb2: { + StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14 + StorageLive(_5); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50 + StorageLive(_6); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49 + StorageDead(_6); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50 + Deinit(_0); // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11 + discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:+0:5: +0:11 + StorageDead(_5); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51 + StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51 + return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2 + } +} diff --git a/src/test/mir-opt/simplify_try_if_let.rs b/src/test/mir-opt/simplify_try_if_let.rs new file mode 100644 index 000000000..fba67de40 --- /dev/null +++ b/src/test/mir-opt/simplify_try_if_let.rs @@ -0,0 +1,43 @@ +// compile-flags: -Zmir-opt-level=1 -Zunsound-mir-opts +// ignore-test +// FIXME: the pass is unsound and causes ICEs in the MIR validator + +// EMIT_MIR simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff + +use std::ptr::NonNull; + +pub struct LinkedList { + head: Option<NonNull<Node>>, + tail: Option<NonNull<Node>>, +} + +pub struct Node { + next: Option<NonNull<Node>>, +} + +impl LinkedList { + pub fn new() -> Self { + Self { head: None, tail: None } + } + + pub fn append(&mut self, other: &mut Self) { + match self.tail { + None => {} + Some(mut tail) => { + // `as_mut` is okay here because we have exclusive access to the entirety + // of both lists. + if let Some(other_head) = other.head.take() { + unsafe { + tail.as_mut().next = Some(other_head); + } + } + } + } + } +} + +fn main() { + let mut one = LinkedList::new(); + let mut two = LinkedList::new(); + one.append(&mut two); +} diff --git a/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff new file mode 100644 index 000000000..11f6b5337 --- /dev/null +++ b/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff @@ -0,0 +1,104 @@ +- // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` before SimplifyArmIdentity ++ // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` after SimplifyArmIdentity + + fn <impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append(_1: &mut LinkedList, _2: &mut LinkedList) -> () { + debug self => _1; // in scope 0 at $DIR/simplify_try_if_let.rs:20:19: 20:28 + debug other => _2; // in scope 0 at $DIR/simplify_try_if_let.rs:20:30: 20:35 + let mut _0: (); // return place in scope 0 at $DIR/simplify_try_if_let.rs:20:48: 20:48 + let mut _3: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 + let mut _4: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 + let mut _5: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:60 + let mut _6: &mut std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:53 + let mut _7: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:26:24: 26:40 + let mut _9: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:46: 28:62 + let mut _10: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:51: 28:61 + let mut _11: &mut Node; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:38 + let mut _12: &mut std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:29 + scope 1 { + debug tail => _4; // in scope 1 at $DIR/simplify_try_if_let.rs:23:18: 23:26 + let _8: std::ptr::NonNull<Node>; // in scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 + scope 2 { +- debug other_head => _8; // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39 ++ debug other_head => ((_9 as Some).0: std::ptr::NonNull<Node>); // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39 + scope 3 { + } + } + } + + bb0: { + _3 = discriminant(((*_1).1: std::option::Option<std::ptr::NonNull<Node>>)); // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 + switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 + } + + bb1: { + StorageLive(_4); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 + _4 = ((((*_1).1: std::option::Option<std::ptr::NonNull<Node>>) as Some).0: std::ptr::NonNull<Node>); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 + StorageLive(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60 + StorageLive(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53 + _6 = &mut ((*_2).0: std::option::Option<std::ptr::NonNull<Node>>); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53 + _5 = Option::<NonNull<Node>>::take(move _6) -> bb4; // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60 + // mir::Constant + // + span: $DIR/simplify_try_if_let.rs:26:54: 26:58 + // + literal: Const { ty: for<'r> fn(&'r mut std::option::Option<std::ptr::NonNull<Node>>) -> std::option::Option<std::ptr::NonNull<Node>> {std::option::Option::<std::ptr::NonNull<Node>>::take}, val: Value(Scalar(<ZST>)) } + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify_try_if_let.rs:21:15: 21:24 + } + + bb3: { + _0 = const (); // scope 0 at $DIR/simplify_try_if_let.rs:22:21: 22:24 + goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10 + } + + bb4: { + StorageDead(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:59: 26:60 + _7 = discriminant(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40 + switchInt(move _7) -> [1_isize: bb6, otherwise: bb5]; // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40 + } + + bb5: { + _0 = const (); // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 + goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 + } + + bb6: { + StorageLive(_8); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 + _8 = ((_5 as Some).0: std::ptr::NonNull<Node>); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 + StorageLive(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 +- StorageLive(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61 +- _10 = _8; // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61 +- ((_9 as Some).0: std::ptr::NonNull<Node>) = move _10; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 +- discriminant(_9) = 1; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 +- StorageDead(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62 ++ _9 = move _5; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 + StorageLive(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38 + StorageLive(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29 + _12 = &mut _4; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29 + _11 = NonNull::<Node>::as_mut(move _12) -> bb7; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38 + // mir::Constant + // + span: $DIR/simplify_try_if_let.rs:28:30: 28:36 + // + literal: Const { ty: for<'r> unsafe fn(&'r mut std::ptr::NonNull<Node>) -> &'r mut Node {std::ptr::NonNull::<Node>::as_mut}, val: Value(Scalar(<ZST>)) } + } + + bb7: { + StorageDead(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:37: 28:38 + ((*_11).0: std::option::Option<std::ptr::NonNull<Node>>) = move _9; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:62 + StorageDead(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62 + StorageDead(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:62: 28:63 + _0 = const (); // scope 3 at $DIR/simplify_try_if_let.rs:27:21: 29:22 + StorageDead(_8); // scope 1 at $DIR/simplify_try_if_let.rs:30:17: 30:18 + goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 + } + + bb8: { + StorageDead(_5); // scope 1 at $DIR/simplify_try_if_let.rs:31:13: 31:14 + StorageDead(_4); // scope 0 at $DIR/simplify_try_if_let.rs:31:13: 31:14 + goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10 + } + + bb9: { + return; // scope 0 at $DIR/simplify_try_if_let.rs:33:6: 33:6 + } + } + diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice-drop-shim.rs new file mode 100644 index 000000000..0fd32906d --- /dev/null +++ b/src/test/mir-opt/slice-drop-shim.rs @@ -0,0 +1,7 @@ +// compile-flags: -Zmir-opt-level=0 + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir +fn main() { + let _fn = std::ptr::drop_in_place::<[String]> as unsafe fn(_); +} diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir new file mode 100644 index 000000000..b4b317e84 --- /dev/null +++ b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.32bit.mir @@ -0,0 +1,101 @@ +// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops + +fn std::ptr::drop_in_place(_1: *mut [String]) -> () { + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _4: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _8: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _14: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + + bb0: { + goto -> bb15; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb3 (cleanup): { + _5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb4 (cleanup): { + _6 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb5: { + _7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb6: { + _8 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb7: { + _4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb8: { + goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb9 (cleanup): { + _11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb10 (cleanup): { + _12 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb11: { + _13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb12: { + _14 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb13: { + _15 = &raw mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _9 = move _15 as *mut std::string::String (Misc); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _10 = Offset(_9, move _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + goto -> bb12; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb14: { + goto -> bb13; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb15: { + _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _3 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } +} diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir new file mode 100644 index 000000000..b4b317e84 --- /dev/null +++ b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.64bit.mir @@ -0,0 +1,101 @@ +// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops + +fn std::ptr::drop_in_place(_1: *mut [String]) -> () { + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _4: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _8: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _14: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + + bb0: { + goto -> bb15; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb3 (cleanup): { + _5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb4 (cleanup): { + _6 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb5: { + _7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb6: { + _8 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb7: { + _4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb8: { + goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb9 (cleanup): { + _11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb10 (cleanup): { + _12 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb11: { + _13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb12: { + _14 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb13: { + _15 = &raw mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _9 = move _15 as *mut std::string::String (Misc); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _10 = Offset(_9, move _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + goto -> bb12; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb14: { + goto -> bb13; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb15: { + _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _3 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } +} diff --git a/src/test/mir-opt/spanview-block.rs b/src/test/mir-opt/spanview-block.rs new file mode 100644 index 000000000..fc1d6e0ed --- /dev/null +++ b/src/test/mir-opt/spanview-block.rs @@ -0,0 +1,5 @@ +// Test spanview block output +// compile-flags: -Z dump-mir-spanview=block + +// EMIT_MIR spanview_block.main.mir_map.0.html +fn main() {} diff --git a/src/test/mir-opt/spanview-statement.rs b/src/test/mir-opt/spanview-statement.rs new file mode 100644 index 000000000..a43ad5e71 --- /dev/null +++ b/src/test/mir-opt/spanview-statement.rs @@ -0,0 +1,5 @@ +// Test spanview output (the default value for `-Z dump-mir-spanview` is "statement") +// compile-flags: -Z dump-mir-spanview + +// EMIT_MIR spanview_statement.main.mir_map.0.html +fn main() {} diff --git a/src/test/mir-opt/spanview-terminator.rs b/src/test/mir-opt/spanview-terminator.rs new file mode 100644 index 000000000..92e1411ea --- /dev/null +++ b/src/test/mir-opt/spanview-terminator.rs @@ -0,0 +1,5 @@ +// Test spanview terminator output +// compile-flags: -Z dump-mir-spanview=terminator + +// EMIT_MIR spanview_terminator.main.mir_map.0.html +fn main() {} diff --git a/src/test/mir-opt/spanview_block.main.mir_map.0.html b/src/test/mir-opt/spanview_block.main.mir_map.0.html new file mode 100644 index 000000000..8e5268043 --- /dev/null +++ b/src/test/mir-opt/spanview_block.main.mir_map.0.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html> +<head> +<title>spanview_block.main.mir_map.0</title> +<style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } +</style> +</head> +<body> +<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0: $DIR/spanview-block.rs:5:11: 5:13: + 5:11-5:13: Assign: _0 = const () + 5:13-5:13: Return: return"><span class="annotation">0⦊</span>{}<span class="annotation">⦉0</span></span></span></span></div> +</body> +</html> diff --git a/src/test/mir-opt/spanview_statement.main.mir_map.0.html b/src/test/mir-opt/spanview_statement.main.mir_map.0.html new file mode 100644 index 000000000..abbff2270 --- /dev/null +++ b/src/test/mir-opt/spanview_statement.main.mir_map.0.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html> +<head> +<title>spanview_statement.main.mir_map.0</title> +<style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } +</style> +</head> +<body> +<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0[0]: $DIR/spanview-statement.rs:5:11: 5:13: + 5:11-5:13: Assign: _0 = const ()"><span class="annotation">0[0]⦊</span>{}<span class="annotation">⦉0[0]</span></span></span><span><span class="code odd" style="--layer: 1" title="0:Return: $DIR/spanview-statement.rs:5:13: 5:13: + 5:13-5:13: Return: return"><span class="annotation">0:Return⦊</span>‸<span class="annotation">⦉0:Return</span></span></span></span></div> +</body> +</html> diff --git a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html new file mode 100644 index 000000000..55fafd90b --- /dev/null +++ b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<html> +<head> +<title>spanview_terminator.main.mir_map.0</title> +<style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } +</style> +</head> +<body> +<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() {}</span><span><span class="code even" style="--layer: 1" title="0:Return: $DIR/spanview-terminator.rs:5:13: 5:13: + 5:13-5:13: Return: return"><span class="annotation">0:Return⦊</span>‸<span class="annotation">⦉0:Return</span></span></span></span></div> +</body> +</html> diff --git a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir new file mode 100644 index 000000000..bc9e91420 --- /dev/null +++ b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir @@ -0,0 +1,203 @@ +// MIR for `XXX` 0 mir_map + +static XXX: &Foo = { + let mut _0: &Foo; // return place in scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:13: +0:25 + let _1: &Foo; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2 + let _2: Foo; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:29: +18:2 + let mut _3: &[(u32, u32)]; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + let mut _4: &[(u32, u32); 42]; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + let _5: &[(u32, u32); 42]; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + let _6: [(u32, u32); 42]; // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:12: +17:6 + let mut _7: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:9: +3:15 + let mut _8: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:17: +3:23 + let mut _9: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:25: +3:31 + let mut _10: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:9: +4:15 + let mut _11: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:17: +4:23 + let mut _12: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:25: +4:31 + let mut _13: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:9: +5:15 + let mut _14: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:17: +5:23 + let mut _15: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:25: +5:31 + let mut _16: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:9: +6:15 + let mut _17: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:17: +6:23 + let mut _18: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:25: +6:31 + let mut _19: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:9: +7:15 + let mut _20: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:17: +7:23 + let mut _21: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:25: +7:31 + let mut _22: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:9: +8:15 + let mut _23: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:17: +8:23 + let mut _24: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:25: +8:31 + let mut _25: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:9: +9:15 + let mut _26: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:17: +9:23 + let mut _27: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:25: +9:31 + let mut _28: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:9: +10:15 + let mut _29: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:17: +10:23 + let mut _30: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:25: +10:31 + let mut _31: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:9: +11:15 + let mut _32: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:17: +11:23 + let mut _33: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:25: +11:31 + let mut _34: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:9: +12:15 + let mut _35: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:17: +12:23 + let mut _36: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:25: +12:31 + let mut _37: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:9: +13:15 + let mut _38: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:17: +13:23 + let mut _39: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:25: +13:31 + let mut _40: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:9: +14:15 + let mut _41: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:17: +14:23 + let mut _42: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:25: +14:31 + let mut _43: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:9: +15:15 + let mut _44: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:17: +15:23 + let mut _45: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:25: +15:31 + let mut _46: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:9: +16:15 + let mut _47: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:17: +16:23 + let mut _48: (u32, u32); // in scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:25: +16:31 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2 + StorageLive(_2); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:29: +18:2 + StorageLive(_3); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + StorageLive(_4); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + StorageLive(_5); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + StorageLive(_6); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:12: +17:6 + StorageLive(_7); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:9: +3:15 + _7 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:9: +3:15 + StorageLive(_8); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:17: +3:23 + _8 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:17: +3:23 + StorageLive(_9); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:25: +3:31 + _9 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+3:25: +3:31 + StorageLive(_10); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:9: +4:15 + _10 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:9: +4:15 + StorageLive(_11); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:17: +4:23 + _11 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:17: +4:23 + StorageLive(_12); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:25: +4:31 + _12 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+4:25: +4:31 + StorageLive(_13); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:9: +5:15 + _13 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:9: +5:15 + StorageLive(_14); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:17: +5:23 + _14 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:17: +5:23 + StorageLive(_15); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:25: +5:31 + _15 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+5:25: +5:31 + StorageLive(_16); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:9: +6:15 + _16 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:9: +6:15 + StorageLive(_17); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:17: +6:23 + _17 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:17: +6:23 + StorageLive(_18); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:25: +6:31 + _18 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+6:25: +6:31 + StorageLive(_19); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:9: +7:15 + _19 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:9: +7:15 + StorageLive(_20); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:17: +7:23 + _20 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:17: +7:23 + StorageLive(_21); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:25: +7:31 + _21 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+7:25: +7:31 + StorageLive(_22); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:9: +8:15 + _22 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:9: +8:15 + StorageLive(_23); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:17: +8:23 + _23 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:17: +8:23 + StorageLive(_24); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:25: +8:31 + _24 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+8:25: +8:31 + StorageLive(_25); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:9: +9:15 + _25 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:9: +9:15 + StorageLive(_26); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:17: +9:23 + _26 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:17: +9:23 + StorageLive(_27); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:25: +9:31 + _27 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+9:25: +9:31 + StorageLive(_28); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:9: +10:15 + _28 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:9: +10:15 + StorageLive(_29); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:17: +10:23 + _29 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:17: +10:23 + StorageLive(_30); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:25: +10:31 + _30 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+10:25: +10:31 + StorageLive(_31); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:9: +11:15 + _31 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:9: +11:15 + StorageLive(_32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:17: +11:23 + _32 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:17: +11:23 + StorageLive(_33); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:25: +11:31 + _33 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+11:25: +11:31 + StorageLive(_34); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:9: +12:15 + _34 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:9: +12:15 + StorageLive(_35); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:17: +12:23 + _35 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:17: +12:23 + StorageLive(_36); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:25: +12:31 + _36 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+12:25: +12:31 + StorageLive(_37); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:9: +13:15 + _37 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:9: +13:15 + StorageLive(_38); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:17: +13:23 + _38 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:17: +13:23 + StorageLive(_39); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:25: +13:31 + _39 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+13:25: +13:31 + StorageLive(_40); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:9: +14:15 + _40 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:9: +14:15 + StorageLive(_41); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:17: +14:23 + _41 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:17: +14:23 + StorageLive(_42); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:25: +14:31 + _42 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+14:25: +14:31 + StorageLive(_43); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:9: +15:15 + _43 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:9: +15:15 + StorageLive(_44); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:17: +15:23 + _44 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:17: +15:23 + StorageLive(_45); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:25: +15:31 + _45 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+15:25: +15:31 + StorageLive(_46); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:9: +16:15 + _46 = (const 0_u32, const 1_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:9: +16:15 + StorageLive(_47); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:17: +16:23 + _47 = (const 0_u32, const 2_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:17: +16:23 + StorageLive(_48); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:25: +16:31 + _48 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+16:25: +16:31 + _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48]; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:12: +17:6 + StorageDead(_48); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_47); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_46); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_45); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_44); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_43); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_42); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_41); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_40); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_39); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_38); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_37); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_36); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_35); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_34); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_33); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_31); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_30); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_29); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_28); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_27); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_26); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_25); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_24); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_23); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_22); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_21); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_20); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_19); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_18); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_17); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_16); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_15); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_14); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_13); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_12); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_11); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_10); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_9); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_8); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + StorageDead(_7); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + _5 = &_6; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + _4 = &(*_5); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + _3 = move _4 as &[(u32, u32)] (Pointer(Unsize)); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+2:11: +17:6 + StorageDead(_4); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+17:5: +17:6 + _2 = Foo { tup: const "hi", data: move _3 }; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:29: +18:2 + // mir::Constant + // + span: $DIR/storage_live_dead_in_statics.rs:6:10: 6:14 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + StorageDead(_3); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+18:1: +18:2 + _1 = &_2; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2 + _0 = &(*_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:28: +18:2 + StorageDead(_5); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+18:1: +18:2 + StorageDead(_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:+18:1: +18:2 + return; // scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:1: +0:25 + } +} diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/storage_live_dead_in_statics.rs new file mode 100644 index 000000000..b03de8612 --- /dev/null +++ b/src/test/mir-opt/storage_live_dead_in_statics.rs @@ -0,0 +1,33 @@ +// Check that when we compile the static `XXX` into MIR, we do not +// generate `StorageStart` or `StorageEnd` statements. + +// EMIT_MIR storage_live_dead_in_statics.XXX.mir_map.0.mir +static XXX: &'static Foo = &Foo { + tup: "hi", + data: &[ + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + (0, 1), (0, 2), (0, 3), + ] +}; + +#[derive(Debug)] +struct Foo { + tup: &'static str, + data: &'static [(u32, u32)] +} + +fn main() { + println!("{:?}", XXX); +} diff --git a/src/test/mir-opt/storage_ranges.main.nll.0.mir b/src/test/mir-opt/storage_ranges.main.nll.0.mir new file mode 100644 index 000000000..812eb3b82 --- /dev/null +++ b/src/test/mir-opt/storage_ranges.main.nll.0.mir @@ -0,0 +1,64 @@ +// MIR for `main` 0 nll + +| Free Region Mapping +| '_#0r | Global | ['_#0r, '_#1r] +| '_#1r | Local | ['_#1r] +| +| Inferred Region Values +| '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r} +| '_#1r | U0 | {bb0[0..=22], '_#1r} +| '_#2r | U0 | {} +| '_#3r | U0 | {bb0[10..=11]} +| '_#4r | U0 | {bb0[11]} +| +| Inference Constraints +| '_#0r live at {bb0[0..=22]} +| '_#1r live at {bb0[0..=22]} +| '_#3r live at {bb0[10]} +| '_#4r live at {bb0[11]} +| '_#3r: '_#4r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0) +| +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/storage_ranges.rs:+1:9: +1:10 + let _2: (); // in scope 0 at $DIR/storage_ranges.rs:+2:5: +4:6 + let _4: std::option::Option<i32>; // in scope 0 at $DIR/storage_ranges.rs:+3:18: +3:25 + let mut _5: i32; // in scope 0 at $DIR/storage_ranges.rs:+3:23: +3:24 + scope 1 { + debug a => _1; // in scope 1 at $DIR/storage_ranges.rs:+1:9: +1:10 + let _3: &std::option::Option<i32>; // in scope 1 at $DIR/storage_ranges.rs:+3:13: +3:14 + let _6: i32; // in scope 1 at $DIR/storage_ranges.rs:+5:9: +5:10 + scope 2 { + debug b => _3; // in scope 2 at $DIR/storage_ranges.rs:+3:13: +3:14 + } + scope 3 { + debug c => _6; // in scope 3 at $DIR/storage_ranges.rs:+5:9: +5:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/storage_ranges.rs:+1:9: +1:10 + _1 = const 0_i32; // scope 0 at $DIR/storage_ranges.rs:+1:13: +1:14 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/storage_ranges.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/storage_ranges.rs:+2:5: +4:6 + StorageLive(_3); // scope 1 at $DIR/storage_ranges.rs:+3:13: +3:14 + StorageLive(_4); // scope 1 at $DIR/storage_ranges.rs:+3:18: +3:25 + StorageLive(_5); // scope 1 at $DIR/storage_ranges.rs:+3:23: +3:24 + _5 = _1; // scope 1 at $DIR/storage_ranges.rs:+3:23: +3:24 + _4 = Option::<i32>::Some(move _5); // scope 1 at $DIR/storage_ranges.rs:+3:18: +3:25 + StorageDead(_5); // scope 1 at $DIR/storage_ranges.rs:+3:24: +3:25 + _3 = &_4; // scope 1 at $DIR/storage_ranges.rs:+3:17: +3:25 + FakeRead(ForLet(None), _3); // scope 1 at $DIR/storage_ranges.rs:+3:13: +3:14 + _2 = const (); // scope 1 at $DIR/storage_ranges.rs:+2:5: +4:6 + StorageDead(_4); // scope 1 at $DIR/storage_ranges.rs:+4:5: +4:6 + StorageDead(_3); // scope 1 at $DIR/storage_ranges.rs:+4:5: +4:6 + StorageDead(_2); // scope 1 at $DIR/storage_ranges.rs:+4:5: +4:6 + StorageLive(_6); // scope 1 at $DIR/storage_ranges.rs:+5:9: +5:10 + _6 = const 1_i32; // scope 1 at $DIR/storage_ranges.rs:+5:13: +5:14 + FakeRead(ForLet(None), _6); // scope 1 at $DIR/storage_ranges.rs:+5:9: +5:10 + _0 = const (); // scope 0 at $DIR/storage_ranges.rs:+0:11: +6:2 + StorageDead(_6); // scope 1 at $DIR/storage_ranges.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/storage_ranges.rs:+6:1: +6:2 + return; // scope 0 at $DIR/storage_ranges.rs:+6:2: +6:2 + } +} diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs new file mode 100644 index 000000000..996051a29 --- /dev/null +++ b/src/test/mir-opt/storage_ranges.rs @@ -0,0 +1,9 @@ +// EMIT_MIR storage_ranges.main.nll.0.mir + +fn main() { + let a = 0; + { + let b = &Some(a); + } + let c = 1; +} diff --git a/src/test/mir-opt/tls-access.rs b/src/test/mir-opt/tls-access.rs new file mode 100644 index 000000000..19344c868 --- /dev/null +++ b/src/test/mir-opt/tls-access.rs @@ -0,0 +1,14 @@ +// EMIT_MIR tls_access.main.PreCodegen.after.mir +// compile-flags: -Zmir-opt-level=0 + +#![feature(thread_local)] + +#[thread_local] +static mut FOO: u8 = 3; + +fn main() { + unsafe { + let a = &FOO; + FOO = 42; + } +} diff --git a/src/test/mir-opt/tls_access.main.PreCodegen.after.mir b/src/test/mir-opt/tls_access.main.PreCodegen.after.mir new file mode 100644 index 000000000..b6c36be2b --- /dev/null +++ b/src/test/mir-opt/tls_access.main.PreCodegen.after.mir @@ -0,0 +1,28 @@ +// MIR for `main` after PreCodegen + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/tls-access.rs:+0:11: +0:11 + let _2: *mut u8; // in scope 0 at $DIR/tls-access.rs:+2:18: +2:21 + let mut _3: *mut u8; // in scope 0 at $DIR/tls-access.rs:+3:9: +3:12 + scope 1 { + let _1: &u8; // in scope 1 at $DIR/tls-access.rs:+2:13: +2:14 + scope 2 { + debug a => _1; // in scope 2 at $DIR/tls-access.rs:+2:13: +2:14 + } + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/tls-access.rs:+2:13: +2:14 + StorageLive(_2); // scope 1 at $DIR/tls-access.rs:+2:18: +2:21 + _2 = &/*tls*/ mut FOO; // scope 1 at $DIR/tls-access.rs:+2:18: +2:21 + _1 = &(*_2); // scope 1 at $DIR/tls-access.rs:+2:17: +2:21 + StorageLive(_3); // scope 2 at $DIR/tls-access.rs:+3:9: +3:12 + _3 = &/*tls*/ mut FOO; // scope 2 at $DIR/tls-access.rs:+3:9: +3:12 + (*_3) = const 42_u8; // scope 2 at $DIR/tls-access.rs:+3:9: +3:17 + StorageDead(_3); // scope 2 at $DIR/tls-access.rs:+3:17: +3:18 + _0 = const (); // scope 1 at $DIR/tls-access.rs:+1:5: +4:6 + StorageDead(_2); // scope 1 at $DIR/tls-access.rs:+4:5: +4:6 + StorageDead(_1); // scope 1 at $DIR/tls-access.rs:+4:5: +4:6 + return; // scope 0 at $DIR/tls-access.rs:+5:2: +5:2 + } +} diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir new file mode 100644 index 000000000..6e9a8b4d9 --- /dev/null +++ b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir @@ -0,0 +1,111 @@ +// MIR for `move_out_by_subslice` 0 mir_map + +fn move_out_by_subslice() -> () { + let mut _0: (); // return place in scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +0:27 + let _1: [std::boxed::Box<i32>; 2]; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + let mut _2: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _3: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _4: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _5: *mut u8; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _6: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + let mut _8: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + let mut _9: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + let mut _10: *mut u8; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + let mut _11: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + scope 1 { + debug a => _1; // in scope 1 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + let _12: [std::boxed::Box<i32>; 2]; // in scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17 + scope 4 { + debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:10: +2:17 + } + } + scope 2 { + } + scope 3 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + _3 = SizeOf(i32); // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + _4 = AlignOf(i32); // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb12]; // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + // mir::Constant + // + span: $DIR/uniform_array_move_out.rs:11:14: 11:19 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_6); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + _6 = ShallowInitBox(move _5, i32); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + (*_6) = const 1_i32; // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19 + _2 = move _6; // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + drop(_6) -> [return: bb2, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19 + } + + bb2: { + StorageDead(_6); // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19 + StorageLive(_7); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + _8 = SizeOf(i32); // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + _9 = AlignOf(i32); // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb11]; // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + // mir::Constant + // + span: $DIR/uniform_array_move_out.rs:11:21: 11:26 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb3: { + StorageLive(_11); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + _11 = ShallowInitBox(move _10, i32); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + (*_11) = const 2_i32; // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26 + _7 = move _11; // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + drop(_11) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26 + } + + bb4: { + StorageDead(_11); // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26 + _1 = [move _2, move _7]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:13: +1:27 + drop(_7) -> [return: bb5, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + } + + bb5: { + StorageDead(_7); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + drop(_2) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + } + + bb6: { + StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17 + _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:17 + _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +3:2 + drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + } + + bb7: { + StorageDead(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + drop(_1) -> [return: bb8, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + } + + bb8: { + StorageDead(_1); // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + return; // scope 0 at $DIR/uniform_array_move_out.rs:+3:2: +3:2 + } + + bb9 (cleanup): { + drop(_1) -> bb12; // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + } + + bb10 (cleanup): { + drop(_7) -> bb11; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + } + + bb11 (cleanup): { + drop(_2) -> bb12; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + } + + bb12 (cleanup): { + resume; // scope 0 at $DIR/uniform_array_move_out.rs:+0:1: +3:2 + } +} diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir new file mode 100644 index 000000000..23a50b22a --- /dev/null +++ b/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir @@ -0,0 +1,111 @@ +// MIR for `move_out_from_end` 0 mir_map + +fn move_out_from_end() -> () { + let mut _0: (); // return place in scope 0 at $DIR/uniform_array_move_out.rs:+0:24: +0:24 + let _1: [std::boxed::Box<i32>; 2]; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + let mut _2: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _3: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _4: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _5: *mut u8; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _6: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + let mut _8: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + let mut _9: usize; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + let mut _10: *mut u8; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + let mut _11: std::boxed::Box<i32>; // in scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + scope 1 { + debug a => _1; // in scope 1 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + let _12: std::boxed::Box<i32>; // in scope 1 at $DIR/uniform_array_move_out.rs:+2:14: +2:16 + scope 4 { + debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:14: +2:16 + } + } + scope 2 { + } + scope 3 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + _3 = SizeOf(i32); // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + _4 = AlignOf(i32); // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb12]; // scope 2 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + // mir::Constant + // + span: $DIR/uniform_array_move_out.rs:5:14: 5:19 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_6); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + _6 = ShallowInitBox(move _5, i32); // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + (*_6) = const 1_i32; // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19 + _2 = move _6; // scope 0 at $DIR/uniform_array_move_out.rs:+1:14: +1:19 + drop(_6) -> [return: bb2, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19 + } + + bb2: { + StorageDead(_6); // scope 0 at $DIR/uniform_array_move_out.rs:+1:18: +1:19 + StorageLive(_7); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + _8 = SizeOf(i32); // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + _9 = AlignOf(i32); // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb11]; // scope 3 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + // mir::Constant + // + span: $DIR/uniform_array_move_out.rs:5:21: 5:26 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) } + } + + bb3: { + StorageLive(_11); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + _11 = ShallowInitBox(move _10, i32); // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + (*_11) = const 2_i32; // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26 + _7 = move _11; // scope 0 at $DIR/uniform_array_move_out.rs:+1:21: +1:26 + drop(_11) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26 + } + + bb4: { + StorageDead(_11); // scope 0 at $DIR/uniform_array_move_out.rs:+1:25: +1:26 + _1 = [move _2, move _7]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:13: +1:27 + drop(_7) -> [return: bb5, unwind: bb11]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + } + + bb5: { + StorageDead(_7); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + drop(_2) -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + } + + bb6: { + StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:14: +2:16 + _12 = move _1[1 of 2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:14: +2:16 + _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:24: +3:2 + drop(_12) -> [return: bb7, unwind: bb9]; // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + } + + bb7: { + StorageDead(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + drop(_1) -> [return: bb8, unwind: bb12]; // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + } + + bb8: { + StorageDead(_1); // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + return; // scope 0 at $DIR/uniform_array_move_out.rs:+3:2: +3:2 + } + + bb9 (cleanup): { + drop(_1) -> bb12; // scope 0 at $DIR/uniform_array_move_out.rs:+3:1: +3:2 + } + + bb10 (cleanup): { + drop(_7) -> bb11; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + } + + bb11 (cleanup): { + drop(_2) -> bb12; // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 + } + + bb12 (cleanup): { + resume; // scope 0 at $DIR/uniform_array_move_out.rs:+0:1: +3:2 + } +} diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs new file mode 100644 index 000000000..35e425528 --- /dev/null +++ b/src/test/mir-opt/uniform_array_move_out.rs @@ -0,0 +1,18 @@ +#![feature(box_syntax)] + +// EMIT_MIR uniform_array_move_out.move_out_from_end.mir_map.0.mir +fn move_out_from_end() { + let a = [box 1, box 2]; + let [.., _y] = a; +} + +// EMIT_MIR uniform_array_move_out.move_out_by_subslice.mir_map.0.mir +fn move_out_by_subslice() { + let a = [box 1, box 2]; + let [_y @ ..] = a; +} + +fn main() { + move_out_by_subslice(); + move_out_from_end(); +} diff --git a/src/test/mir-opt/uninhabited-enum.rs b/src/test/mir-opt/uninhabited-enum.rs new file mode 100644 index 000000000..97c6e8cd5 --- /dev/null +++ b/src/test/mir-opt/uninhabited-enum.rs @@ -0,0 +1,19 @@ +#![feature(never_type)] + +pub enum Void {} + +// EMIT_MIR uninhabited_enum.process_never.SimplifyLocals.after.mir +#[no_mangle] +pub fn process_never(input: *const !) { + let _input = unsafe { &*input }; +} + +// EMIT_MIR uninhabited_enum.process_void.SimplifyLocals.after.mir +#[no_mangle] +pub fn process_void(input: *const Void) { + let _input = unsafe { &*input }; + // In the future, this should end with `unreachable`, but we currently only do + // unreachability analysis for `!`. +} + +fn main() {} diff --git a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir new file mode 100644 index 000000000..34c38d24c --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir @@ -0,0 +1,18 @@ +// MIR for `process_never` after SimplifyLocals + +fn process_never(_1: *const !) -> () { + debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:+0:22: +0:27 + let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:+0:39: +0:39 + let _2: &!; // in scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + scope 1 { + debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + } + scope 2 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:+2:1: +2:2 + unreachable; // scope 0 at $DIR/uninhabited-enum.rs:+0:39: +2:2 + } +} diff --git a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir new file mode 100644 index 000000000..bbb81724c --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir @@ -0,0 +1,18 @@ +// MIR for `process_void` after SimplifyLocals + +fn process_void(_1: *const Void) -> () { + debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:+0:21: +0:26 + let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:+0:41: +0:41 + let _2: &Void; // in scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + scope 1 { + debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + } + scope 2 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14 + StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:+4:1: +4:2 + return; // scope 0 at $DIR/uninhabited-enum.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir new file mode 100644 index 000000000..3d860dac3 --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -0,0 +1,63 @@ +// MIR for `main` after SimplifyCfg-after-uninhabited-enum-branching + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +0:11 + let _1: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +5:6 + let mut _2: Test1; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + let mut _3: isize; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+2:9: +2:20 + let _4: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34 + let _5: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24 + let _6: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6 + let mut _7: Test2; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + let mut _8: isize; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+8:9: +8:17 + let _9: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +5:6 + StorageLive(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + _3 = discriminant(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + StorageLive(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24 + _5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:23:21: 23:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _1 = &(*_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24 + StorageDead(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24 + StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7 + StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7 + StorageLive(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6 + StorageLive(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + Deinit(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + discriminant(_7) = 0; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + _8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + switchInt(move _8) -> [4_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 + } + + bb1: { + StorageLive(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 + _9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:28:21: 28:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 + StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 + goto -> bb3; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 + } + + bb2: { + _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + goto -> bb3; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 + } + + bb3: { + StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7 + StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7 + _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2 + return; // scope 0 at $DIR/uninhabited_enum_branching.rs:+11:2: +11:2 + } +} diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff new file mode 100644 index 000000000..023f6ae32 --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff @@ -0,0 +1,93 @@ +- // MIR for `main` before UninhabitedEnumBranching ++ // MIR for `main` after UninhabitedEnumBranching + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +0:11 + let _1: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +5:6 + let mut _2: Test1; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + let mut _3: isize; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+2:9: +2:20 + let _4: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34 + let _5: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24 + let _6: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6 + let mut _7: Test2; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + let mut _8: isize; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+8:9: +8:17 + let _9: &str; // in scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +5:6 + StorageLive(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + _3 = discriminant(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 +- switchInt(move _3) -> [0_isize: bb2, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 ++ switchInt(move _3) -> bb1; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24 + _5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:23:21: 23:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _1 = &(*_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:21: +4:24 + StorageDead(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24 + goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24 + } + + bb2: { + _1 = const "A(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:21:24: 21:34 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34 + } + + bb3: { + StorageLive(_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34 + _4 = const "B(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:22:24: 22:34 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _1 = &(*_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:24: +3:34 + StorageDead(_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34 + goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34 + } + + bb4: { + StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7 + StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching.rs:+5:6: +5:7 + StorageLive(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +10:6 + StorageLive(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + Deinit(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + discriminant(_7) = 0; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + _8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + switchInt(move _8) -> [4_isize: bb6, otherwise: bb5]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 + } + + bb5: { + StorageLive(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 + _9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:28:21: 28:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 + StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 + goto -> bb7; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 + } + + bb6: { + _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + goto -> bb7; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 + } + + bb7: { + StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7 + StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7 + _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2 + return; // scope 0 at $DIR/uninhabited_enum_branching.rs:+11:2: +11:2 + } + } + diff --git a/src/test/mir-opt/uninhabited_enum_branching.rs b/src/test/mir-opt/uninhabited_enum_branching.rs new file mode 100644 index 000000000..0ef604c30 --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum_branching.rs @@ -0,0 +1,30 @@ +enum Empty { } + +// test matching an enum with uninhabited variants +enum Test1 { + A(Empty), + B(Empty), + C +} + +// test an enum where the discriminants don't match the variant indexes +// (the optimization should do nothing here) +enum Test2 { + D = 4, + E = 5, +} + +// EMIT_MIR uninhabited_enum_branching.main.UninhabitedEnumBranching.diff +// EMIT_MIR uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +fn main() { + match Test1::C { + Test1::A(_) => "A(Empty)", + Test1::B(_) => "B(Empty)", + Test1::C => "C", + }; + + match Test2::D { + Test2::D => "D", + Test2::E => "E", + }; +} diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir new file mode 100644 index 000000000..a5e7f5269 --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -0,0 +1,96 @@ +// MIR for `main` after SimplifyCfg-after-uninhabited-enum-branching + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +0:11 + let _1: Plop; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13 + let mut _2: Test1; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46 + let _3: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+3:5: +8:6 + let mut _4: &Test1; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + let mut _5: isize; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+4:9: +4:20 + let _6: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34 + let _7: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24 + let _8: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24 + let _9: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6 + let mut _10: isize; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+11:9: +11:20 + let _11: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34 + let _12: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 + let _13: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 + scope 1 { + debug plop => _1; // in scope 1 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13 + StorageLive(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46 + Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46 + discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46 + Deinit(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48 + (_1.0: u32) = const 51_u32; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48 + (_1.1: Test1) = move _2; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48 + StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:47: +1:48 + StorageLive(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +8:6 + StorageLive(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + _4 = &(_1.1: Test1); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + _5 = discriminant((*_4)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + switchInt(move _5) -> [2_isize: bb2, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 + } + + bb1: { + StorageLive(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24 + _8 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:25:21: 25:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _3 = &(*_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24 + StorageDead(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24 + goto -> bb3; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24 + } + + bb2: { + StorageLive(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24 + _7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:24:21: 24:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _3 = &(*_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24 + StorageDead(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24 + goto -> bb3; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24 + } + + bb3: { + StorageDead(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7 + StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7 + StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6 + _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 + switchInt(move _10) -> [2_isize: bb5, otherwise: bb4]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 + } + + bb4: { + StorageLive(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 + _13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:32:21: 32:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 + StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 + goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 + } + + bb5: { + StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 + _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:31:21: 31:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 + StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 + goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 + } + + bb6: { + StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7 + _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2 + StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2 + return; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:2: +16:2 + } +} diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff new file mode 100644 index 000000000..157518491 --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff @@ -0,0 +1,138 @@ +- // MIR for `main` before UninhabitedEnumBranching ++ // MIR for `main` after UninhabitedEnumBranching + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +0:11 + let _1: Plop; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13 + let mut _2: Test1; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46 + let _3: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+3:5: +8:6 + let mut _4: &Test1; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + let mut _5: isize; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+4:9: +4:20 + let _6: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34 + let _7: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24 + let _8: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24 + let _9: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6 + let mut _10: isize; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+11:9: +11:20 + let _11: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34 + let _12: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 + let _13: &str; // in scope 0 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 + scope 1 { + debug plop => _1; // in scope 1 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:9: +1:13 + StorageLive(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46 + Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46 + discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:38: +1:46 + Deinit(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48 + (_1.0: u32) = const 51_u32; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48 + (_1.1: Test1) = move _2; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:16: +1:48 + StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+1:47: +1:48 + StorageLive(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +8:6 + StorageLive(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + _4 = &(_1.1: Test1); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + _5 = discriminant((*_4)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 +- switchInt(move _5) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 ++ switchInt(move _5) -> [2_isize: bb4, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 + } + + bb1: { + StorageLive(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24 + _8 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:25:21: 25:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _3 = &(*_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:21: +7:24 + StorageDead(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24 + goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24 + } + + bb2: { + _3 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:22:24: 22:34 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34 + } + + bb3: { + StorageLive(_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34 + _6 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:23:24: 23:34 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _3 = &(*_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:24: +5:34 + StorageDead(_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34 + goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34 + } + + bb4: { + StorageLive(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24 + _7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:24:21: 24:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _3 = &(*_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:21: +6:24 + StorageDead(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24 + goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24 + } + + bb5: { + StorageDead(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7 + StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7 + StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6 + _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 +- switchInt(move _10) -> [0_isize: bb7, 1_isize: bb8, 2_isize: bb9, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 ++ switchInt(move _10) -> [2_isize: bb9, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 + } + + bb6: { + StorageLive(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 + _13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:32:21: 32:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 + StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 + goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 + } + + bb7: { + _9 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:29:24: 29:34 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34 + } + + bb8: { + StorageLive(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34 + _11 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:30:24: 30:34 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _9 = &(*_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34 + StorageDead(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34 + goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34 + } + + bb9: { + StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 + _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 + // mir::Constant + // + span: $DIR/uninhabited_enum_branching2.rs:31:21: 31:24 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + _9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 + StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 + goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 + } + + bb10: { + StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7 + _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2 + StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2 + return; // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:2: +16:2 + } + } + diff --git a/src/test/mir-opt/uninhabited_enum_branching2.rs b/src/test/mir-opt/uninhabited_enum_branching2.rs new file mode 100644 index 000000000..e22e94314 --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum_branching2.rs @@ -0,0 +1,34 @@ +enum Empty { } + +// test matching an enum with uninhabited variants +enum Test1 { + A(Empty), + B(Empty), + C, + D, +} + +struct Plop { + xx: u32, + test1: Test1, +} + +// EMIT_MIR uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff +// EMIT_MIR uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +fn main() { + let plop = Plop { xx: 51, test1: Test1::C }; + + match &plop.test1 { + Test1::A(_) => "A(Empty)", + Test1::B(_) => "B(Empty)", + Test1::C => "C", + Test1::D => "D", + }; + + match plop.test1 { + Test1::A(_) => "A(Empty)", + Test1::B(_) => "B(Empty)", + Test1::C => "C", + Test1::D => "D", + }; +} diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff new file mode 100644 index 000000000..11d93fca7 --- /dev/null +++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff @@ -0,0 +1,38 @@ +- // MIR for `eliminate_fallthrough` before UninhabitedEnumBranching ++ // MIR for `eliminate_fallthrough` after UninhabitedEnumBranching + + fn eliminate_fallthrough(_1: S) -> u32 { + debug s => _1; // in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+0:26: +0:27 + let mut _0: u32; // return place in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+0:35: +0:38 + let mut _2: isize; // in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:9: +2:10 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:11: +1:12 +- switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 ++ switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb5]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 3_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15 + goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:14: +2:15 + goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:14: +2:15 + } + + bb3: { + _0 = const 2_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+3:14: +3:15 + goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+3:14: +3:15 + } + + bb4: { + return; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+6:2: +6:2 ++ } ++ ++ bb5: { ++ unreachable; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15 + } + } + diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff new file mode 100644 index 000000000..a7f8321ae --- /dev/null +++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff @@ -0,0 +1,34 @@ +- // MIR for `keep_fallthrough` before UninhabitedEnumBranching ++ // MIR for `keep_fallthrough` after UninhabitedEnumBranching + + fn keep_fallthrough(_1: S) -> u32 { + debug s => _1; // in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+0:21: +0:22 + let mut _0: u32; // return place in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+0:30: +0:33 + let mut _2: isize; // in scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:9: +2:13 + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:11: +1:12 +- switchInt(move _2) -> [0_isize: bb2, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 ++ switchInt(move _2) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 + } + + bb1: { + _0 = const 3_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15 + goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+4:14: +4:15 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:17: +2:18 + goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+2:17: +2:18 + } + + bb3: { + _0 = const 2_u32; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+3:14: +3:15 + goto -> bb4; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+3:14: +3:15 + } + + bb4: { + return; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.rs b/src/test/mir-opt/uninhabited_fallthrough_elimination.rs new file mode 100644 index 000000000..0853883f8 --- /dev/null +++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.rs @@ -0,0 +1,32 @@ +enum Empty {} + +enum S { + A(Empty), + B, + C, +} + +use S::*; + +// EMIT_MIR uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff +fn keep_fallthrough(s: S) -> u32 { + match s { + A(_) => 1, + B => 2, + _ => 3, + } +} + +// EMIT_MIR uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff +fn eliminate_fallthrough(s: S) -> u32 { + match s { + C => 1, + B => 2, + _ => 3, + } +} + +fn main() { + keep_fallthrough(B); + eliminate_fallthrough(B); +} diff --git a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff new file mode 100644 index 000000000..52d9543e9 --- /dev/null +++ b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff @@ -0,0 +1,69 @@ +- // MIR for `main` before UnreachablePropagation ++ // MIR for `main` after UnreachablePropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:11: +0:11 + let mut _1: std::option::Option<Empty>; // in scope 0 at $DIR/unreachable.rs:+1:23: +1:30 + let mut _2: isize; // in scope 0 at $DIR/unreachable.rs:+1:12: +1:20 + let _5: (); // in scope 0 at $DIR/unreachable.rs:+4:9: +8:10 + let mut _6: bool; // in scope 0 at $DIR/unreachable.rs:+4:12: +4:16 + let mut _7: !; // in scope 0 at $DIR/unreachable.rs:+10:9: +10:21 + scope 1 { + debug _x => _3; // in scope 1 at $DIR/unreachable.rs:+1:17: +1:19 + let _3: Empty; // in scope 1 at $DIR/unreachable.rs:+1:17: +1:19 + let mut _4: i32; // in scope 1 at $DIR/unreachable.rs:+2:13: +2:19 + scope 2 { + debug _y => _4; // in scope 2 at $DIR/unreachable.rs:+2:13: +2:19 + } + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/unreachable.rs:+1:23: +1:30 + _1 = empty() -> bb1; // scope 1 at $DIR/unreachable.rs:+1:23: +1:30 + // mir::Constant + // + span: $DIR/unreachable.rs:9:23: 9:28 + // + literal: Const { ty: fn() -> Option<Empty> {empty}, val: Value(<ZST>) } + } + + bb1: { + _2 = discriminant(_1); // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 +- switchInt(move _2) -> [1_isize: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 ++ goto -> bb2; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 + } + + bb2: { +- StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+1:17: +1:19 +- _3 = move ((_1 as Some).0: Empty); // scope 1 at $DIR/unreachable.rs:+1:17: +1:19 +- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+2:13: +2:19 +- StorageLive(_5); // scope 2 at $DIR/unreachable.rs:+4:9: +8:10 +- StorageLive(_6); // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 +- _6 = const true; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 +- switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 +- } +- +- bb3: { +- _4 = const 21_i32; // scope 2 at $DIR/unreachable.rs:+5:13: +5:20 +- _5 = const (); // scope 2 at $DIR/unreachable.rs:+4:17: +6:10 +- goto -> bb5; // scope 2 at $DIR/unreachable.rs:+4:9: +8:10 +- } +- +- bb4: { +- _4 = const 42_i32; // scope 2 at $DIR/unreachable.rs:+7:13: +7:20 +- _5 = const (); // scope 2 at $DIR/unreachable.rs:+6:16: +8:10 +- goto -> bb5; // scope 2 at $DIR/unreachable.rs:+4:9: +8:10 +- } +- +- bb5: { +- StorageDead(_6); // scope 2 at $DIR/unreachable.rs:+8:9: +8:10 +- StorageDead(_5); // scope 2 at $DIR/unreachable.rs:+8:9: +8:10 +- StorageLive(_7); // scope 2 at $DIR/unreachable.rs:+10:9: +10:21 +- unreachable; // scope 2 at $DIR/unreachable.rs:+10:15: +10:17 +- } +- +- bb6: { + _0 = const (); // scope 0 at $DIR/unreachable.rs:+11:6: +11:6 + StorageDead(_1); // scope 0 at $DIR/unreachable.rs:+12:1: +12:2 + return; // scope 0 at $DIR/unreachable.rs:+12:2: +12:2 + } + } + diff --git a/src/test/mir-opt/unreachable.rs b/src/test/mir-opt/unreachable.rs new file mode 100644 index 000000000..6098b525b --- /dev/null +++ b/src/test/mir-opt/unreachable.rs @@ -0,0 +1,20 @@ +enum Empty {} + +fn empty() -> Option<Empty> { + None +} + +// EMIT_MIR unreachable.main.UnreachablePropagation.diff +fn main() { + if let Some(_x) = empty() { + let mut _y; + + if true { + _y = 21; + } else { + _y = 42; + } + + match _x { } + } +} diff --git a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff new file mode 100644 index 000000000..3d31553c4 --- /dev/null +++ b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff @@ -0,0 +1,74 @@ +- // MIR for `main` before UnreachablePropagation ++ // MIR for `main` after UnreachablePropagation + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/unreachable_diverging.rs:+0:11: +0:11 + let _1: bool; // in scope 0 at $DIR/unreachable_diverging.rs:+1:9: +1:10 + let mut _2: std::option::Option<Empty>; // in scope 0 at $DIR/unreachable_diverging.rs:+2:25: +2:32 + let mut _3: isize; // in scope 0 at $DIR/unreachable_diverging.rs:+2:12: +2:22 + let _5: (); // in scope 0 at $DIR/unreachable_diverging.rs:+3:9: +5:10 + let mut _6: bool; // in scope 0 at $DIR/unreachable_diverging.rs:+3:12: +3:13 + let mut _7: !; // in scope 0 at $DIR/unreachable_diverging.rs:+6:9: +6:22 + scope 1 { + debug x => _1; // in scope 1 at $DIR/unreachable_diverging.rs:+1:9: +1:10 + scope 2 { + debug bomb => _4; // in scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21 + let _4: Empty; // in scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/unreachable_diverging.rs:+1:9: +1:10 + _1 = const true; // scope 0 at $DIR/unreachable_diverging.rs:+1:13: +1:17 + StorageLive(_2); // scope 2 at $DIR/unreachable_diverging.rs:+2:25: +2:32 + _2 = empty() -> bb1; // scope 2 at $DIR/unreachable_diverging.rs:+2:25: +2:32 + // mir::Constant + // + span: $DIR/unreachable_diverging.rs:14:25: 14:30 + // + literal: Const { ty: fn() -> Option<Empty> {empty}, val: Value(<ZST>) } + } + + bb1: { + _3 = discriminant(_2); // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22 +- switchInt(move _3) -> [1_isize: bb2, otherwise: bb6]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22 ++ switchInt(move _3) -> [1_isize: bb2, otherwise: bb5]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22 + } + + bb2: { + StorageLive(_4); // scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21 + _4 = move ((_2 as Some).0: Empty); // scope 2 at $DIR/unreachable_diverging.rs:+2:17: +2:21 + StorageLive(_5); // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10 + StorageLive(_6); // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 + _6 = _1; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 +- switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 ++ goto -> bb3; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 + } + + bb3: { +- _5 = loop_forever() -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27 ++ _5 = loop_forever() -> bb4; // scope 2 at $DIR/unreachable_diverging.rs:+4:13: +4:27 + // mir::Constant + // + span: $DIR/unreachable_diverging.rs:16:13: 16:25 + // + literal: Const { ty: fn() {loop_forever}, val: Value(<ZST>) } + } + + bb4: { +- _5 = const (); // scope 2 at $DIR/unreachable_diverging.rs:+5:10: +5:10 +- goto -> bb5; // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10 +- } +- +- bb5: { + StorageDead(_6); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10 + StorageDead(_5); // scope 2 at $DIR/unreachable_diverging.rs:+5:9: +5:10 + StorageLive(_7); // scope 2 at $DIR/unreachable_diverging.rs:+6:9: +6:22 + unreachable; // scope 2 at $DIR/unreachable_diverging.rs:+6:15: +6:19 + } + +- bb6: { ++ bb5: { + _0 = const (); // scope 1 at $DIR/unreachable_diverging.rs:+7:6: +7:6 + StorageDead(_1); // scope 0 at $DIR/unreachable_diverging.rs:+8:1: +8:2 + StorageDead(_2); // scope 0 at $DIR/unreachable_diverging.rs:+8:1: +8:2 + return; // scope 0 at $DIR/unreachable_diverging.rs:+8:2: +8:2 + } + } + diff --git a/src/test/mir-opt/unreachable_diverging.rs b/src/test/mir-opt/unreachable_diverging.rs new file mode 100644 index 000000000..bbf28efc7 --- /dev/null +++ b/src/test/mir-opt/unreachable_diverging.rs @@ -0,0 +1,20 @@ +pub enum Empty {} + +fn empty() -> Option<Empty> { + None +} + +fn loop_forever() { + loop {} +} + +// EMIT_MIR unreachable_diverging.main.UnreachablePropagation.diff +fn main() { + let x = true; + if let Some(bomb) = empty() { + if x { + loop_forever() + } + match bomb {} + } +} diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs new file mode 100644 index 000000000..670f61cd5 --- /dev/null +++ b/src/test/mir-opt/unusual-item-types.rs @@ -0,0 +1,29 @@ +// Test that we don't ICE when trying to dump MIR for unusual item types and +// that we don't create filenames containing `<` and `>` +// compile-flags: -Zmir-opt-level=0 +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +struct A; + +// EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir +impl A { + const ASSOCIATED_CONSTANT: i32 = 2; +} + +// See #59021 +// EMIT_MIR unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir +enum Test { + X(usize), + Y { a: usize }, +} + +// EMIT_MIR unusual_item_types.E-V-{constant#0}.mir_map.0.mir +enum E { + V = 5, +} + +fn main() { + let f = Test::X as fn(usize) -> Test; +// EMIT_MIR core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir + let v = Vec::<i32>::new(); +} diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir new file mode 100644 index 000000000..a72e00ecd --- /dev/null +++ b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.32bit.mir @@ -0,0 +1,10 @@ +// MIR for `E::V::{constant#0}` 0 mir_map + +E::V::{constant#0}: isize = { + let mut _0: isize; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 + + bb0: { + _0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 + return; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 + } +} diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir new file mode 100644 index 000000000..a72e00ecd --- /dev/null +++ b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.64bit.mir @@ -0,0 +1,10 @@ +// MIR for `E::V::{constant#0}` 0 mir_map + +E::V::{constant#0}: isize = { + let mut _0: isize; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 + + bb0: { + _0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 + return; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10 + } +} diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir new file mode 100644 index 000000000..0686af46e --- /dev/null +++ b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.32bit.mir @@ -0,0 +1,12 @@ +// MIR for `Test::X` 0 mir_map + +fn Test::X(_1: usize) -> Test { + let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + + bb0: { + Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + } +} diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir new file mode 100644 index 000000000..0686af46e --- /dev/null +++ b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.64bit.mir @@ -0,0 +1,12 @@ +// MIR for `Test::X` 0 mir_map + +fn Test::X(_1: usize) -> Test { + let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + + bb0: { + Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6 + } +} diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir new file mode 100644 index 000000000..7ffd242e0 --- /dev/null +++ b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.32bit.mir @@ -0,0 +1,39 @@ +// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops + +fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () { + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _2: &mut std::vec::Vec<i32>; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + + bb0: { + goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb3: { + goto -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb4 (cleanup): { + drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb5: { + drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb6: { + _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _3 = <Vec<i32> as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + // mir::Constant + // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL + // + literal: Const { ty: for<'r> fn(&'r mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) } + } +} diff --git a/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir new file mode 100644 index 000000000..7ffd242e0 --- /dev/null +++ b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.64bit.mir @@ -0,0 +1,39 @@ +// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops + +fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () { + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _2: &mut std::vec::Vec<i32>; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + + bb0: { + goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb3: { + goto -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb4 (cleanup): { + drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb2; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb5: { + drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb3, unwind: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } + + bb6: { + _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _3 = <Vec<i32> as Drop>::drop(move _2) -> [return: bb5, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + // mir::Constant + // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL + // + literal: Const { ty: for<'r> fn(&'r mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) } + } +} diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir new file mode 100644 index 000000000..f7bc8d58f --- /dev/null +++ b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.32bit.mir @@ -0,0 +1,10 @@ +// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map + +const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = { + let mut _0: i32; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35 + + bb0: { + _0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39 + return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:35 + } +} diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir new file mode 100644 index 000000000..f7bc8d58f --- /dev/null +++ b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.64bit.mir @@ -0,0 +1,10 @@ +// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map + +const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = { + let mut _0: i32; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35 + + bb0: { + _0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39 + return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:35 + } +} diff --git a/src/test/mir-opt/while-storage.rs b/src/test/mir-opt/while-storage.rs new file mode 100644 index 000000000..afd083acb --- /dev/null +++ b/src/test/mir-opt/while-storage.rs @@ -0,0 +1,19 @@ +// Test that we correctly generate StorageDead statements for while loop +// conditions on all branches + +fn get_bool(c: bool) -> bool { + c +} + +// EMIT_MIR while_storage.while_loop.PreCodegen.after.mir +fn while_loop(c: bool) { + while get_bool(c) { + if get_bool(c) { + break; + } + } +} + +fn main() { + while_loop(false); +} diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff new file mode 100644 index 000000000..eef701114 --- /dev/null +++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff @@ -0,0 +1,55 @@ +- // MIR for `change_loop_body` before ConstProp ++ // MIR for `change_loop_body` after ConstProp + + fn change_loop_body() -> () { + let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27 + let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 + let mut _2: (); // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2 + let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32 + let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25 + let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6 + let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + let _7: (); // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + scope 1 { + debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15 + scope 2 { + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 + _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19 + StorageLive(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + Deinit(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + discriminant(_3) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 +- _4 = discriminant(_3); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 +- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ _4 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + } + + bb1: { + switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + } + + bb2: { + _1 = const 1_i32; // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15 + nop; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 + goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 + } + + bb3: { + StorageLive(_7); // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 + nop; // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 + StorageDead(_7); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 + goto -> bb4; // scope 1 at no-location + } + + bb4: { + StorageDead(_3); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 + StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2 + return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff new file mode 100644 index 000000000..eef701114 --- /dev/null +++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff @@ -0,0 +1,55 @@ +- // MIR for `change_loop_body` before ConstProp ++ // MIR for `change_loop_body` after ConstProp + + fn change_loop_body() -> () { + let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27 + let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 + let mut _2: (); // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2 + let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32 + let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25 + let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6 + let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + let _7: (); // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + scope 1 { + debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15 + scope 2 { + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 + _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19 + StorageLive(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + Deinit(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + discriminant(_3) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 +- _4 = discriminant(_3); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 +- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ _4 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + } + + bb1: { + switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + } + + bb2: { + _1 = const 1_i32; // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15 + nop; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 + goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 + } + + bb3: { + StorageLive(_7); // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 + nop; // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 + StorageDead(_7); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 + goto -> bb4; // scope 1 at no-location + } + + bb4: { + StorageDead(_3); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 + StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2 + return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir new file mode 100644 index 000000000..15b0aece8 --- /dev/null +++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir @@ -0,0 +1,17 @@ +// MIR for `change_loop_body` after PreCodegen + +fn change_loop_body() -> () { + let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27 + let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 + scope 1 { + debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15 + scope 2 { + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 + StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2 + return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2 + } +} diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir new file mode 100644 index 000000000..15b0aece8 --- /dev/null +++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir @@ -0,0 +1,17 @@ +// MIR for `change_loop_body` after PreCodegen + +fn change_loop_body() -> () { + let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27 + let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 + scope 1 { + debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15 + scope 2 { + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 + StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2 + return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2 + } +} diff --git a/src/test/mir-opt/while_let_loops.rs b/src/test/mir-opt/while_let_loops.rs new file mode 100644 index 000000000..f320a218c --- /dev/null +++ b/src/test/mir-opt/while_let_loops.rs @@ -0,0 +1,15 @@ +// EMIT_MIR while_let_loops.change_loop_body.ConstProp.diff +// EMIT_MIR while_let_loops.change_loop_body.PreCodegen.after.mir +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +pub fn change_loop_body() { + let mut _x = 0; + while let Some(0u32) = None { + _x = 1; + break; + } +} + +fn main() { + change_loop_body(); +} diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir new file mode 100644 index 000000000..a5e7d6afd --- /dev/null +++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir @@ -0,0 +1,64 @@ +// MIR for `while_loop` after PreCodegen + +fn while_loop(_1: bool) -> () { + debug c => _1; // in scope 0 at $DIR/while-storage.rs:+0:15: +0:16 + let mut _0: (); // return place in scope 0 at $DIR/while-storage.rs:+0:24: +0:24 + let mut _2: bool; // in scope 0 at $DIR/while-storage.rs:+1:11: +1:22 + let mut _3: bool; // in scope 0 at $DIR/while-storage.rs:+1:20: +1:21 + let mut _4: bool; // in scope 0 at $DIR/while-storage.rs:+2:12: +2:23 + let mut _5: bool; // in scope 0 at $DIR/while-storage.rs:+2:21: +2:22 + + bb0: { + goto -> bb1; // scope 0 at $DIR/while-storage.rs:+1:5: +5:6 + } + + bb1: { + StorageLive(_2); // scope 0 at $DIR/while-storage.rs:+1:11: +1:22 + StorageLive(_3); // scope 0 at $DIR/while-storage.rs:+1:20: +1:21 + _3 = _1; // scope 0 at $DIR/while-storage.rs:+1:20: +1:21 + _2 = get_bool(move _3) -> bb2; // scope 0 at $DIR/while-storage.rs:+1:11: +1:22 + // mir::Constant + // + span: $DIR/while-storage.rs:10:11: 10:19 + // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/while-storage.rs:+1:21: +1:22 + switchInt(move _2) -> [false: bb7, otherwise: bb3]; // scope 0 at $DIR/while-storage.rs:+1:11: +1:22 + } + + bb3: { + StorageLive(_4); // scope 0 at $DIR/while-storage.rs:+2:12: +2:23 + StorageLive(_5); // scope 0 at $DIR/while-storage.rs:+2:21: +2:22 + _5 = _1; // scope 0 at $DIR/while-storage.rs:+2:21: +2:22 + _4 = get_bool(move _5) -> bb4; // scope 0 at $DIR/while-storage.rs:+2:12: +2:23 + // mir::Constant + // + span: $DIR/while-storage.rs:11:12: 11:20 + // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(<ZST>) } + } + + bb4: { + StorageDead(_5); // scope 0 at $DIR/while-storage.rs:+2:22: +2:23 + switchInt(move _4) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/while-storage.rs:+2:12: +2:23 + } + + bb5: { + StorageDead(_4); // scope 0 at $DIR/while-storage.rs:+4:9: +4:10 + goto -> bb8; // scope 0 at no-location + } + + bb6: { + StorageDead(_4); // scope 0 at $DIR/while-storage.rs:+4:9: +4:10 + StorageDead(_2); // scope 0 at $DIR/while-storage.rs:+5:5: +5:6 + goto -> bb1; // scope 0 at $DIR/while-storage.rs:+1:5: +5:6 + } + + bb7: { + goto -> bb8; // scope 0 at no-location + } + + bb8: { + StorageDead(_2); // scope 0 at $DIR/while-storage.rs:+5:5: +5:6 + return; // scope 0 at $DIR/while-storage.rs:+6:2: +6:2 + } +} |