diff options
Diffstat (limited to 'tests/mir-opt')
584 files changed, 24216 insertions, 0 deletions
diff --git a/tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff b/tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff new file mode 100644 index 000000000..9780332d8 --- /dev/null +++ b/tests/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: 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/tests/mir-opt/76803_regression.rs b/tests/mir-opt/76803_regression.rs new file mode 100644 index 000000000..05dc3c978 --- /dev/null +++ b/tests/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/tests/mir-opt/README.md b/tests/mir-opt/README.md new file mode 100644 index 000000000..0721d9f70 --- /dev/null +++ b/tests/mir-opt/README.md @@ -0,0 +1,51 @@ +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. + +## Unit testing + +If you are only testing the behavior of a particular mir-opt pass on some specific input (as is +usually the case), you should add + +``` +// unit-test: PassName +``` + +to the top of the file. This makes sure that other passes don't run which means you'll get the input +you expected and your test won't break when other code changes. + +## 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/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..5f8b2f931 --- /dev/null +++ b/tests/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/tests/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..4c67376b5 --- /dev/null +++ b/tests/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/tests/mir-opt/address_of.rs b/tests/mir-opt/address_of.rs new file mode 100644 index 000000000..c4bea5613 --- /dev/null +++ b/tests/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/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..af5178d40 --- /dev/null +++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.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/tests/mir-opt/array_index_is_temporary.rs b/tests/mir-opt/array_index_is_temporary.rs new file mode 100644 index 000000000..e7bde81d4 --- /dev/null +++ b/tests/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 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/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir b/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir new file mode 100644 index 000000000..2487ef5c2 --- /dev/null +++ b/tests/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/tests/mir-opt/asm_unwind_panic_abort.rs b/tests/mir-opt/asm_unwind_panic_abort.rs new file mode 100644 index 000000000..ad8f9398e --- /dev/null +++ b/tests/mir-opt/asm_unwind_panic_abort.rs @@ -0,0 +1,15 @@ +//! Tests that unwinding from an asm block is caught and forced to abort +//! when `-C panic=abort`. + +// 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/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..1f099cd5e --- /dev/null +++ b/tests/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/tests/mir-opt/basic_assignment.rs b/tests/mir-opt/basic_assignment.rs new file mode 100644 index 000000000..ac350271e --- /dev/null +++ b/tests/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/tests/mir-opt/bool_compare.opt1.InstCombine.diff b/tests/mir-opt/bool_compare.opt1.InstCombine.diff new file mode 100644 index 000000000..0af5d82d3 --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/bool_compare.opt2.InstCombine.diff b/tests/mir-opt/bool_compare.opt2.InstCombine.diff new file mode 100644 index 000000000..f5d1febd9 --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/bool_compare.opt3.InstCombine.diff b/tests/mir-opt/bool_compare.opt3.InstCombine.diff new file mode 100644 index 000000000..e7432adac --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/bool_compare.opt4.InstCombine.diff b/tests/mir-opt/bool_compare.opt4.InstCombine.diff new file mode 100644 index 000000000..6b3e27772 --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/bool_compare.rs b/tests/mir-opt/bool_compare.rs new file mode 100644 index 000000000..4435bf5b0 --- /dev/null +++ b/tests/mir-opt/bool_compare.rs @@ -0,0 +1,28 @@ +// unit-test: InstCombine + +// 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/tests/mir-opt/box_expr.main.ElaborateDrops.before.mir b/tests/mir-opt/box_expr.main.ElaborateDrops.before.mir new file mode 100644 index 000000000..49133138d --- /dev/null +++ b/tests/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/tests/mir-opt/box_expr.rs b/tests/mir-opt/box_expr.rs new file mode 100644 index 000000000..a214504f6 --- /dev/null +++ b/tests/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/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir new file mode 100644 index 000000000..2a7f90fe9 --- /dev/null +++ b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir @@ -0,0 +1,41 @@ +// MIR for `a::{closure#0}` 0 generator_resume +/* generator_layout = GeneratorLayout { + field_tys: {}, + variant_fields: { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + }, + storage_conflicts: BitMatrix(0x0) {}, +} */ + +fn a::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:11:14: 11:16]>, _2: &mut Context<'_>) -> Poll<()> { + debug _task_context => _4; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16 + let mut _0: std::task::Poll<()>; // return place in scope 0 at $DIR/async_await.rs:+0:14: +0:16 + let mut _3: (); // in scope 0 at $DIR/async_await.rs:+0:14: +0:16 + let mut _4: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16 + let mut _5: u32; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16 + + bb0: { + _5 = discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:11:14: 11:16]))); // scope 0 at $DIR/async_await.rs:+0:14: +0:16 + switchInt(move _5) -> [0: bb1, 1: bb2, otherwise: bb3]; // scope 0 at $DIR/async_await.rs:+0:14: +0:16 + } + + bb1: { + _4 = move _2; // scope 0 at $DIR/async_await.rs:+0:14: +0:16 + _3 = const (); // scope 0 at $DIR/async_await.rs:+0:14: +0:16 + Deinit(_0); // scope 0 at $DIR/async_await.rs:+0:16: +0:16 + ((_0 as Ready).0: ()) = move _3; // scope 0 at $DIR/async_await.rs:+0:16: +0:16 + discriminant(_0) = 0; // scope 0 at $DIR/async_await.rs:+0:16: +0:16 + discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:11:14: 11:16]))) = 1; // scope 0 at $DIR/async_await.rs:+0:16: +0:16 + return; // scope 0 at $DIR/async_await.rs:+0:16: +0:16 + } + + bb2: { + assert(const false, "`async fn` resumed after completion") -> bb2; // scope 0 at $DIR/async_await.rs:+0:14: +0:16 + } + + bb3: { + unreachable; // scope 0 at $DIR/async_await.rs:+0:14: +0:16 + } +} diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir new file mode 100644 index 000000000..05edc4797 --- /dev/null +++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir @@ -0,0 +1,337 @@ +// MIR for `b::{closure#0}` 0 generator_resume +/* generator_layout = GeneratorLayout { + field_tys: { + _0: impl std::future::Future<Output = ()>, + _1: impl std::future::Future<Output = ()>, + }, + variant_fields: { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_0], + Suspend1 (4): [_1], + }, + storage_conflicts: BitMatrix(2x2) { + (_0, _0), + (_1, _1), + }, +} */ + +fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, _2: &mut Context<'_>) -> Poll<()> { + debug _task_context => _38; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2 + let mut _0: std::task::Poll<()>; // return place in scope 0 at $DIR/async_await.rs:+0:18: +3:2 + let _3: (); // in scope 0 at $DIR/async_await.rs:+1:5: +1:14 + let mut _4: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _5: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:8 + let mut _6: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _7: (); // in scope 0 at $DIR/async_await.rs:+0:18: +3:2 + let _8: (); // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _9: std::task::Poll<()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _10: std::pin::Pin<&mut impl std::future::Future<Output = ()>>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _11: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _12: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _13: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14 + let mut _14: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14 + let mut _15: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _16: isize; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _18: !; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14 + let mut _19: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _20: (); // in scope 0 at $DIR/async_await.rs:+1:8: +1:14 + let mut _21: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _22: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:8 + let mut _23: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let _24: (); // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _25: std::task::Poll<()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _26: std::pin::Pin<&mut impl std::future::Future<Output = ()>>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _27: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _28: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _29: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14 + let mut _30: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14 + let mut _31: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _32: isize; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _34: !; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14 + let mut _35: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _36: (); // in scope 0 at $DIR/async_await.rs:+2:8: +2:14 + let mut _37: (); // in scope 0 at $DIR/async_await.rs:+0:18: +3:2 + let mut _38: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2 + let mut _39: u32; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2 + scope 1 { + debug __awaitee => (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>); // in scope 1 at $DIR/async_await.rs:+1:8: +1:14 + let _17: (); // in scope 1 at $DIR/async_await.rs:+1:5: +1:14 + scope 2 { + } + scope 3 { + debug result => _17; // in scope 3 at $DIR/async_await.rs:+1:5: +1:14 + } + } + scope 4 { + debug __awaitee => (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>); // in scope 4 at $DIR/async_await.rs:+2:8: +2:14 + let _33: (); // in scope 4 at $DIR/async_await.rs:+2:5: +2:14 + scope 5 { + } + scope 6 { + debug result => _33; // in scope 6 at $DIR/async_await.rs:+2:5: +2:14 + } + } + + bb0: { + _39 = discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb30]; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + } + + bb1: { + _38 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + StorageLive(_3); // scope 0 at $DIR/async_await.rs:+1:5: +1:14 + StorageLive(_4); // scope 0 at $DIR/async_await.rs:+1:8: +1:14 + StorageLive(_5); // scope 0 at $DIR/async_await.rs:+1:5: +1:8 + _5 = a() -> bb2; // scope 0 at $DIR/async_await.rs:+1:5: +1:8 + // mir::Constant + // + span: $DIR/async_await.rs:15:5: 15:6 + // + literal: Const { ty: fn() -> impl Future<Output = ()> {a}, val: Value(<ZST>) } + } + + bb2: { + _4 = <impl Future<Output = ()> as IntoFuture>::into_future(move _5) -> bb3; // scope 0 at $DIR/async_await.rs:+1:8: +1:14 + // mir::Constant + // + span: $DIR/async_await.rs:15:8: 15:14 + // + literal: Const { ty: fn(impl Future<Output = ()>) -> <impl Future<Output = ()> as IntoFuture>::IntoFuture {<impl Future<Output = ()> as IntoFuture>::into_future}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_5); // scope 0 at $DIR/async_await.rs:+1:13: +1:14 + nop; // scope 0 at $DIR/async_await.rs:+1:8: +1:14 + (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>) = move _4; // scope 0 at $DIR/async_await.rs:+1:8: +1:14 + goto -> bb4; // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + } + + bb4: { + StorageLive(_8); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + StorageLive(_9); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + StorageLive(_10); // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + StorageLive(_11); // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + StorageLive(_12); // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + _12 = &mut (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>); // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + _11 = &mut (*_12); // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + _10 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _11) -> bb5; // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + // mir::Constant + // + span: $DIR/async_await.rs:15:8: 15:14 + // + literal: Const { ty: unsafe fn(&mut impl Future<Output = ()>) -> Pin<&mut impl Future<Output = ()>> {Pin::<&mut impl Future<Output = ()>>::new_unchecked}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_11); // scope 2 at $DIR/async_await.rs:+1:13: +1:14 + StorageLive(_13); // scope 2 at $DIR/async_await.rs:+1:5: +1:14 + StorageLive(_14); // scope 2 at $DIR/async_await.rs:+1:5: +1:14 + StorageLive(_15); // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + _15 = _38; // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + _14 = move _15; // scope 2 at $DIR/async_await.rs:+1:5: +1:14 + goto -> bb6; // scope 2 at $DIR/async_await.rs:+1:5: +1:14 + } + + bb6: { + _13 = &mut (*_14); // scope 2 at $DIR/async_await.rs:+1:5: +1:14 + StorageDead(_15); // scope 2 at $DIR/async_await.rs:+1:13: +1:14 + _9 = <impl Future<Output = ()> as Future>::poll(move _10, move _13) -> bb7; // scope 2 at $DIR/async_await.rs:+1:8: +1:14 + // mir::Constant + // + span: $DIR/async_await.rs:15:8: 15:14 + // + literal: Const { ty: for<'a, 'b, 'c> fn(Pin<&'a mut impl Future<Output = ()>>, &'b mut Context<'c>) -> Poll<<impl Future<Output = ()> as Future>::Output> {<impl Future<Output = ()> as Future>::poll}, val: Value(<ZST>) } + } + + bb7: { + StorageDead(_13); // scope 2 at $DIR/async_await.rs:+1:13: +1:14 + StorageDead(_10); // scope 2 at $DIR/async_await.rs:+1:13: +1:14 + _16 = discriminant(_9); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + switchInt(move _16) -> [0: bb10, 1: bb8, otherwise: bb9]; // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + } + + bb8: { + _8 = const (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + StorageDead(_14); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + StorageDead(_12); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + StorageDead(_9); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + StorageDead(_8); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + StorageLive(_19); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + StorageLive(_20); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + _20 = (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + Deinit(_0); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + discriminant(_0) = 1; // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 3; // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + return; // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + } + + bb9: { + unreachable; // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + } + + bb10: { + StorageLive(_17); // scope 1 at $DIR/async_await.rs:+1:5: +1:14 + _17 = ((_9 as Ready).0: ()); // scope 1 at $DIR/async_await.rs:+1:5: +1:14 + _3 = _17; // scope 3 at $DIR/async_await.rs:+1:5: +1:14 + StorageDead(_17); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + StorageDead(_14); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + StorageDead(_12); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + StorageDead(_9); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + StorageDead(_8); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + goto -> bb12; // scope 0 at $DIR/async_await.rs:+1:13: +1:14 + } + + bb11: { + StorageDead(_20); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + _38 = move _19; // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + StorageDead(_19); // scope 1 at $DIR/async_await.rs:+1:13: +1:14 + _7 = const (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + goto -> bb4; // scope 1 at $DIR/async_await.rs:+1:8: +1:14 + } + + bb12: { + nop; // scope 0 at $DIR/async_await.rs:+1:13: +1:14 + goto -> bb13; // scope 0 at $DIR/async_await.rs:+1:14: +1:15 + } + + bb13: { + StorageDead(_4); // scope 0 at $DIR/async_await.rs:+1:14: +1:15 + StorageDead(_3); // scope 0 at $DIR/async_await.rs:+1:14: +1:15 + StorageLive(_21); // scope 0 at $DIR/async_await.rs:+2:8: +2:14 + StorageLive(_22); // scope 0 at $DIR/async_await.rs:+2:5: +2:8 + _22 = a() -> bb14; // scope 0 at $DIR/async_await.rs:+2:5: +2:8 + // mir::Constant + // + span: $DIR/async_await.rs:16:5: 16:6 + // + literal: Const { ty: fn() -> impl Future<Output = ()> {a}, val: Value(<ZST>) } + } + + bb14: { + _21 = <impl Future<Output = ()> as IntoFuture>::into_future(move _22) -> bb15; // scope 0 at $DIR/async_await.rs:+2:8: +2:14 + // mir::Constant + // + span: $DIR/async_await.rs:16:8: 16:14 + // + literal: Const { ty: fn(impl Future<Output = ()>) -> <impl Future<Output = ()> as IntoFuture>::IntoFuture {<impl Future<Output = ()> as IntoFuture>::into_future}, val: Value(<ZST>) } + } + + bb15: { + StorageDead(_22); // scope 0 at $DIR/async_await.rs:+2:13: +2:14 + nop; // scope 0 at $DIR/async_await.rs:+2:8: +2:14 + (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>) = move _21; // scope 0 at $DIR/async_await.rs:+2:8: +2:14 + goto -> bb16; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + } + + bb16: { + StorageLive(_24); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + StorageLive(_25); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + StorageLive(_26); // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + StorageLive(_27); // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + StorageLive(_28); // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + _28 = &mut (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>); // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + _27 = &mut (*_28); // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + _26 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _27) -> bb17; // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + // mir::Constant + // + span: $DIR/async_await.rs:16:8: 16:14 + // + literal: Const { ty: unsafe fn(&mut impl Future<Output = ()>) -> Pin<&mut impl Future<Output = ()>> {Pin::<&mut impl Future<Output = ()>>::new_unchecked}, val: Value(<ZST>) } + } + + bb17: { + StorageDead(_27); // scope 5 at $DIR/async_await.rs:+2:13: +2:14 + StorageLive(_29); // scope 5 at $DIR/async_await.rs:+2:5: +2:14 + StorageLive(_30); // scope 5 at $DIR/async_await.rs:+2:5: +2:14 + StorageLive(_31); // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + _31 = _38; // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + _30 = move _31; // scope 5 at $DIR/async_await.rs:+2:5: +2:14 + goto -> bb18; // scope 5 at $DIR/async_await.rs:+2:5: +2:14 + } + + bb18: { + _29 = &mut (*_30); // scope 5 at $DIR/async_await.rs:+2:5: +2:14 + StorageDead(_31); // scope 5 at $DIR/async_await.rs:+2:13: +2:14 + _25 = <impl Future<Output = ()> as Future>::poll(move _26, move _29) -> bb19; // scope 5 at $DIR/async_await.rs:+2:8: +2:14 + // mir::Constant + // + span: $DIR/async_await.rs:16:8: 16:14 + // + literal: Const { ty: for<'a, 'b, 'c> fn(Pin<&'a mut impl Future<Output = ()>>, &'b mut Context<'c>) -> Poll<<impl Future<Output = ()> as Future>::Output> {<impl Future<Output = ()> as Future>::poll}, val: Value(<ZST>) } + } + + bb19: { + StorageDead(_29); // scope 5 at $DIR/async_await.rs:+2:13: +2:14 + StorageDead(_26); // scope 5 at $DIR/async_await.rs:+2:13: +2:14 + _32 = discriminant(_25); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + switchInt(move _32) -> [0: bb22, 1: bb20, otherwise: bb21]; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + } + + bb20: { + _24 = const (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + StorageDead(_30); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + StorageDead(_28); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + StorageDead(_25); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + StorageDead(_24); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + StorageLive(_35); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + StorageLive(_36); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + _36 = (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + Deinit(_0); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + discriminant(_0) = 1; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 4; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + return; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + } + + bb21: { + unreachable; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + } + + bb22: { + StorageLive(_33); // scope 4 at $DIR/async_await.rs:+2:5: +2:14 + _33 = ((_25 as Ready).0: ()); // scope 4 at $DIR/async_await.rs:+2:5: +2:14 + _37 = _33; // scope 6 at $DIR/async_await.rs:+2:5: +2:14 + StorageDead(_33); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + StorageDead(_30); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + StorageDead(_28); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + StorageDead(_25); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + StorageDead(_24); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + goto -> bb24; // scope 0 at $DIR/async_await.rs:+2:13: +2:14 + } + + bb23: { + StorageDead(_36); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + _38 = move _35; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + StorageDead(_35); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 + _7 = const (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + goto -> bb16; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + } + + bb24: { + nop; // scope 0 at $DIR/async_await.rs:+2:13: +2:14 + goto -> bb25; // scope 0 at $DIR/async_await.rs:+3:1: +3:2 + } + + bb25: { + StorageDead(_21); // scope 0 at $DIR/async_await.rs:+3:1: +3:2 + goto -> bb26; // scope 0 at $DIR/async_await.rs:+3:1: +3:2 + } + + bb26: { + Deinit(_0); // scope 0 at $DIR/async_await.rs:+3:2: +3:2 + ((_0 as Ready).0: ()) = move _37; // scope 0 at $DIR/async_await.rs:+3:2: +3:2 + discriminant(_0) = 0; // scope 0 at $DIR/async_await.rs:+3:2: +3:2 + discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 1; // scope 0 at $DIR/async_await.rs:+3:2: +3:2 + return; // scope 0 at $DIR/async_await.rs:+3:2: +3:2 + } + + bb27: { + StorageLive(_3); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + StorageLive(_4); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + StorageLive(_19); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + StorageLive(_20); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + _19 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + goto -> bb11; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + } + + bb28: { + StorageLive(_21); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + StorageLive(_35); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + StorageLive(_36); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + _35 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + goto -> bb23; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + } + + bb29: { + assert(const false, "`async fn` resumed after completion") -> bb29; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + } + + bb30: { + unreachable; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + } +} diff --git a/tests/mir-opt/building/async_await.rs b/tests/mir-opt/building/async_await.rs new file mode 100644 index 000000000..0b991e3b8 --- /dev/null +++ b/tests/mir-opt/building/async_await.rs @@ -0,0 +1,17 @@ +// This test makes sure that the generator MIR pass eliminates all calls to +// `get_context`, and that the MIR argument type for an async fn and all locals +// related to `yield` are `&mut Context`, and its return type is `Poll`. + +// edition:2018 +// compile-flags: -C panic=abort + +#![crate_type = "lib"] + +// EMIT_MIR async_await.a-{closure#0}.generator_resume.0.mir +async fn a() {} + +// EMIT_MIR async_await.b-{closure#0}.generator_resume.0.mir +pub async fn b() { + a().await; + a().await +} diff --git a/tests/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir b/tests/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir new file mode 100644 index 000000000..20dd251e7 --- /dev/null +++ b/tests/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir @@ -0,0 +1,22 @@ +// MIR for `arbitrary_let` after built + +fn arbitrary_let(_1: i32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/arbitrary_let.rs:+0:29: +0:32 + let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + goto -> bb2; // scope 0 at $DIR/arbitrary_let.rs:+4:13: +4:25 + } + + bb1: { + _0 = _3; // scope 0 at $DIR/arbitrary_let.rs:+7:13: +7:20 + return; // scope 0 at $DIR/arbitrary_let.rs:+8:13: +8:21 + } + + bb2: { + _3 = _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + goto -> bb1; // scope 0 at $DIR/arbitrary_let.rs:+12:13: +12:24 + } +} diff --git a/tests/mir-opt/building/custom/arbitrary_let.rs b/tests/mir-opt/building/custom/arbitrary_let.rs new file mode 100644 index 000000000..776df3151 --- /dev/null +++ b/tests/mir-opt/building/custom/arbitrary_let.rs @@ -0,0 +1,28 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; +use core::ptr::{addr_of, addr_of_mut}; + +// EMIT_MIR arbitrary_let.arbitrary_let.built.after.mir +#[custom_mir(dialect = "built")] +fn arbitrary_let(x: i32) -> i32 { + mir!( + { + let y = x; + Goto(second) + } + third = { + RET = z; + Return() + } + second = { + let z = y; + Goto(third) + } + ) +} + +fn main() { + assert_eq!(arbitrary_let(5), 5); +} diff --git a/tests/mir-opt/building/custom/consts.consts.built.after.mir b/tests/mir-opt/building/custom/consts.consts.built.after.mir new file mode 100644 index 000000000..ba753cfc2 --- /dev/null +++ b/tests/mir-opt/building/custom/consts.consts.built.after.mir @@ -0,0 +1,22 @@ +// MIR for `consts` after built + +fn consts() -> () { + let mut _0: (); // return place in scope 0 at $DIR/consts.rs:+0:27: +0:27 + let mut _1: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: i8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: u32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _4: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _5: fn() {consts::<10>}; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _1 = const 5_u8; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _2 = const _; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _3 = const C; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _4 = const _; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _5 = consts::<10>; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + // mir::Constant + // + span: $DIR/consts.rs:16:18: 16:30 + // + literal: Const { ty: fn() {consts::<10>}, val: Value(<ZST>) } + return; // scope 0 at $DIR/consts.rs:+7:9: +7:17 + } +} diff --git a/tests/mir-opt/building/custom/consts.rs b/tests/mir-opt/building/custom/consts.rs new file mode 100644 index 000000000..16d10eb59 --- /dev/null +++ b/tests/mir-opt/building/custom/consts.rs @@ -0,0 +1,36 @@ +#![feature(custom_mir, core_intrinsics, inline_const)] + +extern crate core; +use core::intrinsics::mir::*; + +const D: i32 = 5; + +// EMIT_MIR consts.consts.built.after.mir +#[custom_mir(dialect = "built")] +fn consts<const C: u32>() { + mir!({ + let _a = 5_u8; + let _b = const { 5_i8 }; + let _c = C; + let _d = D; + let _e = consts::<10>; + Return() + }) +} + +static S: i32 = 0x05050505; +static mut T: i32 = 0x0a0a0a0a; +// EMIT_MIR consts.statics.built.after.mir +#[custom_mir(dialect = "built")] +fn statics() { + mir!({ + let _a: &i32 = Static(S); + let _b: *mut i32 = StaticMut(T); + Return() + }) +} + +fn main() { + consts::<5>(); + statics(); +} diff --git a/tests/mir-opt/building/custom/consts.statics.built.after.mir b/tests/mir-opt/building/custom/consts.statics.built.after.mir new file mode 100644 index 000000000..bfef976aa --- /dev/null +++ b/tests/mir-opt/building/custom/consts.statics.built.after.mir @@ -0,0 +1,27 @@ +// MIR for `statics` after built + +fn statics() -> () { + let mut _0: (); // return place in scope 0 at $DIR/consts.rs:+0:14: +0:14 + let mut _1: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _1 = const {alloc1: &i32}; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + // mir::Constant + // + span: $DIR/consts.rs:27:31: 27:32 + // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) } + _2 = const {alloc2: *mut i32}; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + // mir::Constant + // + span: $DIR/consts.rs:28:38: 28:39 + // + literal: Const { ty: *mut i32, val: Value(Scalar(alloc2)) } + return; // scope 0 at $DIR/consts.rs:+4:9: +4:17 + } +} + +alloc2 (static: T, size: 4, align: 4) { + 0a 0a 0a 0a │ .... +} + +alloc1 (static: S, size: 4, align: 4) { + 05 05 05 05 │ .... +} diff --git a/tests/mir-opt/building/custom/enums.rs b/tests/mir-opt/building/custom/enums.rs new file mode 100644 index 000000000..e5cd45637 --- /dev/null +++ b/tests/mir-opt/building/custom/enums.rs @@ -0,0 +1,120 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + +// EMIT_MIR enums.switch_bool.built.after.mir +#[custom_mir(dialect = "built")] +pub fn switch_bool(b: bool) -> u32 { + mir!( + { + match b { + true => t, + false => f, + _ => f, + } + } + + t = { + RET = 5; + Return() + } + + f = { + RET = 10; + Return() + } + ) +} + +// EMIT_MIR enums.switch_option.built.after.mir +#[custom_mir(dialect = "built")] +pub fn switch_option(option: Option<()>) -> bool { + mir!( + { + let discr = Discriminant(option); + match discr { + 0 => n, + 1 => s, + _ => s, + } + } + + n = { + RET = false; + Return() + } + + s = { + RET = true; + Return() + } + ) +} + +#[repr(u8)] +enum Bool { + False = 0, + True = 1, +} + +// EMIT_MIR enums.switch_option_repr.built.after.mir +#[custom_mir(dialect = "built")] +fn switch_option_repr(option: Bool) -> bool { + mir!( + { + let discr = Discriminant(option); + match discr { + 0 => f, + _ => t, + } + } + + t = { + RET = true; + Return() + } + + f = { + RET = false; + Return() + } + ) +} + +// EMIT_MIR enums.set_discr.built.after.mir +#[custom_mir(dialect = "runtime", phase = "initial")] +fn set_discr(option: &mut Option<()>) { + mir!({ + SetDiscriminant(*option, 0); + Return() + }) +} + +// EMIT_MIR enums.set_discr_repr.built.after.mir +#[custom_mir(dialect = "runtime", phase = "initial")] +fn set_discr_repr(b: &mut Bool) { + mir!({ + SetDiscriminant(*b, 0); + Return() + }) +} + +fn main() { + assert_eq!(switch_bool(true), 5); + assert_eq!(switch_bool(false), 10); + + assert_eq!(switch_option(Some(())), true); + assert_eq!(switch_option(None), false); + + assert_eq!(switch_option_repr(Bool::True), true); + assert_eq!(switch_option_repr(Bool::False), false); + + let mut opt = Some(()); + set_discr(&mut opt); + assert_eq!(opt, None); + + let mut b = Bool::True; + set_discr_repr(&mut b); + assert!(matches!(b, Bool::False)); +} diff --git a/tests/mir-opt/building/custom/enums.set_discr.built.after.mir b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir new file mode 100644 index 000000000..7de9ed098 --- /dev/null +++ b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `set_discr` after built + +fn set_discr(_1: &mut Option<()>) -> () { + let mut _0: (); // return place in scope 0 at $DIR/enums.rs:+0:39: +0:39 + + bb0: { + discriminant((*_1)) = 0; // scope 0 at $DIR/enums.rs:+2:9: +2:36 + return; // scope 0 at $DIR/enums.rs:+3:9: +3:17 + } +} diff --git a/tests/mir-opt/building/custom/enums.set_discr_repr.built.after.mir b/tests/mir-opt/building/custom/enums.set_discr_repr.built.after.mir new file mode 100644 index 000000000..6fdc3d0f4 --- /dev/null +++ b/tests/mir-opt/building/custom/enums.set_discr_repr.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `set_discr_repr` after built + +fn set_discr_repr(_1: &mut Bool) -> () { + let mut _0: (); // return place in scope 0 at $DIR/enums.rs:+0:33: +0:33 + + bb0: { + discriminant((*_1)) = 0; // scope 0 at $DIR/enums.rs:+2:9: +2:31 + return; // scope 0 at $DIR/enums.rs:+3:9: +3:17 + } +} diff --git a/tests/mir-opt/building/custom/enums.switch_bool.built.after.mir b/tests/mir-opt/building/custom/enums.switch_bool.built.after.mir new file mode 100644 index 000000000..95c57d2dc --- /dev/null +++ b/tests/mir-opt/building/custom/enums.switch_bool.built.after.mir @@ -0,0 +1,19 @@ +// MIR for `switch_bool` after built + +fn switch_bool(_1: bool) -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/enums.rs:+0:32: +0:35 + + bb0: { + switchInt(_1) -> [1: bb1, 0: bb2, otherwise: bb2]; // scope 0 at $DIR/enums.rs:+3:13: +7:14 + } + + bb1: { + _0 = const 5_u32; // scope 0 at $DIR/enums.rs:+11:13: +11:20 + return; // scope 0 at $DIR/enums.rs:+12:13: +12:21 + } + + bb2: { + _0 = const 10_u32; // scope 0 at $DIR/enums.rs:+16:13: +16:21 + return; // scope 0 at $DIR/enums.rs:+17:13: +17:21 + } +} diff --git a/tests/mir-opt/building/custom/enums.switch_option.built.after.mir b/tests/mir-opt/building/custom/enums.switch_option.built.after.mir new file mode 100644 index 000000000..a659ba7c1 --- /dev/null +++ b/tests/mir-opt/building/custom/enums.switch_option.built.after.mir @@ -0,0 +1,21 @@ +// MIR for `switch_option` after built + +fn switch_option(_1: Option<()>) -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/enums.rs:+0:45: +0:49 + let mut _2: isize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = discriminant(_1); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + switchInt(_2) -> [0: bb1, 1: bb2, otherwise: bb2]; // scope 0 at $DIR/enums.rs:+4:13: +8:14 + } + + bb1: { + _0 = const false; // scope 0 at $DIR/enums.rs:+12:13: +12:24 + return; // scope 0 at $DIR/enums.rs:+13:13: +13:21 + } + + bb2: { + _0 = const true; // scope 0 at $DIR/enums.rs:+17:13: +17:23 + return; // scope 0 at $DIR/enums.rs:+18:13: +18:21 + } +} diff --git a/tests/mir-opt/building/custom/enums.switch_option_repr.built.after.mir b/tests/mir-opt/building/custom/enums.switch_option_repr.built.after.mir new file mode 100644 index 000000000..d60e4b1b7 --- /dev/null +++ b/tests/mir-opt/building/custom/enums.switch_option_repr.built.after.mir @@ -0,0 +1,21 @@ +// MIR for `switch_option_repr` after built + +fn switch_option_repr(_1: Bool) -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/enums.rs:+0:40: +0:44 + let mut _2: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = discriminant(_1); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + switchInt(_2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/enums.rs:+4:13: +7:14 + } + + bb1: { + _0 = const true; // scope 0 at $DIR/enums.rs:+11:13: +11:23 + return; // scope 0 at $DIR/enums.rs:+12:13: +12:21 + } + + bb2: { + _0 = const false; // scope 0 at $DIR/enums.rs:+16:13: +16:24 + return; // scope 0 at $DIR/enums.rs:+17:13: +17:21 + } +} diff --git a/tests/mir-opt/building/custom/projections.rs b/tests/mir-opt/building/custom/projections.rs new file mode 100644 index 000000000..5e472e531 --- /dev/null +++ b/tests/mir-opt/building/custom/projections.rs @@ -0,0 +1,85 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + +union U { + a: i32, + b: u32, +} + +// EMIT_MIR projections.unions.built.after.mir +#[custom_mir(dialect = "built")] +fn unions(u: U) -> i32 { + mir!({ + RET = u.a; + Return() + }) +} + +// EMIT_MIR projections.tuples.built.after.mir +#[custom_mir(dialect = "analysis", phase = "post-cleanup")] +fn tuples(i: (u32, i32)) -> (u32, i32) { + mir!( + // FIXME(JakobDegen): This is necessary because we can't give type hints for `RET` + let temp: (u32, i32); + { + temp.0 = i.0; + temp.1 = i.1; + + RET = temp; + Return() + } + ) +} + +// EMIT_MIR projections.unwrap.built.after.mir +#[custom_mir(dialect = "built")] +fn unwrap(opt: Option<i32>) -> i32 { + mir!({ + RET = Field(Variant(opt, 1), 0); + Return() + }) +} + +// EMIT_MIR projections.unwrap_deref.built.after.mir +#[custom_mir(dialect = "built")] +fn unwrap_deref(opt: Option<&i32>) -> i32 { + mir!({ + RET = *Field::<&i32>(Variant(opt, 1), 0); + Return() + }) +} + +// EMIT_MIR projections.set.built.after.mir +#[custom_mir(dialect = "built")] +fn set(opt: &mut Option<i32>) { + mir!({ + place!(Field(Variant(*opt, 1), 0)) = 10; + Return() + }) +} + +// EMIT_MIR projections.simple_index.built.after.mir +#[custom_mir(dialect = "built")] +fn simple_index(a: [i32; 10], b: &[i32]) -> i32 { + mir!({ + let temp = 3; + RET = a[temp]; + RET = (*b)[temp]; + Return() + }) +} + +fn main() { + assert_eq!(unions(U { a: 5 }), 5); + assert_eq!(tuples((5, 6)), (5, 6)); + + assert_eq!(unwrap(Some(5)), 5); + assert_eq!(unwrap_deref(Some(&5)), 5); + let mut o = Some(5); + set(&mut o); + assert_eq!(o, Some(10)); + + assert_eq!(simple_index([0; 10], &[0; 10]), 0); +} diff --git a/tests/mir-opt/building/custom/projections.set.built.after.mir b/tests/mir-opt/building/custom/projections.set.built.after.mir new file mode 100644 index 000000000..2f15176a6 --- /dev/null +++ b/tests/mir-opt/building/custom/projections.set.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `set` after built + +fn set(_1: &mut Option<i32>) -> () { + let mut _0: (); // return place in scope 0 at $DIR/projections.rs:+0:31: +0:31 + + bb0: { + (((*_1) as variant#1).0: i32) = const 10_i32; // scope 0 at $DIR/projections.rs:+2:9: +2:48 + return; // scope 0 at $DIR/projections.rs:+3:9: +3:17 + } +} diff --git a/tests/mir-opt/building/custom/projections.simple_index.built.after.mir b/tests/mir-opt/building/custom/projections.simple_index.built.after.mir new file mode 100644 index 000000000..fc422e4b3 --- /dev/null +++ b/tests/mir-opt/building/custom/projections.simple_index.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `simple_index` after built + +fn simple_index(_1: [i32; 10], _2: &[i32]) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:45: +0:48 + let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _3 = const 3_usize; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _0 = _1[_3]; // scope 0 at $DIR/projections.rs:+3:9: +3:22 + _0 = (*_2)[_3]; // scope 0 at $DIR/projections.rs:+4:9: +4:25 + return; // scope 0 at $DIR/projections.rs:+5:9: +5:17 + } +} diff --git a/tests/mir-opt/building/custom/projections.tuples.built.after.mir b/tests/mir-opt/building/custom/projections.tuples.built.after.mir new file mode 100644 index 000000000..65487d3c9 --- /dev/null +++ b/tests/mir-opt/building/custom/projections.tuples.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `tuples` after built + +fn tuples(_1: (u32, i32)) -> (u32, i32) { + let mut _0: (u32, i32); // return place in scope 0 at $DIR/projections.rs:+0:29: +0:39 + let mut _2: (u32, i32); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + (_2.0: u32) = (_1.0: u32); // scope 0 at $DIR/projections.rs:+5:13: +5:25 + (_2.1: i32) = (_1.1: i32); // scope 0 at $DIR/projections.rs:+6:13: +6:25 + _0 = _2; // scope 0 at $DIR/projections.rs:+8:13: +8:23 + return; // scope 0 at $DIR/projections.rs:+9:13: +9:21 + } +} diff --git a/tests/mir-opt/building/custom/projections.unions.built.after.mir b/tests/mir-opt/building/custom/projections.unions.built.after.mir new file mode 100644 index 000000000..922538a5f --- /dev/null +++ b/tests/mir-opt/building/custom/projections.unions.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `unions` after built + +fn unions(_1: U) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:20: +0:23 + + bb0: { + _0 = (_1.0: i32); // scope 0 at $DIR/projections.rs:+2:9: +2:18 + return; // scope 0 at $DIR/projections.rs:+3:9: +3:17 + } +} diff --git a/tests/mir-opt/building/custom/projections.unwrap.built.after.mir b/tests/mir-opt/building/custom/projections.unwrap.built.after.mir new file mode 100644 index 000000000..75b03a3c3 --- /dev/null +++ b/tests/mir-opt/building/custom/projections.unwrap.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `unwrap` after built + +fn unwrap(_1: Option<i32>) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:32: +0:35 + + bb0: { + _0 = ((_1 as variant#1).0: i32); // scope 0 at $DIR/projections.rs:+2:9: +2:40 + return; // scope 0 at $DIR/projections.rs:+3:9: +3:17 + } +} diff --git a/tests/mir-opt/building/custom/projections.unwrap_deref.built.after.mir b/tests/mir-opt/building/custom/projections.unwrap_deref.built.after.mir new file mode 100644 index 000000000..c6b0f7efa --- /dev/null +++ b/tests/mir-opt/building/custom/projections.unwrap_deref.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `unwrap_deref` after built + +fn unwrap_deref(_1: Option<&i32>) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:39: +0:42 + + bb0: { + _0 = (*((_1 as variant#1).0: &i32)); // scope 0 at $DIR/projections.rs:+2:9: +2:49 + return; // scope 0 at $DIR/projections.rs:+3:9: +3:17 + } +} diff --git a/tests/mir-opt/building/custom/references.immut_ref.built.after.mir b/tests/mir-opt/building/custom/references.immut_ref.built.after.mir new file mode 100644 index 000000000..f5ee11262 --- /dev/null +++ b/tests/mir-opt/building/custom/references.immut_ref.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `immut_ref` after built + +fn immut_ref(_1: &i32) -> &i32 { + let mut _0: &i32; // return place in scope 0 at $DIR/references.rs:+0:30: +0:34 + let mut _2: *const i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = &raw const (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:29 + _0 = &(*_2); // scope 0 at $DIR/references.rs:+6:13: +6:23 + Retag(_0); // scope 0 at $DIR/references.rs:+7:13: +7:23 + return; // scope 0 at $DIR/references.rs:+8:13: +8:21 + } +} diff --git a/tests/mir-opt/building/custom/references.mut_ref.built.after.mir b/tests/mir-opt/building/custom/references.mut_ref.built.after.mir new file mode 100644 index 000000000..8e2ffc33b --- /dev/null +++ b/tests/mir-opt/building/custom/references.mut_ref.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `mut_ref` after built + +fn mut_ref(_1: &mut i32) -> &mut i32 { + let mut _0: &mut i32; // return place in scope 0 at $DIR/references.rs:+0:32: +0:40 + let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = &raw mut (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:33 + _0 = &mut (*_2); // scope 0 at $DIR/references.rs:+6:13: +6:26 + Retag(_0); // scope 0 at $DIR/references.rs:+7:13: +7:23 + return; // scope 0 at $DIR/references.rs:+8:13: +8:21 + } +} diff --git a/tests/mir-opt/building/custom/references.raw_pointer.built.after.mir b/tests/mir-opt/building/custom/references.raw_pointer.built.after.mir new file mode 100644 index 000000000..775e5e3ad --- /dev/null +++ b/tests/mir-opt/building/custom/references.raw_pointer.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `raw_pointer` after built + +fn raw_pointer(_1: *const i32) -> *const i32 { + let mut _0: *const i32; // return place in scope 0 at $DIR/references.rs:+0:38: +0:48 + + bb0: { + _0 = &raw const (*_1); // scope 0 at $DIR/references.rs:+4:9: +4:27 + return; // scope 0 at $DIR/references.rs:+5:9: +5:17 + } +} diff --git a/tests/mir-opt/building/custom/references.rs b/tests/mir-opt/building/custom/references.rs new file mode 100644 index 000000000..a1c896de0 --- /dev/null +++ b/tests/mir-opt/building/custom/references.rs @@ -0,0 +1,55 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; +use core::ptr::{addr_of, addr_of_mut}; + +// EMIT_MIR references.mut_ref.built.after.mir +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub fn mut_ref(x: &mut i32) -> &mut i32 { + mir!( + let t: *mut i32; + + { + t = addr_of_mut!(*x); + RET = &mut *t; + Retag(RET); + Return() + } + ) +} + +// EMIT_MIR references.immut_ref.built.after.mir +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub fn immut_ref(x: &i32) -> &i32 { + mir!( + let t: *const i32; + + { + t = addr_of!(*x); + RET = & *t; + Retag(RET); + Return() + } + ) +} + +// EMIT_MIR references.raw_pointer.built.after.mir +#[custom_mir(dialect = "built")] +pub fn raw_pointer(x: *const i32) -> *const i32 { + // Regression test for a bug in which unsafetyck was not correctly turned off for + // `dialect = "built"` + mir!({ + RET = addr_of!(*x); + Return() + }) +} + +fn main() { + let mut x = 5; + assert_eq!(*mut_ref(&mut x), 5); + assert_eq!(*immut_ref(&x), 5); + unsafe { + assert_eq!(*raw_pointer(addr_of!(x)), 5); + } +} diff --git a/tests/mir-opt/building/custom/simple_assign.rs b/tests/mir-opt/building/custom/simple_assign.rs new file mode 100644 index 000000000..db041aab2 --- /dev/null +++ b/tests/mir-opt/building/custom/simple_assign.rs @@ -0,0 +1,39 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + +// EMIT_MIR simple_assign.simple.built.after.mir +#[custom_mir(dialect = "built")] +pub fn simple(x: i32) -> i32 { + mir!( + let temp1: i32; + let temp2: _; + + { + StorageLive(temp1); + temp1 = x; + Goto(exit) + } + + exit = { + temp2 = Move(temp1); + StorageDead(temp1); + RET = temp2; + Return() + } + ) +} + +// EMIT_MIR simple_assign.simple_ref.built.after.mir +#[custom_mir(dialect = "built")] +pub fn simple_ref(x: &mut i32) -> &mut i32 { + mir!({ + RET = Move(x); + Return() + }) +} + +fn main() { + assert_eq!(5, simple(5)); +} diff --git a/tests/mir-opt/building/custom/simple_assign.simple.built.after.mir b/tests/mir-opt/building/custom/simple_assign.simple.built.after.mir new file mode 100644 index 000000000..743016708 --- /dev/null +++ b/tests/mir-opt/building/custom/simple_assign.simple.built.after.mir @@ -0,0 +1,20 @@ +// MIR for `simple` after built + +fn simple(_1: i32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:26: +0:29 + let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simple_assign.rs:+6:13: +6:31 + _2 = _1; // scope 0 at $DIR/simple_assign.rs:+7:13: +7:22 + goto -> bb1; // scope 0 at $DIR/simple_assign.rs:+8:13: +8:23 + } + + bb1: { + _3 = move _2; // scope 0 at $DIR/simple_assign.rs:+12:13: +12:32 + StorageDead(_2); // scope 0 at $DIR/simple_assign.rs:+13:13: +13:31 + _0 = _3; // scope 0 at $DIR/simple_assign.rs:+14:13: +14:24 + return; // scope 0 at $DIR/simple_assign.rs:+15:13: +15:21 + } +} diff --git a/tests/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir b/tests/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir new file mode 100644 index 000000000..2b0e8f104 --- /dev/null +++ b/tests/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `simple_ref` after built + +fn simple_ref(_1: &mut i32) -> &mut i32 { + let mut _0: &mut i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:35: +0:43 + + bb0: { + _0 = move _1; // scope 0 at $DIR/simple_assign.rs:+2:9: +2:22 + return; // scope 0 at $DIR/simple_assign.rs:+3:9: +3:17 + } +} diff --git a/tests/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir b/tests/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir new file mode 100644 index 000000000..a1a27226b --- /dev/null +++ b/tests/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir @@ -0,0 +1,17 @@ +// MIR for `assert_nonzero` after built + +fn assert_nonzero(_1: i32) -> () { + let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:27: +0:27 + + bb0: { + switchInt(_1) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/terminators.rs:+3:13: +6:14 + } + + bb1: { + unreachable; // scope 0 at $DIR/terminators.rs:+10:13: +10:26 + } + + bb2: { + return; // scope 0 at $DIR/terminators.rs:+14:13: +14:21 + } +} diff --git a/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir b/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir new file mode 100644 index 000000000..1b2345a96 --- /dev/null +++ b/tests/mir-opt/building/custom/terminators.direct_call.built.after.mir @@ -0,0 +1,16 @@ +// MIR for `direct_call` after built + +fn direct_call(_1: i32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/terminators.rs:+0:27: +0:30 + + bb0: { + _0 = ident::<i32>(_1) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:42 + // mir::Constant + // + span: $DIR/terminators.rs:15:33: 15:38 + // + literal: Const { ty: fn(i32) -> i32 {ident::<i32>}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21 + } +} diff --git a/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir b/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir new file mode 100644 index 000000000..c903e5946 --- /dev/null +++ b/tests/mir-opt/building/custom/terminators.drop_first.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `drop_first` after built + +fn drop_first(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () { + let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:59: +0:59 + + bb0: { + replace(_1 <- move _2) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:49 + } + + bb1: { + return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21 + } +} diff --git a/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir b/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir new file mode 100644 index 000000000..f14246f2d --- /dev/null +++ b/tests/mir-opt/building/custom/terminators.drop_second.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `drop_second` after built + +fn drop_second(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () { + let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:60: +0:60 + + bb0: { + drop(_2) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:30 + } + + bb1: { + return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21 + } +} diff --git a/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir b/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir new file mode 100644 index 000000000..2f1b14069 --- /dev/null +++ b/tests/mir-opt/building/custom/terminators.indirect_call.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `indirect_call` after built + +fn indirect_call(_1: i32, _2: fn(i32) -> i32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/terminators.rs:+0:48: +0:51 + + bb0: { + _0 = _2(_1) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:38 + } + + bb1: { + return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21 + } +} diff --git a/tests/mir-opt/building/custom/terminators.rs b/tests/mir-opt/building/custom/terminators.rs new file mode 100644 index 000000000..c23233fcf --- /dev/null +++ b/tests/mir-opt/building/custom/terminators.rs @@ -0,0 +1,108 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + +fn ident<T>(t: T) -> T { + t +} + +// EMIT_MIR terminators.direct_call.built.after.mir +#[custom_mir(dialect = "built")] +fn direct_call(x: i32) -> i32 { + mir!( + { + Call(RET, retblock, ident(x)) + } + + retblock = { + Return() + } + ) +} + +// EMIT_MIR terminators.indirect_call.built.after.mir +#[custom_mir(dialect = "built")] +fn indirect_call(x: i32, f: fn(i32) -> i32) -> i32 { + mir!( + { + Call(RET, retblock, f(x)) + } + + retblock = { + Return() + } + ) +} + +struct WriteOnDrop<'a>(&'a mut i32, i32); + +impl<'a> Drop for WriteOnDrop<'a> { + fn drop(&mut self) { + *self.0 = self.1; + } +} + +// EMIT_MIR terminators.drop_first.built.after.mir +#[custom_mir(dialect = "built")] +fn drop_first<'a>(a: WriteOnDrop<'a>, b: WriteOnDrop<'a>) { + mir!( + { + DropAndReplace(a, Move(b), retblock) + } + + retblock = { + Return() + } + ) +} + +// EMIT_MIR terminators.drop_second.built.after.mir +#[custom_mir(dialect = "built")] +fn drop_second<'a>(a: WriteOnDrop<'a>, b: WriteOnDrop<'a>) { + mir!( + { + Drop(b, retblock) + } + + retblock = { + Return() + } + ) +} + +// EMIT_MIR terminators.assert_nonzero.built.after.mir +#[custom_mir(dialect = "built")] +fn assert_nonzero(a: i32) { + mir!( + { + match a { + 0 => unreachable, + _ => retblock + } + } + + unreachable = { + Unreachable() + } + + retblock = { + Return() + } + ) +} + +fn main() { + assert_eq!(direct_call(5), 5); + assert_eq!(indirect_call(5, ident), 5); + + let mut a = 0; + let mut b = 0; + drop_first(WriteOnDrop(&mut a, 1), WriteOnDrop(&mut b, 1)); + assert_eq!((a, b), (1, 0)); + + let mut a = 0; + let mut b = 0; + drop_second(WriteOnDrop(&mut a, 1), WriteOnDrop(&mut b, 1)); + assert_eq!((a, b), (0, 1)); +} diff --git a/tests/mir-opt/building/enum_cast.bar.built.after.mir b/tests/mir-opt/building/enum_cast.bar.built.after.mir new file mode 100644 index 000000000..0746e0b49 --- /dev/null +++ b/tests/mir-opt/building/enum_cast.bar.built.after.mir @@ -0,0 +1,23 @@ +// MIR for `bar` after built + +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 _2: Bar; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _4: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + let mut _5: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _4 = Ge(const 1_isize, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + assume(_4); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _5 = Le(const 0_isize, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + assume(_5); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 + return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/building/enum_cast.boo.built.after.mir b/tests/mir-opt/building/enum_cast.boo.built.after.mir new file mode 100644 index 000000000..699c876b0 --- /dev/null +++ b/tests/mir-opt/building/enum_cast.boo.built.after.mir @@ -0,0 +1,23 @@ +// MIR for `boo` after built + +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 _2: Boo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _4: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + let mut _5: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _4 = Ge(const 1_u8, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + assume(_4); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _5 = Le(const 0_u8, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + assume(_5); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 + return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/building/enum_cast.droppy.built.after.mir b/tests/mir-opt/building/enum_cast.droppy.built.after.mir new file mode 100644 index 000000000..5231c2eab --- /dev/null +++ b/tests/mir-opt/building/enum_cast.droppy.built.after.mir @@ -0,0 +1,72 @@ +// MIR for `droppy` after built + +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 _4: Droppy; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 + let mut _5: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 + let mut _6: bool; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27 + let mut _7: bool; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27 + let _8: 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 => _8; // 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 + StorageLive(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18 + _4 = move _2; // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18 + _5 = discriminant(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + _6 = Ge(const 2_isize, _5); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + assume(_6); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + _7 = Le(const 0_isize, _5); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + assume(_7); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + _3 = move _5 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27 + } + + bb1: { + StorageDead(_4); // scope 3 at $DIR/enum_cast.rs:+5:26: +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: bb2, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + } + + bb2: { + 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(_8); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + _8 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22 + FakeRead(ForLet(None), _8); // 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(_8) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 + } + + bb3: { + StorageDead(_8); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 + return; // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2 + } + + bb4 (cleanup): { + drop(_2) -> bb5; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2 + } +} diff --git a/tests/mir-opt/building/enum_cast.foo.built.after.mir b/tests/mir-opt/building/enum_cast.foo.built.after.mir new file mode 100644 index 000000000..17e0abf2e --- /dev/null +++ b/tests/mir-opt/building/enum_cast.foo.built.after.mir @@ -0,0 +1,17 @@ +// MIR for `foo` after built + +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 _2: Foo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 + return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/building/enum_cast.rs b/tests/mir-opt/building/enum_cast.rs new file mode 100644 index 000000000..98fd5acfb --- /dev/null +++ b/tests/mir-opt/building/enum_cast.rs @@ -0,0 +1,50 @@ +// EMIT_MIR enum_cast.foo.built.after.mir +// EMIT_MIR enum_cast.bar.built.after.mir +// EMIT_MIR enum_cast.boo.built.after.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.built.after.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/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir new file mode 100644 index 000000000..628a33f10 --- /dev/null +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -0,0 +1,75 @@ +// MIR for `main` after built + +| User Type Annotations +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8> +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8> +| +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_101867.rs:+0:11: +0:11 + let _1: std::option::Option<u8> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue_101867.rs:+1:9: +1:10 + let mut _2: !; // in scope 0 at $DIR/issue_101867.rs:+2:26: +4:6 + let _3: (); // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL + let mut _6: isize; // in scope 0 at $DIR/issue_101867.rs:+2:9: +2:16 + scope 1 { + debug x => _1; // in scope 1 at $DIR/issue_101867.rs:+1:9: +1:10 + let _5: u8; // in scope 1 at $DIR/issue_101867.rs:+2:14: +2:15 + scope 2 { + debug y => _5; // in scope 2 at $DIR/issue_101867.rs:+2:14: +2:15 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue_101867.rs:+1:9: +1:10 + _1 = Option::<u8>::Some(const 1_u8); // scope 0 at $DIR/issue_101867.rs:+1:25: +1:32 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue_101867.rs:+1:9: +1:10 + AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue_101867.rs:+1:12: +1:22 + StorageLive(_5); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15 + FakeRead(ForMatchedPlace(None), _1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20 + _6 = discriminant(_1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20 + switchInt(move _6) -> [1: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16 + } + + bb1: { + StorageLive(_3); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL + StorageLive(_4); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL + _4 = begin_panic::<&str>(const "explicit panic") -> bb7; // scope 1 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: { + StorageDead(_4); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL + StorageDead(_3); // scope 1 at $DIR/issue_101867.rs:+3:16: +3:17 + unreachable; // scope 1 at $DIR/issue_101867.rs:+2:26: +4:6 + } + + bb3: { + goto -> bb6; // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20 + } + + bb4: { + falseEdge -> [real: bb5, imaginary: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16 + } + + bb5: { + _5 = ((_1 as Some).0: u8); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15 + _0 = const (); // scope 0 at $DIR/issue_101867.rs:+0:11: +5:2 + StorageDead(_5); // scope 1 at $DIR/issue_101867.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/issue_101867.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue_101867.rs:+5:2: +5:2 + } + + bb6: { + StorageDead(_5); // scope 1 at $DIR/issue_101867.rs:+5:1: +5:2 + goto -> bb1; // scope 0 at $DIR/issue_101867.rs:+0:11: +5:2 + } + + bb7 (cleanup): { + resume; // scope 0 at $DIR/issue_101867.rs:+0:1: +5:2 + } +} diff --git a/tests/mir-opt/building/issue_101867.rs b/tests/mir-opt/building/issue_101867.rs new file mode 100644 index 000000000..a32d8cb37 --- /dev/null +++ b/tests/mir-opt/building/issue_101867.rs @@ -0,0 +1,7 @@ +// EMIT_MIR issue_101867.main.built.after.mir +fn main() { + let x: Option<u8> = Some(1); + let Some(y) = x else { + panic!(); + }; +} diff --git a/tests/mir-opt/building/issue_49232.main.built.after.mir b/tests/mir-opt/building/issue_49232.main.built.after.mir new file mode 100644 index 000000000..de5e4c0f6 --- /dev/null +++ b/tests/mir-opt/building/issue_49232.main.built.after.mir @@ -0,0 +1,82 @@ +// MIR for `main` after built + +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) -> [0: 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/tests/mir-opt/building/issue_49232.rs b/tests/mir-opt/building/issue_49232.rs new file mode 100644 index 000000000..7e9f0de81 --- /dev/null +++ b/tests/mir-opt/building/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.built.after.mir +fn main() { + loop { + let beacon = { + match true { + false => 4, + true => break, + } + }; + drop(&beacon); + } +} diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir new file mode 100644 index 000000000..cb36bc64d --- /dev/null +++ b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir @@ -0,0 +1,112 @@ +// MIR for `full_tested_match` after built + +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 + 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: bb1, 1: 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 -> bb11; // 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: bb10, 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 + _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: bb12]; // 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) -> [0: 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 -> bb11; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + } + + bb8: { + goto -> bb9; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + } + + bb9: { + 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 + } + + bb10: { + 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 -> bb11; // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26 + } + + bb11: { + 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 + } + + bb12 (cleanup): { + resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2 + } +} diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir new file mode 100644 index 000000000..7f8755faa --- /dev/null +++ b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir @@ -0,0 +1,112 @@ +// MIR for `full_tested_match2` after built + +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: bb1, 1: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27 + } + + bb1: { + falseEdge -> [real: bb10, 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 -> bb11; // 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: bb12]; // 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) -> [0: 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 -> bb11; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37 + } + + bb8: { + goto -> bb9; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + } + + bb9: { + 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 + } + + bb10: { + _1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23 + goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23 + } + + bb11: { + 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 + } + + bb12 (cleanup): { + resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2 + } +} diff --git a/tests/mir-opt/building/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match_false_edges.main.built.after.mir new file mode 100644 index 000000000..e8b93f437 --- /dev/null +++ b/tests/mir-opt/building/match_false_edges.main.built.after.mir @@ -0,0 +1,174 @@ +// MIR for `main` after built + +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: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 + } + + bb1: { + falseEdge -> [real: bb13, imaginary: bb6]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11 + } + + bb2: { + falseEdge -> [real: bb8, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17 + } + + bb3: { + goto -> bb1; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 + } + + bb4: { + _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 + switchInt(move _3) -> [1: bb6, otherwise: bb5]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 + } + + bb5: { + 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 -> bb19; // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16 + } + + bb6: { + falseEdge -> [real: bb14, imaginary: bb5]; // scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16 + } + + bb7: { + goto -> bb5; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 + } + + bb8: { + 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: bb9, unwind: bb20]; // 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>) } + } + + bb9: { + switchInt(move _8) -> [0: bb11, otherwise: bb10]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + } + + bb10: { + 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 -> bb19; // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33 + } + + bb11: { + goto -> bb12; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + } + + bb12: { + 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: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + } + + bb13: { + 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 -> bb19; // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16 + } + + bb14: { + 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: bb15, unwind: bb20]; // 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>) } + } + + bb15: { + switchInt(move _12) -> [0: bb17, otherwise: bb16]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + } + + bb16: { + 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 -> bb19; // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34 + } + + bb17: { + goto -> bb18; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + } + + bb18: { + 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: bb7, imaginary: bb5]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + } + + bb19: { + 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 + } + + bb20 (cleanup): { + resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +7:2 + } +} diff --git a/tests/mir-opt/building/match_false_edges.rs b/tests/mir-opt/building/match_false_edges.rs new file mode 100644 index 000000000..ddfcc1493 --- /dev/null +++ b/tests/mir-opt/building/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.built.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.built.after.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.built.after.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/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir new file mode 100644 index 000000000..41eb00363 --- /dev/null +++ b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir @@ -0,0 +1,96 @@ +// MIR for `main` after built + +| 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/tests/mir-opt/building/receiver_ptr_mutability.rs b/tests/mir-opt/building/receiver_ptr_mutability.rs new file mode 100644 index 000000000..668530968 --- /dev/null +++ b/tests/mir-opt/building/receiver_ptr_mutability.rs @@ -0,0 +1,20 @@ +// EMIT_MIR receiver_ptr_mutability.main.built.after.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/tests/mir-opt/building/simple_match.match_bool.built.after.mir b/tests/mir-opt/building/simple_match.match_bool.built.after.mir new file mode 100644 index 000000000..aa2fd4632 --- /dev/null +++ b/tests/mir-opt/building/simple_match.match_bool.built.after.mir @@ -0,0 +1,29 @@ +// MIR for `match_bool` after built + +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) -> [0: 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/tests/mir-opt/building/simple_match.rs b/tests/mir-opt/building/simple_match.rs new file mode 100644 index 000000000..0ef97dde6 --- /dev/null +++ b/tests/mir-opt/building/simple_match.rs @@ -0,0 +1,12 @@ +// Test that we don't generate unnecessarily large MIR for very simple matches + + +// EMIT_MIR simple_match.match_bool.built.after.mir +fn match_bool(x: bool) -> usize { + match x { + true => 10, + _ => 20, + } +} + +fn main() {} diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir new file mode 100644 index 000000000..1d3f77e07 --- /dev/null +++ b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir @@ -0,0 +1,203 @@ +// MIR for `XXX` after built + +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: +18:3 + } +} diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.rs b/tests/mir-opt/building/storage_live_dead_in_statics.rs new file mode 100644 index 000000000..79f709148 --- /dev/null +++ b/tests/mir-opt/building/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.built.after.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/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir new file mode 100644 index 000000000..234cd0839 --- /dev/null +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir @@ -0,0 +1,111 @@ +// MIR for `move_out_by_subslice` after built + +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:12 + scope 4 { + debug _y => _12; // in scope 4 at $DIR/uniform_array_move_out.rs:+2:10: +2:12 + } + } + 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:12 + _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12 + _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/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir new file mode 100644 index 000000000..24a189498 --- /dev/null +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir @@ -0,0 +1,111 @@ +// MIR for `move_out_from_end` after built + +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/tests/mir-opt/building/uniform_array_move_out.rs b/tests/mir-opt/building/uniform_array_move_out.rs new file mode 100644 index 000000000..e925036ec --- /dev/null +++ b/tests/mir-opt/building/uniform_array_move_out.rs @@ -0,0 +1,18 @@ +#![feature(box_syntax)] + +// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.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.built.after.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/tests/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..73f5655a1 --- /dev/null +++ b/tests/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/tests/mir-opt/byte_slice.rs b/tests/mir-opt/byte_slice.rs new file mode 100644 index 000000000..48e9c48c1 --- /dev/null +++ b/tests/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/tests/mir-opt/combine_array_len.norm2.InstCombine.diff b/tests/mir-opt/combine_array_len.norm2.InstCombine.diff new file mode 100644 index 000000000..c73150f94 --- /dev/null +++ b/tests/mir-opt/combine_array_len.norm2.InstCombine.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/tests/mir-opt/combine_array_len.rs b/tests/mir-opt/combine_array_len.rs new file mode 100644 index 000000000..3ef3bd09a --- /dev/null +++ b/tests/mir-opt/combine_array_len.rs @@ -0,0 +1,12 @@ +// unit-test: InstCombine +// 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/tests/mir-opt/combine_clone_of_primitives.rs b/tests/mir-opt/combine_clone_of_primitives.rs new file mode 100644 index 000000000..7cc50a86e --- /dev/null +++ b/tests/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/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff new file mode 100644 index 000000000..6f01553ee --- /dev/null +++ b/tests/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:8:5: 8:9 + let mut _3: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + let _4: &T; // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + let mut _5: u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + let mut _6: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + let _7: &u64; // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + let mut _8: [f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + let mut _9: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + let _10: &[f32; 3]; // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + _4 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 +- _3 = &(*_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 ++ _3 = _4; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + _2 = <T as Clone>::clone(move _3) -> bb1; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + // mir::Constant + // + span: $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + // + literal: Const { ty: for<'a> fn(&'a T) -> T {<T as Clone>::clone}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:8: 8:9 + StorageLive(_5); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + StorageLive(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + StorageLive(_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + _7 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- _6 = &(*_7); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- _5 = <u64 as Clone>::clone(move _6) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- // mir::Constant +- // + span: $DIR/combine_clone_of_primitives.rs:9:5: 9:11 +- // + literal: Const { ty: for<'a> fn(&'a u64) -> u64 {<u64 as Clone>::clone}, val: Value(<ZST>) } ++ _6 = _7; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 ++ _5 = (*_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 ++ goto -> bb2; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + } + + bb2: { + StorageDead(_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:10: 9:11 + StorageLive(_8); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + StorageLive(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + StorageLive(_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + _10 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- _9 = &(*_10); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- // mir::Constant +- // + span: $DIR/combine_clone_of_primitives.rs:10:5: 10:16 +- // + literal: Const { ty: for<'a> fn(&'a [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value(<ZST>) } ++ _9 = _10; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 ++ _8 = (*_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 ++ goto -> bb3; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + } + + bb3: { + StorageDead(_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:15: 10: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/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir new file mode 100644 index 000000000..6140fc52f --- /dev/null +++ b/tests/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:9:5: 9: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 + _0 = const (); // 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/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir new file mode 100644 index 000000000..b2ed23c68 --- /dev/null +++ b/tests/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:9:5: 9: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 + _0 = const (); // 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/tests/mir-opt/const_allocation.rs b/tests/mir-opt/const_allocation.rs new file mode 100644 index 000000000..91a2455eb --- /dev/null +++ b/tests/mir-opt/const_allocation.rs @@ -0,0 +1,10 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir new file mode 100644 index 000000000..aab005c52 --- /dev/null +++ b/tests/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:6:5: 6: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 + _0 = const (); // 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/tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir new file mode 100644 index 000000000..0eff9474c --- /dev/null +++ b/tests/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:6:5: 6: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 + _0 = const (); // 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/tests/mir-opt/const_allocation2.rs b/tests/mir-opt/const_allocation2.rs new file mode 100644 index 000000000..f2870aa47 --- /dev/null +++ b/tests/mir-opt/const_allocation2.rs @@ -0,0 +1,12 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir new file mode 100644 index 000000000..55c6db5d0 --- /dev/null +++ b/tests/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:6:5: 6: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 + _0 = const (); // 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/tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir new file mode 100644 index 000000000..27492a7fd --- /dev/null +++ b/tests/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:6:5: 6: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 + _0 = const (); // 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/tests/mir-opt/const_allocation3.rs b/tests/mir-opt/const_allocation3.rs new file mode 100644 index 000000000..da3fd089b --- /dev/null +++ b/tests/mir-opt/const_allocation3.rs @@ -0,0 +1,30 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff new file mode 100644 index 000000000..dd548adde --- /dev/null +++ b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -0,0 +1,126 @@ +- // 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 _12: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16 + let mut _13: 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 _14: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _15: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _16: u32; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + scope 6 { + debug f => (bool, bool, u32){ .0 => _14, .1 => _15, .2 => _16, }; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _10: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + scope 7 { + debug o => _10; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 + let _17: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _18: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + scope 8 { + debug p => Point{ .0 => _17, .1 => _18, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _11: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + scope 9 { +- debug a => _11; // 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(_14); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + StorageLive(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + StorageLive(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + Deinit(_14); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + Deinit(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + Deinit(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _14 = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _15 = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _16 = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + StorageLive(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + Deinit(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + ((_10 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + discriminant(_10) = 1; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + StorageLive(_17); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + StorageLive(_18); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + Deinit(_17); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + Deinit(_18); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + _17 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + _18 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + StorageLive(_11); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + StorageLive(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 + _12 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 + StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 + _13 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 + _11 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 + StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 + StorageDead(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 + StorageDead(_11); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_17); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_18); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_10); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_14); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_15); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_16); // 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/tests/mir-opt/const_debuginfo.rs b/tests/mir-opt/const_debuginfo.rs new file mode 100644 index 000000000..a188da385 --- /dev/null +++ b/tests/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/tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff b/tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff new file mode 100644 index 000000000..a717d1bbd --- /dev/null +++ b/tests/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: bb2, 2: 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: bb2, 2: 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) -> [0: 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/tests/mir-opt/const_goto.rs b/tests/mir-opt/const_goto.rs new file mode 100644 index 000000000..6f84f186b --- /dev/null +++ b/tests/mir-opt/const_goto.rs @@ -0,0 +1,18 @@ +// unit-test: ConstGoto + +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/tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff b/tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff new file mode 100644 index 000000000..24be8c9b8 --- /dev/null +++ b/tests/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: bb2, 2: bb2, 3: 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) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6 + } + + bb3: { +- switchInt(_1) -> [0: 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/tests/mir-opt/const_goto_const_eval_fail.rs b/tests/mir-opt/const_goto_const_eval_fail.rs new file mode 100644 index 000000000..3b85fe6ab --- /dev/null +++ b/tests/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/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff new file mode 100644 index 000000000..f54577259 --- /dev/null +++ b/tests/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 +- Deinit(_2); // 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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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/tests/mir-opt/const_goto_storage.rs b/tests/mir-opt/const_goto_storage.rs new file mode 100644 index 000000000..459599c73 --- /dev/null +++ b/tests/mir-opt/const_goto_storage.rs @@ -0,0 +1,21 @@ +// unit-test: ConstGoto + +// 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/tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..028480bdc --- /dev/null +++ b/tests/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/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff new file mode 100644 index 000000000..2ef437811 --- /dev/null +++ b/tests/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 _; // 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<'a> fn(&'a [&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:45 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:45 + } +- } +- +- alloc1 (static: Y, size: 4, align: 4) { +- 2a 00 00 00 │ *... + } + diff --git a/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir b/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir new file mode 100644 index 000000000..476fc49a1 --- /dev/null +++ b/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir @@ -0,0 +1,17 @@ +// MIR for `BOP` after built + +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:24 + } +} diff --git a/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..41657b53f --- /dev/null +++ b/tests/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/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff new file mode 100644 index 000000000..25ba0face --- /dev/null +++ b/tests/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 _; // 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<'a> fn(&'a [&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:56 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:56 + } + } +- +- alloc3 (extern static: X) + diff --git a/tests/mir-opt/const_promotion_extern_static.rs b/tests/mir-opt/const_promotion_extern_static.rs new file mode 100644 index 000000000..e4261cfe5 --- /dev/null +++ b/tests/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.built.after.mir +static BOP: &i32 = &13; + +fn main() {} diff --git a/tests/mir-opt/const_prop/aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/aggregate.main.ConstProp.diff new file mode 100644 index 000000000..04378dbf3 --- /dev/null +++ b/tests/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 + _0 = const (); // 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/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir b/tests/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir new file mode 100644 index 000000000..cfc9a72e3 --- /dev/null +++ b/tests/mir-opt/const_prop/aggregate.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/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 = 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 + _0 = const (); // 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/tests/mir-opt/const_prop/aggregate.rs b/tests/mir-opt/const_prop/aggregate.rs new file mode 100644 index 000000000..6a3080384 --- /dev/null +++ b/tests/mir-opt/const_prop/aggregate.rs @@ -0,0 +1,8 @@ +// unit-test: ConstProp +// compile-flags: -O + +// EMIT_MIR aggregate.main.ConstProp.diff +// EMIT_MIR aggregate.main.PreCodegen.after.mir +fn main() { + let x = (0, 1, 2).1 + 0; +} diff --git a/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff new file mode 100644 index 000000000..439b2a3e1 --- /dev/null +++ b/tests/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff @@ -0,0 +1,39 @@ +- // 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 = Len(_2); // 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 ++ _4 = const 4_usize; // 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 {}", move _4, _3) -> 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 + _0 = const (); // 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/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff new file mode 100644 index 000000000..439b2a3e1 --- /dev/null +++ b/tests/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff @@ -0,0 +1,39 @@ +- // 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 = Len(_2); // 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 ++ _4 = const 4_usize; // 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 {}", move _4, _3) -> 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 + _0 = const (); // 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/tests/mir-opt/const_prop/array_index.rs b/tests/mir-opt/const_prop/array_index.rs new file mode 100644 index 000000000..d31c2827b --- /dev/null +++ b/tests/mir-opt/const_prop/array_index.rs @@ -0,0 +1,7 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff new file mode 100644 index 000000000..bea32a67e --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.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/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 ++ _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(!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 + } + + 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, _3) -> 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 + StorageDead(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19 + _0 = const (); // 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/tests/mir-opt/const_prop/bad_op_div_by_zero.rs b/tests/mir-opt/const_prop/bad_op_div_by_zero.rs new file mode 100644 index 000000000..a6fd325ec --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_div_by_zero.rs @@ -0,0 +1,7 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff new file mode 100644 index 000000000..8485703e3 --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_mod_by_zero.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/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 + 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/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs b/tests/mir-opt/const_prop/bad_op_mod_by_zero.rs new file mode 100644 index 000000000..cc16a4a5a --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff new file mode 100644 index 000000000..27e41d486 --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.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_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 _5: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _7: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: &[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 _4: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + scope 3 { + debug _b => _4; // 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 + _8 = const _; // 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 = _8; // 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(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _5 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _7 = Lt(_5, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _7 = Lt(const 3_usize, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + } + + bb1: { + _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + StorageDead(_4); // 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/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff new file mode 100644 index 000000000..27e41d486 --- /dev/null +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.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_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 _5: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _7: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: &[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 _4: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + scope 3 { + debug _b => _4; // 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 + _8 = const _; // 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 = _8; // 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(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _5 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _7 = Lt(_5, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _7 = Lt(const 3_usize, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + } + + bb1: { + _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + StorageDead(_4); // 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/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs new file mode 100644 index 000000000..cf22b06d5 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/boolean_identities.rs b/tests/mir-opt/const_prop/boolean_identities.rs new file mode 100644 index 000000000..c7b609949 --- /dev/null +++ b/tests/mir-opt/const_prop/boolean_identities.rs @@ -0,0 +1,11 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff b/tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff new file mode 100644 index 000000000..0de800917 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/boxes.main.ConstProp.diff b/tests/mir-opt/const_prop/boxes.main.ConstProp.diff new file mode 100644 index 000000000..5ec421eb2 --- /dev/null +++ b/tests/mir-opt/const_prop/boxes.main.ConstProp.diff @@ -0,0 +1,60 @@ +- // 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 + 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 ++ _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(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22 + // mir::Constant + // + span: $DIR/boxes.rs:13:14: 13: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 + _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 + _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 + _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 + _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 + _0 = const (); // 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/tests/mir-opt/const_prop/boxes.rs b/tests/mir-opt/const_prop/boxes.rs new file mode 100644 index 000000000..d287830db --- /dev/null +++ b/tests/mir-opt/const_prop/boxes.rs @@ -0,0 +1,14 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_prop/cast.main.ConstProp.diff b/tests/mir-opt/const_prop/cast.main.ConstProp.diff new file mode 100644 index 000000000..1d4dfc29f --- /dev/null +++ b/tests/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 (IntToInt); // 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 (IntToInt); // scope 1 at $DIR/cast.rs:+3:13: +3:24 ++ _2 = const 42_u8; // scope 1 at $DIR/cast.rs:+3:13: +3:24 + _0 = const (); // 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/tests/mir-opt/const_prop/cast.rs b/tests/mir-opt/const_prop/cast.rs new file mode 100644 index 000000000..984086eda --- /dev/null +++ b/tests/mir-opt/const_prop/cast.rs @@ -0,0 +1,8 @@ +// unit-test: ConstProp +// EMIT_MIR cast.main.ConstProp.diff + +fn main() { + let x = 42u8 as u32; + + let y = 42u32 as u8; +} diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.diff new file mode 100644 index 000000000..96d0d2566 --- /dev/null +++ b/tests/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 + _0 = const (); // 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/tests/mir-opt/const_prop/checked_add.rs b/tests/mir-opt/const_prop/checked_add.rs new file mode 100644 index 000000000..b9860da4c --- /dev/null +++ b/tests/mir-opt/const_prop/checked_add.rs @@ -0,0 +1,7 @@ +// unit-test: ConstProp +// compile-flags: -C overflow-checks=on + +// EMIT_MIR checked_add.main.ConstProp.diff +fn main() { + let x: u32 = 1 + 1; +} diff --git a/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/tests/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff new file mode 100644 index 000000000..bea7114c7 --- /dev/null +++ b/tests/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 _; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + // mir::Constant + // + span: $DIR/const_prop_fails_gracefully.rs:8:13: 8: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:9:5: 9: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 + _0 = const (); // 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/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs b/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs new file mode 100644 index 000000000..0a3dcbd38 --- /dev/null +++ b/tests/mir-opt/const_prop/const_prop_fails_gracefully.rs @@ -0,0 +1,10 @@ +// unit-test: ConstProp +#[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/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff new file mode 100644 index 000000000..f270ab8b6 --- /dev/null +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff @@ -0,0 +1,32 @@ +- // 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 _; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 ++ switchInt(const false) -> [0: 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: { + 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/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir b/tests/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir new file mode 100644 index 000000000..9f7528f0c --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/control_flow_simplification.rs b/tests/mir-opt/const_prop/control_flow_simplification.rs new file mode 100644 index 000000000..7dbe8e734 --- /dev/null +++ b/tests/mir-opt/const_prop/control_flow_simplification.rs @@ -0,0 +1,21 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff new file mode 100644 index 000000000..b4dccecc6 --- /dev/null +++ b/tests/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: 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: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + } + + bb1: { + switchInt(((_3 as Some).0: bool)) -> [0: 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 + _0 = const (); // 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/tests/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff new file mode 100644 index 000000000..b4dccecc6 --- /dev/null +++ b/tests/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: 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: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + } + + bb1: { + switchInt(((_3 as Some).0: bool)) -> [0: 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 + _0 = const (); // 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/tests/mir-opt/const_prop/discriminant.rs b/tests/mir-opt/const_prop/discriminant.rs new file mode 100644 index 000000000..fdd67ca8a --- /dev/null +++ b/tests/mir-opt/const_prop/discriminant.rs @@ -0,0 +1,13 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_prop/indirect.main.ConstProp.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.diff new file mode 100644 index 000000000..f4c0c5c5e --- /dev/null +++ b/tests/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 (IntToInt); // 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", move _2, 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 + _0 = const (); // 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/tests/mir-opt/const_prop/indirect.rs b/tests/mir-opt/const_prop/indirect.rs new file mode 100644 index 000000000..44916cbfe --- /dev/null +++ b/tests/mir-opt/const_prop/indirect.rs @@ -0,0 +1,7 @@ +// unit-test: ConstProp +// compile-flags: -C overflow-checks=on + +// EMIT_MIR indirect.main.ConstProp.diff +fn main() { + let x = (2u32 as u8) + 1; +} diff --git a/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff new file mode 100644 index 000000000..6c4757c1a --- /dev/null +++ b/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff @@ -0,0 +1,66 @@ +- // 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 + 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 _7: main::Str<"���">; // in scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 + scope 7 { + debug _non_utf8_str => _7; // 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 5 at $DIR/invalid_constant.rs:+24:9: +24:22 + StorageDead(_7); // 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/tests/mir-opt/const_prop/invalid_constant.rs b/tests/mir-opt/const_prop/invalid_constant.rs new file mode 100644 index 000000000..0337a7ca8 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.diff new file mode 100644 index 000000000..488e772d0 --- /dev/null +++ b/tests/mir-opt/const_prop/issue_66971.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/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 + + 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 + Deinit(_2); // 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 + _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 + // mir::Constant + // + span: $DIR/issue_66971.rs:17:5: 17: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 + return; // scope 0 at $DIR/issue_66971.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/issue_66971.rs b/tests/mir-opt/const_prop/issue_66971.rs new file mode 100644 index 000000000..6ca03438e --- /dev/null +++ b/tests/mir-opt/const_prop/issue_66971.rs @@ -0,0 +1,18 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.diff new file mode 100644 index 000000000..cd5304859 --- /dev/null +++ b/tests/mir-opt/const_prop/issue_67019.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_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:12:5: 12: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 + return; // scope 0 at $DIR/issue_67019.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/issue_67019.rs b/tests/mir-opt/const_prop/issue_67019.rs new file mode 100644 index 000000000..ffc6fa1f2 --- /dev/null +++ b/tests/mir-opt/const_prop/issue_67019.rs @@ -0,0 +1,13 @@ +// unit-test: ConstProp +// 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/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff new file mode 100644 index 000000000..5331e5b82 --- /dev/null +++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.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/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 + 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/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff new file mode 100644 index 000000000..5331e5b82 --- /dev/null +++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.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/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 + 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/tests/mir-opt/const_prop/large_array_index.rs b/tests/mir-opt/const_prop/large_array_index.rs new file mode 100644 index 000000000..48d134376 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/mult_by_zero.rs b/tests/mir-opt/const_prop/mult_by_zero.rs new file mode 100644 index 000000000..c839f92f2 --- /dev/null +++ b/tests/mir-opt/const_prop/mult_by_zero.rs @@ -0,0 +1,11 @@ +// unit-test +// 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/tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff b/tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff new file mode 100644 index 000000000..629c8e601 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/mutable_variable.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable.main.ConstProp.diff new file mode 100644 index 000000000..a672c457a --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable.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/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 + 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/tests/mir-opt/const_prop/mutable_variable.rs b/tests/mir-opt/const_prop/mutable_variable.rs new file mode 100644 index 000000000..cb01719dd --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable.rs @@ -0,0 +1,9 @@ +// unit-test +// compile-flags: -O + +// EMIT_MIR mutable_variable.main.ConstProp.diff +fn main() { + let mut x = 42; + x = 99; + let y = x; +} diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff new file mode 100644 index 000000000..f6bf52206 --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.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/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 + 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/tests/mir-opt/const_prop/mutable_variable_aggregate.rs b/tests/mir-opt/const_prop/mutable_variable_aggregate.rs new file mode 100644 index 000000000..d4ff8d890 --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.rs @@ -0,0 +1,9 @@ +// unit-test +// 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/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff new file mode 100644 index 000000000..213a70227 --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.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_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 + 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/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs new file mode 100644 index 000000000..9060f7e9b --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs @@ -0,0 +1,10 @@ +// unit-test +// 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/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff new file mode 100644 index 000000000..149aa6290 --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.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/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:6:29: 6: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 + 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/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs new file mode 100644 index 000000000..cb59509ff --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs @@ -0,0 +1,15 @@ +// unit-test +// 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/tests/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff new file mode 100644 index 000000000..7fa29cccd --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.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/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 mut _2: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + let mut _3: *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 _4: u32; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 + scope 2 { + } + scope 3 { + debug y => _4; // 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 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + _3 = 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:10:13: 10:19 + // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) } + _2 = (*_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + _1 = move _2; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19 + StorageDead(_2); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:18: +3:19 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:19: +3:20 + StorageLive(_4); // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 + _4 = _1; // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:13: +5:14 + StorageDead(_4); // 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) { + 42 42 42 42 │ BBBB + } + diff --git a/tests/mir-opt/const_prop/mutable_variable_no_prop.rs b/tests/mir-opt/const_prop/mutable_variable_no_prop.rs new file mode 100644 index 000000000..b69ec931a --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_no_prop.rs @@ -0,0 +1,13 @@ +// unit-test +// compile-flags: -O + +static mut STATIC: u32 = 0x42424242; + +// EMIT_MIR mutable_variable_no_prop.main.ConstProp.diff +fn main() { + let mut x = 42; + unsafe { + x = STATIC; + } + let y = x; +} diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff new file mode 100644 index 000000000..c3f77b960 --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff @@ -0,0 +1,57 @@ +- // 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 _2: 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 _5: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let mut _6: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + scope 2 { + debug x => (i32, i32){ .0 => _5, .1 => _6, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let _3: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + scope 3 { + debug y => _3; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + let _4: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + scope 4 { + debug z => _4; // 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:6:13: 6:16 + // + literal: Const { ty: fn() -> i32 {foo}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + StorageLive(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + Deinit(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + Deinit(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + _5 = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + _6 = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + StorageLive(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + _2 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + _6 = move _2; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 + StorageDead(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + _3 = _6; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 + StorageLive(_4); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 +- _4 = _5; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 ++ _4 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 + StorageDead(_4); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_6); // 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/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs new file mode 100644 index 000000000..b077cfd3e --- /dev/null +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.rs @@ -0,0 +1,16 @@ +// unit-test +// 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/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff new file mode 100644 index 000000000..7c7aeac4c --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff @@ -0,0 +1,66 @@ +- // 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: u32; // 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 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = _9; // 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 + 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/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff new file mode 100644 index 000000000..7c7aeac4c --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff @@ -0,0 +1,66 @@ +- // 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: u32; // 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 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = _9; // 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 + 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/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir new file mode 100644 index 000000000..9db87cfc8 --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir @@ -0,0 +1,27 @@ +// MIR for `main` after PreCodegen + +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/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir new file mode 100644 index 000000000..9db87cfc8 --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir @@ -0,0 +1,27 @@ +// MIR for `main` after PreCodegen + +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/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff new file mode 100644 index 000000000..3f9f3b2ea --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff @@ -0,0 +1,72 @@ +- // MIR for `main` before ScalarReplacementOfAggregates ++ // MIR for `main` after ScalarReplacementOfAggregates + + 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 ++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _11: u32; // 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 + } + + bb1: { + _1 = move (_2.0: 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 = Len(_4); // 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 + } + + bb2: { + _3 = _4[_5]; // 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 +- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageDead(_11); // 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/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff new file mode 100644 index 000000000..3f9f3b2ea --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff @@ -0,0 +1,72 @@ +- // MIR for `main` before ScalarReplacementOfAggregates ++ // MIR for `main` after ScalarReplacementOfAggregates + + 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 ++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _11: u32; // 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 + } + + bb1: { + _1 = move (_2.0: 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 = Len(_4); // 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 + } + + bb2: { + _3 = _4[_5]; // 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 +- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageDead(_11); // 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/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir new file mode 100644 index 000000000..d926b9df7 --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir @@ -0,0 +1,27 @@ +// MIR for `main` after SimplifyLocals-final + +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/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir new file mode 100644 index 000000000..d926b9df7 --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir @@ -0,0 +1,27 @@ +// MIR for `main` after SimplifyLocals-final + +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/tests/mir-opt/const_prop/optimizes_into_variable.rs b/tests/mir-opt/const_prop/optimizes_into_variable.rs new file mode 100644 index 000000000..abea07e20 --- /dev/null +++ b/tests/mir-opt/const_prop/optimizes_into_variable.rs @@ -0,0 +1,18 @@ +// unit-test +// compile-flags: -C overflow-checks=on + +struct Point { + x: u32, + y: u32, +} + +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// EMIT_MIR optimizes_into_variable.main.ScalarReplacementOfAggregates.diff +// EMIT_MIR optimizes_into_variable.main.ConstProp.diff +// EMIT_MIR optimizes_into_variable.main.SimplifyLocals-final.after.mir +// EMIT_MIR optimizes_into_variable.main.PreCodegen.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/tests/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/tests/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff new file mode 100644 index 000000000..388c6ca81 --- /dev/null +++ b/tests/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff @@ -0,0 +1,47 @@ +- // 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:8:13: 8: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:8:19: 8: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 + 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/tests/mir-opt/const_prop/read_immutable_static.rs b/tests/mir-opt/const_prop/read_immutable_static.rs new file mode 100644 index 000000000..4f7afe6ca --- /dev/null +++ b/tests/mir-opt/const_prop/read_immutable_static.rs @@ -0,0 +1,9 @@ +// unit-test +// compile-flags: -O + +static FOO: u8 = 2; + +// EMIT_MIR read_immutable_static.main.ConstProp.diff +fn main() { + let x = FOO + FOO; +} diff --git a/tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff new file mode 100644 index 000000000..8a73f0390 --- /dev/null +++ b/tests/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 _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + // mir::Constant + // + span: $DIR/ref_deref.rs:6:6: 6: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/tests/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/tests/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff new file mode 100644 index 000000000..015ec4d07 --- /dev/null +++ b/tests/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 _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 ++ // mir::Constant ++ // + span: $DIR/ref_deref.rs:6:6: 6: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/tests/mir-opt/const_prop/ref_deref.rs b/tests/mir-opt/const_prop/ref_deref.rs new file mode 100644 index 000000000..d2549c8b6 --- /dev/null +++ b/tests/mir-opt/const_prop/ref_deref.rs @@ -0,0 +1,7 @@ +// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop +// EMIT_MIR ref_deref.main.PromoteTemps.diff +// EMIT_MIR ref_deref.main.ConstProp.diff + +fn main() { + *(&4); +} diff --git a/tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff new file mode 100644 index 000000000..ec3d90433 --- /dev/null +++ b/tests/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 _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + // mir::Constant + // + span: $DIR/ref_deref_project.rs:6:6: 6: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/tests/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/tests/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff new file mode 100644 index 000000000..cd0616e65 --- /dev/null +++ b/tests/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 _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 ++ // mir::Constant ++ // + span: $DIR/ref_deref_project.rs:6:6: 6: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/tests/mir-opt/const_prop/ref_deref_project.rs b/tests/mir-opt/const_prop/ref_deref_project.rs new file mode 100644 index 000000000..2fdd4e153 --- /dev/null +++ b/tests/mir-opt/const_prop/ref_deref_project.rs @@ -0,0 +1,7 @@ +// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop +// 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/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff new file mode 100644 index 000000000..15c93f270 --- /dev/null +++ b/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff @@ -0,0 +1,24 @@ +- // 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: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + let mut _2: 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:26 + StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + _2 = 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>) } + _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26 + StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41 + return; // scope 0 at $DIR/reify_fn_ptr.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.rs b/tests/mir-opt/const_prop/reify_fn_ptr.rs new file mode 100644 index 000000000..bfe2563ad --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff new file mode 100644 index 000000000..636032adb --- /dev/null +++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff @@ -0,0 +1,42 @@ +- // 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 + 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/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff new file mode 100644 index 000000000..636032adb --- /dev/null +++ b/tests/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff @@ -0,0 +1,42 @@ +- // 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 + 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/tests/mir-opt/const_prop/repeat.rs b/tests/mir-opt/const_prop/repeat.rs new file mode 100644 index 000000000..36d9b9fc6 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/return_place.add.ConstProp.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.diff new file mode 100644 index 000000000..5ebd8a520 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.mir new file mode 100644 index 000000000..ececd9942 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/return_place.rs b/tests/mir-opt/const_prop/return_place.rs new file mode 100644 index 000000000..06a853696 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff new file mode 100644 index 000000000..d518eff04 --- /dev/null +++ b/tests/mir-opt/const_prop/scalar_literal_propagation.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/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 + 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/tests/mir-opt/const_prop/scalar_literal_propagation.rs b/tests/mir-opt/const_prop/scalar_literal_propagation.rs new file mode 100644 index 000000000..8724e4d57 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff new file mode 100644 index 000000000..9017fd18e --- /dev/null +++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff @@ -0,0 +1,50 @@ +- // 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 + + 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 _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + // mir::Constant + // + span: $DIR/slice_len.rs:6:6: 6: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 + _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 = Len((*_2)); // 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 ++ _7 = const 3_usize; // 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/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff new file mode 100644 index 000000000..9017fd18e --- /dev/null +++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff @@ -0,0 +1,50 @@ +- // 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 + + 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 _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + // mir::Constant + // + span: $DIR/slice_len.rs:6:6: 6: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 + _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 = Len((*_2)); // 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 ++ _7 = const 3_usize; // 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/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs new file mode 100644 index 000000000..eaaf34b96 --- /dev/null +++ b/tests/mir-opt/const_prop/slice_len.rs @@ -0,0 +1,7 @@ +// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +// EMIT_MIR slice_len.main.ConstProp.diff +fn main() { + (&[1u32, 2, 3] as &[u32])[1]; +} diff --git a/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff b/tests/mir-opt/const_prop/switch_int.main.ConstProp.diff new file mode 100644 index 000000000..ddc1a4493 --- /dev/null +++ b/tests/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: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 ++ switchInt(const 1_i32) -> [1: 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/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff b/tests/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff new file mode 100644 index 000000000..09c47ee6e --- /dev/null +++ b/tests/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: 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/tests/mir-opt/const_prop/switch_int.rs b/tests/mir-opt/const_prop/switch_int.rs new file mode 100644 index 000000000..d7319eca1 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff new file mode 100644 index 000000000..e4c92b617 --- /dev/null +++ b/tests/mir-opt/const_prop/tuple_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/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 + 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/tests/mir-opt/const_prop/tuple_literal_propagation.rs b/tests/mir-opt/const_prop/tuple_literal_propagation.rs new file mode 100644 index 000000000..e644baec4 --- /dev/null +++ b/tests/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/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff new file mode 100644 index 000000000..ea9fec0aa --- /dev/null +++ b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff @@ -0,0 +1,37 @@ +- // 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 mut _2: *mut i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + let mut _4: 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 _3: bool; // in scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 + scope 2 { + } + scope 3 { + debug y => _3; // 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 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + _2 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + (*_2) = const 5_i32; // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26 + StorageDead(_2); // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27 + StorageLive(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 + StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20 + _4 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18 + _3 = Eq(move _4, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25 + StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25 + StorageDead(_3); // 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/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff new file mode 100644 index 000000000..043f40474 --- /dev/null +++ b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff @@ -0,0 +1,35 @@ +- // 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 + 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/tests/mir-opt/const_prop_miscompile.rs b/tests/mir-opt/const_prop_miscompile.rs new file mode 100644 index 000000000..bc54556b3 --- /dev/null +++ b/tests/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/tests/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/tests/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot new file mode 100644 index 000000000..03df5c950 --- /dev/null +++ b/tests/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 align="left"/> 19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2<br align="left"/> 20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>]; +} diff --git a/tests/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/tests/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot new file mode 100644 index 000000000..c4d389b2d --- /dev/null +++ b/tests/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 align="left"/> 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 align="left"/> 12:13-12:18: @4[0]: Coverage::Expression(4294967293) = 4294967294 + 0 for $DIR/coverage_graphviz.rs:15:1 - 15:2<br align="left"/>Expression(bcb2:(bcb1:(bcb0 + bcb3) - bcb3) + 0) at 15:2-15:2<br align="left"/> 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 align="left"/> 11:12-11:17: @2.Call: _2 = bar() -> [return: bb3, unwind: bb6]</td></tr><tr><td align="left" balign="left">bb1: FalseUnwind<br align="left"/>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 align="left"/> </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=<0>]; + bcb1__Cov_0_3 -> bcb2__Cov_0_3 [label=<otherwise>]; + bcb0__Cov_0_3 -> bcb1__Cov_0_3 [label=<>]; +} diff --git a/tests/mir-opt/coverage_graphviz.rs b/tests/mir-opt/coverage_graphviz.rs new file mode 100644 index 000000000..09403bb3a --- /dev/null +++ b/tests/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/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff new file mode 100644 index 000000000..bf9ab8669 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff @@ -0,0 +1,37 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/cast.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/cast.rs:+1:9: +1:10 + let mut _3: u8; // in scope 0 at $DIR/cast.rs:+2:13: +2:20 + let mut _4: i32; // in scope 0 at $DIR/cast.rs:+2:13: +2:14 + scope 1 { + debug a => _1; // in scope 1 at $DIR/cast.rs:+1:9: +1:10 + let _2: u8; // in scope 1 at $DIR/cast.rs:+2:9: +2:10 + scope 2 { + debug b => _2; // in scope 2 at $DIR/cast.rs:+2:9: +2:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/cast.rs:+1:9: +1:10 + _1 = const 257_i32; // scope 0 at $DIR/cast.rs:+1:13: +1:16 + StorageLive(_2); // scope 1 at $DIR/cast.rs:+2:9: +2:10 + StorageLive(_3); // scope 1 at $DIR/cast.rs:+2:13: +2:20 + StorageLive(_4); // scope 1 at $DIR/cast.rs:+2:13: +2:14 +- _4 = _1; // scope 1 at $DIR/cast.rs:+2:13: +2:14 +- _3 = move _4 as u8 (IntToInt); // scope 1 at $DIR/cast.rs:+2:13: +2:20 ++ _4 = const 257_i32; // scope 1 at $DIR/cast.rs:+2:13: +2:14 ++ _3 = const 1_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:20 + StorageDead(_4); // scope 1 at $DIR/cast.rs:+2:19: +2:20 +- _2 = Add(move _3, const 1_u8); // scope 1 at $DIR/cast.rs:+2:13: +2:24 ++ _2 = const 2_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:24 + StorageDead(_3); // scope 1 at $DIR/cast.rs:+2:23: +2:24 + _0 = const (); // scope 0 at $DIR/cast.rs:+0:11: +3:2 + StorageDead(_2); // scope 1 at $DIR/cast.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/cast.rs:+3:1: +3:2 + return; // scope 0 at $DIR/cast.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/cast.rs b/tests/mir-opt/dataflow-const-prop/cast.rs new file mode 100644 index 000000000..484403f7f --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/cast.rs @@ -0,0 +1,7 @@ +// unit-test: DataflowConstProp + +// EMIT_MIR cast.main.DataflowConstProp.diff +fn main() { + let a = 257; + let b = a as u8 + 1; +} diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff new file mode 100644 index 000000000..a4ebd0c8c --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff @@ -0,0 +1,80 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/checked.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/checked.rs:+1:9: +1:10 + let mut _4: i32; // in scope 0 at $DIR/checked.rs:+3:13: +3:14 + let mut _5: i32; // in scope 0 at $DIR/checked.rs:+3:17: +3:18 + let mut _6: (i32, bool); // in scope 0 at $DIR/checked.rs:+3:13: +3:18 + let mut _9: i32; // in scope 0 at $DIR/checked.rs:+6:13: +6:14 + let mut _10: (i32, bool); // in scope 0 at $DIR/checked.rs:+6:13: +6:18 + scope 1 { + debug a => _1; // in scope 1 at $DIR/checked.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/checked.rs:+2:9: +2:10 + scope 2 { + debug b => _2; // in scope 2 at $DIR/checked.rs:+2:9: +2:10 + let _3: i32; // in scope 2 at $DIR/checked.rs:+3:9: +3:10 + scope 3 { + debug c => _3; // in scope 3 at $DIR/checked.rs:+3:9: +3:10 + let _7: i32; // in scope 3 at $DIR/checked.rs:+5:9: +5:10 + scope 4 { + debug d => _7; // in scope 4 at $DIR/checked.rs:+5:9: +5:10 + let _8: i32; // in scope 4 at $DIR/checked.rs:+6:9: +6:10 + scope 5 { + debug e => _8; // in scope 5 at $DIR/checked.rs:+6:9: +6:10 + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/checked.rs:+1:9: +1:10 + _1 = const 1_i32; // scope 0 at $DIR/checked.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/checked.rs:+2:9: +2:10 + _2 = const 2_i32; // scope 1 at $DIR/checked.rs:+2:13: +2:14 + StorageLive(_3); // scope 2 at $DIR/checked.rs:+3:9: +3:10 + StorageLive(_4); // scope 2 at $DIR/checked.rs:+3:13: +3:14 +- _4 = _1; // scope 2 at $DIR/checked.rs:+3:13: +3:14 ++ _4 = const 1_i32; // scope 2 at $DIR/checked.rs:+3:13: +3:14 + StorageLive(_5); // scope 2 at $DIR/checked.rs:+3:17: +3:18 +- _5 = _2; // scope 2 at $DIR/checked.rs:+3:17: +3:18 +- _6 = CheckedAdd(_4, _5); // scope 2 at $DIR/checked.rs:+3:13: +3:18 +- assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> bb1; // scope 2 at $DIR/checked.rs:+3:13: +3:18 ++ _5 = const 2_i32; // scope 2 at $DIR/checked.rs:+3:17: +3:18 ++ _6 = CheckedAdd(const 1_i32, const 2_i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18 ++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> bb1; // scope 2 at $DIR/checked.rs:+3:13: +3:18 + } + + bb1: { +- _3 = move (_6.0: i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18 ++ _3 = const 3_i32; // scope 2 at $DIR/checked.rs:+3:13: +3:18 + StorageDead(_5); // scope 2 at $DIR/checked.rs:+3:17: +3:18 + StorageDead(_4); // scope 2 at $DIR/checked.rs:+3:17: +3:18 + StorageLive(_7); // scope 3 at $DIR/checked.rs:+5:9: +5:10 + _7 = const _; // scope 3 at $DIR/checked.rs:+5:13: +5:21 + StorageLive(_8); // scope 4 at $DIR/checked.rs:+6:9: +6:10 + StorageLive(_9); // scope 4 at $DIR/checked.rs:+6:13: +6:14 +- _9 = _7; // scope 4 at $DIR/checked.rs:+6:13: +6:14 +- _10 = CheckedAdd(_9, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18 +- assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18 ++ _9 = const i32::MAX; // scope 4 at $DIR/checked.rs:+6:13: +6:14 ++ _10 = CheckedAdd(const i32::MAX, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18 ++ assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18 + } + + bb2: { +- _8 = move (_10.0: i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18 ++ _8 = const i32::MIN; // scope 4 at $DIR/checked.rs:+6:13: +6:18 + StorageDead(_9); // scope 4 at $DIR/checked.rs:+6:17: +6:18 + _0 = const (); // scope 0 at $DIR/checked.rs:+0:11: +7:2 + StorageDead(_8); // scope 4 at $DIR/checked.rs:+7:1: +7:2 + StorageDead(_7); // scope 3 at $DIR/checked.rs:+7:1: +7:2 + StorageDead(_3); // scope 2 at $DIR/checked.rs:+7:1: +7:2 + StorageDead(_2); // scope 1 at $DIR/checked.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/checked.rs:+7:1: +7:2 + return; // scope 0 at $DIR/checked.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/checked.rs b/tests/mir-opt/dataflow-const-prop/checked.rs new file mode 100644 index 000000000..0738a4ee5 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/checked.rs @@ -0,0 +1,13 @@ +// unit-test: DataflowConstProp +// compile-flags: -Coverflow-checks=on + +// EMIT_MIR checked.main.DataflowConstProp.diff +#[allow(arithmetic_overflow)] +fn main() { + let a = 1; + let b = 2; + let c = a + b; + + let d = i32::MAX; + let e = d + 1; +} diff --git a/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff new file mode 100644 index 000000000..fce18fae4 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff @@ -0,0 +1,61 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum.rs:+0:11: +0:11 + let _1: E; // in scope 0 at $DIR/enum.rs:+1:9: +1:10 + let mut _3: isize; // in scope 0 at $DIR/enum.rs:+2:23: +2:31 + scope 1 { + debug e => _1; // in scope 1 at $DIR/enum.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/enum.rs:+2:9: +2:10 + let _4: i32; // in scope 1 at $DIR/enum.rs:+2:29: +2:30 + let _5: i32; // in scope 1 at $DIR/enum.rs:+2:44: +2:45 + scope 2 { + debug x => _2; // in scope 2 at $DIR/enum.rs:+2:9: +2:10 + } + scope 3 { + debug x => _4; // in scope 3 at $DIR/enum.rs:+2:29: +2:30 + } + scope 4 { + debug x => _5; // in scope 4 at $DIR/enum.rs:+2:44: +2:45 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum.rs:+1:9: +1:10 + Deinit(_1); // scope 0 at $DIR/enum.rs:+1:13: +1:21 + ((_1 as V1).0: i32) = const 0_i32; // scope 0 at $DIR/enum.rs:+1:13: +1:21 + discriminant(_1) = 0; // scope 0 at $DIR/enum.rs:+1:13: +1:21 + StorageLive(_2); // scope 1 at $DIR/enum.rs:+2:9: +2:10 + _3 = discriminant(_1); // scope 1 at $DIR/enum.rs:+2:19: +2:20 + switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 1 at $DIR/enum.rs:+2:13: +2:20 + } + + bb1: { + StorageLive(_5); // scope 1 at $DIR/enum.rs:+2:44: +2:45 + _5 = ((_1 as V2).0: i32); // scope 1 at $DIR/enum.rs:+2:44: +2:45 + _2 = _5; // scope 4 at $DIR/enum.rs:+2:50: +2:51 + StorageDead(_5); // scope 1 at $DIR/enum.rs:+2:50: +2:51 + goto -> bb4; // scope 1 at $DIR/enum.rs:+2:50: +2:51 + } + + bb2: { + unreachable; // scope 1 at $DIR/enum.rs:+2:19: +2:20 + } + + bb3: { + StorageLive(_4); // scope 1 at $DIR/enum.rs:+2:29: +2:30 + _4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30 + _2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36 + StorageDead(_4); // scope 1 at $DIR/enum.rs:+2:35: +2:36 + goto -> bb4; // scope 1 at $DIR/enum.rs:+2:35: +2:36 + } + + bb4: { + _0 = const (); // scope 0 at $DIR/enum.rs:+0:11: +3:2 + StorageDead(_2); // scope 1 at $DIR/enum.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/enum.rs:+3:1: +3:2 + return; // scope 0 at $DIR/enum.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs new file mode 100644 index 000000000..13288577d --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -0,0 +1,13 @@ +// unit-test: DataflowConstProp + +// Not trackable, because variants could be aliased. +enum E { + V1(i32), + V2(i32) +} + +// EMIT_MIR enum.main.DataflowConstProp.diff +fn main() { + let e = E::V1(0); + let x = match e { E::V1(x) => x, E::V2(x) => x }; +} diff --git a/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff new file mode 100644 index 000000000..32489b4bd --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff @@ -0,0 +1,112 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/if.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/if.rs:+1:9: +1:10 + let mut _3: bool; // in scope 0 at $DIR/if.rs:+2:16: +2:22 + let mut _4: i32; // in scope 0 at $DIR/if.rs:+2:16: +2:17 + let mut _6: i32; // in scope 0 at $DIR/if.rs:+3:13: +3:14 + let mut _8: bool; // in scope 0 at $DIR/if.rs:+5:16: +5:22 + let mut _9: i32; // in scope 0 at $DIR/if.rs:+5:16: +5:17 + let mut _10: i32; // in scope 0 at $DIR/if.rs:+5:36: +5:37 + let mut _12: i32; // in scope 0 at $DIR/if.rs:+6:13: +6:14 + scope 1 { + debug a => _1; // in scope 1 at $DIR/if.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/if.rs:+2:9: +2:10 + scope 2 { + debug b => _2; // in scope 2 at $DIR/if.rs:+2:9: +2:10 + let _5: i32; // in scope 2 at $DIR/if.rs:+3:9: +3:10 + scope 3 { + debug c => _5; // in scope 3 at $DIR/if.rs:+3:9: +3:10 + let _7: i32; // in scope 3 at $DIR/if.rs:+5:9: +5:10 + scope 4 { + debug d => _7; // in scope 4 at $DIR/if.rs:+5:9: +5:10 + let _11: i32; // in scope 4 at $DIR/if.rs:+6:9: +6:10 + scope 5 { + debug e => _11; // in scope 5 at $DIR/if.rs:+6:9: +6:10 + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/if.rs:+1:9: +1:10 + _1 = const 1_i32; // scope 0 at $DIR/if.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/if.rs:+2:9: +2:10 + StorageLive(_3); // scope 1 at $DIR/if.rs:+2:16: +2:22 + StorageLive(_4); // scope 1 at $DIR/if.rs:+2:16: +2:17 +- _4 = _1; // scope 1 at $DIR/if.rs:+2:16: +2:17 +- _3 = Eq(move _4, const 1_i32); // scope 1 at $DIR/if.rs:+2:16: +2:22 ++ _4 = const 1_i32; // scope 1 at $DIR/if.rs:+2:16: +2:17 ++ _3 = const true; // scope 1 at $DIR/if.rs:+2:16: +2:22 + StorageDead(_4); // scope 1 at $DIR/if.rs:+2:21: +2:22 +- switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22 ++ switchInt(const true) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22 + } + + bb1: { + _2 = const 2_i32; // scope 1 at $DIR/if.rs:+2:25: +2:26 + goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:39 + } + + bb2: { + _2 = const 3_i32; // scope 1 at $DIR/if.rs:+2:36: +2:37 + goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:39 + } + + bb3: { + StorageDead(_3); // scope 1 at $DIR/if.rs:+2:38: +2:39 + StorageLive(_5); // scope 2 at $DIR/if.rs:+3:9: +3:10 + StorageLive(_6); // scope 2 at $DIR/if.rs:+3:13: +3:14 +- _6 = _2; // scope 2 at $DIR/if.rs:+3:13: +3:14 +- _5 = Add(move _6, const 1_i32); // scope 2 at $DIR/if.rs:+3:13: +3:18 ++ _6 = const 2_i32; // scope 2 at $DIR/if.rs:+3:13: +3:14 ++ _5 = const 3_i32; // scope 2 at $DIR/if.rs:+3:13: +3:18 + StorageDead(_6); // scope 2 at $DIR/if.rs:+3:17: +3:18 + StorageLive(_7); // scope 3 at $DIR/if.rs:+5:9: +5:10 + StorageLive(_8); // scope 3 at $DIR/if.rs:+5:16: +5:22 + StorageLive(_9); // scope 3 at $DIR/if.rs:+5:16: +5:17 +- _9 = _1; // scope 3 at $DIR/if.rs:+5:16: +5:17 +- _8 = Eq(move _9, const 1_i32); // scope 3 at $DIR/if.rs:+5:16: +5:22 ++ _9 = const 1_i32; // scope 3 at $DIR/if.rs:+5:16: +5:17 ++ _8 = const true; // scope 3 at $DIR/if.rs:+5:16: +5:22 + StorageDead(_9); // scope 3 at $DIR/if.rs:+5:21: +5:22 +- switchInt(move _8) -> [0: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22 ++ switchInt(const true) -> [0: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22 + } + + bb4: { +- _7 = _1; // scope 3 at $DIR/if.rs:+5:25: +5:26 ++ _7 = const 1_i32; // scope 3 at $DIR/if.rs:+5:25: +5:26 + goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:43 + } + + bb5: { + StorageLive(_10); // scope 3 at $DIR/if.rs:+5:36: +5:37 + _10 = _1; // scope 3 at $DIR/if.rs:+5:36: +5:37 + _7 = Add(move _10, const 1_i32); // scope 3 at $DIR/if.rs:+5:36: +5:41 + StorageDead(_10); // scope 3 at $DIR/if.rs:+5:40: +5:41 + goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:43 + } + + bb6: { + StorageDead(_8); // scope 3 at $DIR/if.rs:+5:42: +5:43 + StorageLive(_11); // scope 4 at $DIR/if.rs:+6:9: +6:10 + StorageLive(_12); // scope 4 at $DIR/if.rs:+6:13: +6:14 +- _12 = _7; // scope 4 at $DIR/if.rs:+6:13: +6:14 +- _11 = Add(move _12, const 1_i32); // scope 4 at $DIR/if.rs:+6:13: +6:18 ++ _12 = const 1_i32; // scope 4 at $DIR/if.rs:+6:13: +6:14 ++ _11 = const 2_i32; // scope 4 at $DIR/if.rs:+6:13: +6:18 + StorageDead(_12); // scope 4 at $DIR/if.rs:+6:17: +6:18 + _0 = const (); // scope 0 at $DIR/if.rs:+0:11: +7:2 + StorageDead(_11); // scope 4 at $DIR/if.rs:+7:1: +7:2 + StorageDead(_7); // scope 3 at $DIR/if.rs:+7:1: +7:2 + StorageDead(_5); // scope 2 at $DIR/if.rs:+7:1: +7:2 + StorageDead(_2); // scope 1 at $DIR/if.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/if.rs:+7:1: +7:2 + return; // scope 0 at $DIR/if.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/if.rs b/tests/mir-opt/dataflow-const-prop/if.rs new file mode 100644 index 000000000..34fc35790 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/if.rs @@ -0,0 +1,11 @@ +// unit-test: DataflowConstProp + +// EMIT_MIR if.main.DataflowConstProp.diff +fn main() { + let a = 1; + let b = if a == 1 { 2 } else { 3 }; + let c = b + 1; + + let d = if a == 1 { a } else { a + 1 }; + let e = d + 1; +} diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff new file mode 100644 index 000000000..02aafd7ac --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff @@ -0,0 +1,39 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11 + let mut _1: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + let mut _2: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + scope 1 { + } + scope 2 (inlined <u8 as Add>::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47 + debug self => _1; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + debug other => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _3: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _4: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _5: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _1 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _2 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _3 = const u8::MAX; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _4 = const 1_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _5 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + } + + bb1: { + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs new file mode 100644 index 000000000..2f2d9d010 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs @@ -0,0 +1,8 @@ +// compile-flags: -Zunsound-mir-opts + +// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff +fn main() { + // After inlining, this will contain a `CheckedBinaryOp`. The overflow + // must be ignored by the constant propagation to avoid triggering a panic. + let _ = <u8 as std::ops::Add>::add(255, 1); +} diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff new file mode 100644 index 000000000..5a8788497 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff @@ -0,0 +1,35 @@ +- // MIR for `f` before DataflowConstProp ++ // MIR for `f` after DataflowConstProp + + fn f() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/issue_81605.rs:+0:11: +0:16 + let mut _1: usize; // in scope 0 at $DIR/issue_81605.rs:+1:9: +1:33 + let mut _2: bool; // in scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33 + StorageLive(_2); // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 + _2 = const true; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 ++ switchInt(const true) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 + } + + bb1: { + _1 = const 1_usize; // scope 0 at $DIR/issue_81605.rs:+1:19: +1:20 + goto -> bb3; // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33 + } + + bb2: { + _1 = const 2_usize; // scope 0 at $DIR/issue_81605.rs:+1:30: +1:31 + goto -> bb3; // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/issue_81605.rs:+1:32: +1:33 +- _0 = Add(const 1_usize, move _1); // scope 0 at $DIR/issue_81605.rs:+1:5: +1:33 ++ _0 = const 2_usize; // scope 0 at $DIR/issue_81605.rs:+1:5: +1:33 + StorageDead(_1); // scope 0 at $DIR/issue_81605.rs:+1:32: +1:33 + return; // scope 0 at $DIR/issue_81605.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.rs b/tests/mir-opt/dataflow-const-prop/issue_81605.rs new file mode 100644 index 000000000..d75e2a28b --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/issue_81605.rs @@ -0,0 +1,10 @@ +// unit-test: DataflowConstProp + +// EMIT_MIR issue_81605.f.DataflowConstProp.diff +fn f() -> usize { + 1 + if true { 1 } else { 2 } +} + +fn main() { + f(); +} diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff new file mode 100644 index 000000000..158f187f1 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff @@ -0,0 +1,55 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/ref_without_sb.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14 + let _2: (); // in scope 0 at $DIR/ref_without_sb.rs:+2:5: +2:15 + let mut _3: &i32; // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14 + let _4: &i32; // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14 + let _5: (); // in scope 0 at $DIR/ref_without_sb.rs:+4:5: +4:20 + scope 1 { + debug a => _1; // in scope 1 at $DIR/ref_without_sb.rs:+1:9: +1:14 + let _6: i32; // in scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10 + scope 2 { + debug b => _6; // in scope 2 at $DIR/ref_without_sb.rs:+6:9: +6:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14 + _1 = const 0_i32; // scope 0 at $DIR/ref_without_sb.rs:+1:17: +1:18 + StorageLive(_2); // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15 + StorageLive(_3); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14 + StorageLive(_4); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14 + _4 = &_1; // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14 + _3 = &(*_4); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14 + _2 = escape::<i32>(move _3) -> bb1; // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15 + // mir::Constant + // + span: $DIR/ref_without_sb.rs:12:5: 12:11 + // + literal: Const { ty: for<'a> fn(&'a i32) {escape::<i32>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/ref_without_sb.rs:+2:14: +2:15 + StorageDead(_4); // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16 + StorageDead(_2); // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16 + _1 = const 1_i32; // scope 1 at $DIR/ref_without_sb.rs:+3:5: +3:10 + StorageLive(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20 + _5 = some_function() -> bb2; // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20 + // mir::Constant + // + span: $DIR/ref_without_sb.rs:14:5: 14:18 + // + literal: Const { ty: fn() {some_function}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:20: +4:21 + StorageLive(_6); // scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10 + _6 = _1; // scope 1 at $DIR/ref_without_sb.rs:+6:13: +6:14 + _0 = const (); // scope 0 at $DIR/ref_without_sb.rs:+0:11: +7:2 + StorageDead(_6); // scope 1 at $DIR/ref_without_sb.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/ref_without_sb.rs:+7:1: +7:2 + return; // scope 0 at $DIR/ref_without_sb.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs new file mode 100644 index 000000000..2fd480b09 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs @@ -0,0 +1,17 @@ +// unit-test: DataflowConstProp + +#[inline(never)] +fn escape<T>(x: &T) {} + +#[inline(never)] +fn some_function() {} + +// EMIT_MIR ref_without_sb.main.DataflowConstProp.diff +fn main() { + let mut a = 0; + escape(&a); + a = 1; + some_function(); + // This should currently not be propagated. + let b = a; +} diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff new file mode 100644 index 000000000..f66b00a9a --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff @@ -0,0 +1,44 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/repr_transparent.rs:+0:11: +0:11 + let _1: I32; // in scope 0 at $DIR/repr_transparent.rs:+1:9: +1:10 + let mut _3: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:17: +2:26 + let mut _4: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:17: +2:20 + let mut _5: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:23: +2:26 + scope 1 { + debug x => _1; // in scope 1 at $DIR/repr_transparent.rs:+1:9: +1:10 + let _2: I32; // in scope 1 at $DIR/repr_transparent.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/repr_transparent.rs:+2:9: +2:10 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/repr_transparent.rs:+1:9: +1:10 + Deinit(_1); // scope 0 at $DIR/repr_transparent.rs:+1:13: +1:19 + (_1.0: i32) = const 0_i32; // scope 0 at $DIR/repr_transparent.rs:+1:13: +1:19 + StorageLive(_2); // scope 1 at $DIR/repr_transparent.rs:+2:9: +2:10 + StorageLive(_3); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26 + StorageLive(_4); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20 +- _4 = (_1.0: i32); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20 ++ _4 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20 + StorageLive(_5); // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26 +- _5 = (_1.0: i32); // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26 +- _3 = Add(move _4, move _5); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26 ++ _5 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26 ++ _3 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26 + StorageDead(_5); // scope 1 at $DIR/repr_transparent.rs:+2:25: +2:26 + StorageDead(_4); // scope 1 at $DIR/repr_transparent.rs:+2:25: +2:26 + Deinit(_2); // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27 +- (_2.0: i32) = move _3; // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27 ++ (_2.0: i32) = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27 + StorageDead(_3); // scope 1 at $DIR/repr_transparent.rs:+2:26: +2:27 + _0 = const (); // scope 0 at $DIR/repr_transparent.rs:+0:11: +3:2 + StorageDead(_2); // scope 1 at $DIR/repr_transparent.rs:+3:1: +3:2 + StorageDead(_1); // scope 0 at $DIR/repr_transparent.rs:+3:1: +3:2 + return; // scope 0 at $DIR/repr_transparent.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs new file mode 100644 index 000000000..4ce0ca4df --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs @@ -0,0 +1,12 @@ +// unit-test: DataflowConstProp + +// The struct has scalar ABI, but is not a scalar type. +// Make sure that we handle this correctly. +#[repr(transparent)] +struct I32(i32); + +// EMIT_MIR repr_transparent.main.DataflowConstProp.diff +fn main() { + let x = I32(0); + let y = I32(x.0 + x.0); +} diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff new file mode 100644 index 000000000..df08eff94 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff @@ -0,0 +1,46 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/self_assign.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/self_assign.rs:+1:9: +1:14 + let mut _2: i32; // in scope 0 at $DIR/self_assign.rs:+2:9: +2:10 + let mut _3: i32; // in scope 0 at $DIR/self_assign.rs:+3:9: +3:10 + let mut _5: &i32; // in scope 0 at $DIR/self_assign.rs:+6:9: +6:10 + let mut _6: i32; // in scope 0 at $DIR/self_assign.rs:+7:9: +7:11 + scope 1 { + debug a => _1; // in scope 1 at $DIR/self_assign.rs:+1:9: +1:14 + let mut _4: &i32; // in scope 1 at $DIR/self_assign.rs:+5:9: +5:14 + scope 2 { + debug b => _4; // in scope 2 at $DIR/self_assign.rs:+5:9: +5:14 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/self_assign.rs:+1:9: +1:14 + _1 = const 0_i32; // scope 0 at $DIR/self_assign.rs:+1:17: +1:18 + StorageLive(_2); // scope 1 at $DIR/self_assign.rs:+2:9: +2:10 + _2 = _1; // scope 1 at $DIR/self_assign.rs:+2:9: +2:10 + _1 = Add(move _2, const 1_i32); // scope 1 at $DIR/self_assign.rs:+2:5: +2:14 + StorageDead(_2); // scope 1 at $DIR/self_assign.rs:+2:13: +2:14 + StorageLive(_3); // scope 1 at $DIR/self_assign.rs:+3:9: +3:10 + _3 = _1; // scope 1 at $DIR/self_assign.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/self_assign.rs:+3:5: +3:10 + StorageDead(_3); // scope 1 at $DIR/self_assign.rs:+3:9: +3:10 + StorageLive(_4); // scope 1 at $DIR/self_assign.rs:+5:9: +5:14 + _4 = &_1; // scope 1 at $DIR/self_assign.rs:+5:17: +5:19 + StorageLive(_5); // scope 2 at $DIR/self_assign.rs:+6:9: +6:10 + _5 = _4; // scope 2 at $DIR/self_assign.rs:+6:9: +6:10 + _4 = move _5; // scope 2 at $DIR/self_assign.rs:+6:5: +6:10 + StorageDead(_5); // scope 2 at $DIR/self_assign.rs:+6:9: +6:10 + StorageLive(_6); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11 + _6 = (*_4); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11 + _1 = move _6; // scope 2 at $DIR/self_assign.rs:+7:5: +7:11 + StorageDead(_6); // scope 2 at $DIR/self_assign.rs:+7:10: +7:11 + _0 = const (); // scope 0 at $DIR/self_assign.rs:+0:11: +8:2 + StorageDead(_4); // scope 1 at $DIR/self_assign.rs:+8:1: +8:2 + StorageDead(_1); // scope 0 at $DIR/self_assign.rs:+8:1: +8:2 + return; // scope 0 at $DIR/self_assign.rs:+8:2: +8:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.rs b/tests/mir-opt/dataflow-const-prop/self_assign.rs new file mode 100644 index 000000000..8de2195f9 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/self_assign.rs @@ -0,0 +1,12 @@ +// unit-test: DataflowConstProp + +// EMIT_MIR self_assign.main.DataflowConstProp.diff +fn main() { + let mut a = 0; + a = a + 1; + a = a; + + let mut b = &a; + b = b; + a = *b; +} diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff new file mode 100644 index 000000000..c09e4061e --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff @@ -0,0 +1,23 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/self_assign_add.rs:+0:11: +0:11 + let mut _1: i32; // in scope 0 at $DIR/self_assign_add.rs:+1:9: +1:14 + scope 1 { + debug a => _1; // in scope 1 at $DIR/self_assign_add.rs:+1:9: +1:14 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/self_assign_add.rs:+1:9: +1:14 + _1 = const 0_i32; // scope 0 at $DIR/self_assign_add.rs:+1:17: +1:18 +- _1 = Add(_1, const 1_i32); // scope 1 at $DIR/self_assign_add.rs:+2:5: +2:11 +- _1 = Add(_1, const 1_i32); // scope 1 at $DIR/self_assign_add.rs:+3:5: +3:11 ++ _1 = const 1_i32; // scope 1 at $DIR/self_assign_add.rs:+2:5: +2:11 ++ _1 = const 2_i32; // scope 1 at $DIR/self_assign_add.rs:+3:5: +3:11 + _0 = const (); // scope 0 at $DIR/self_assign_add.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/self_assign_add.rs:+4:1: +4:2 + return; // scope 0 at $DIR/self_assign_add.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs new file mode 100644 index 000000000..e32827624 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs @@ -0,0 +1,8 @@ +// unit-test: DataflowConstProp + +// EMIT_MIR self_assign_add.main.DataflowConstProp.diff +fn main() { + let mut a = 0; + a += 1; + a += 1; +} diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff new file mode 100644 index 000000000..8126d4b85 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff @@ -0,0 +1,56 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/sibling_ptr.rs:+0:11: +0:11 + let mut _1: (u8, u8); // in scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14 + let _2: (); // in scope 0 at $DIR/sibling_ptr.rs:+2:5: +5:6 + let mut _4: *mut u8; // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:18 + let mut _5: *mut u8; // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/sibling_ptr.rs:+1:9: +1:14 + let _6: u8; // in scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11 + scope 2 { + let _3: *mut u8; // in scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14 + scope 3 { + debug p => _3; // in scope 3 at $DIR/sibling_ptr.rs:+3:13: +3:14 + } + } + scope 4 { + debug x1 => _6; // in scope 4 at $DIR/sibling_ptr.rs:+6:9: +6:11 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14 + Deinit(_1); // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33 + (_1.0: u8) = const 0_u8; // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33 + (_1.1: u8) = const 0_u8; // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33 + StorageLive(_2); // scope 1 at $DIR/sibling_ptr.rs:+2:5: +5:6 + StorageLive(_3); // scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14 + _3 = &raw mut (_1.0: u8); // scope 2 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageLive(_4); // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18 + StorageLive(_5); // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11 + _5 = _3; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11 + _4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> bb1; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18 + // mir::Constant + // + span: $DIR/sibling_ptr.rs:8:12: 8:15 + // + literal: Const { ty: unsafe fn(*mut u8, usize) -> *mut u8 {ptr::mut_ptr::<impl *mut u8>::add}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_5); // scope 3 at $DIR/sibling_ptr.rs:+4:17: +4:18 + (*_4) = const 1_u8; // scope 3 at $DIR/sibling_ptr.rs:+4:9: +4:22 + StorageDead(_4); // scope 3 at $DIR/sibling_ptr.rs:+4:22: +4:23 + _2 = const (); // scope 2 at $DIR/sibling_ptr.rs:+2:5: +5:6 + StorageDead(_3); // scope 2 at $DIR/sibling_ptr.rs:+5:5: +5:6 + StorageDead(_2); // scope 1 at $DIR/sibling_ptr.rs:+5:5: +5:6 + StorageLive(_6); // scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11 + _6 = (_1.1: u8); // scope 1 at $DIR/sibling_ptr.rs:+6:14: +6:17 + _0 = const (); // scope 0 at $DIR/sibling_ptr.rs:+0:11: +7:2 + StorageDead(_6); // scope 1 at $DIR/sibling_ptr.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/sibling_ptr.rs:+7:1: +7:2 + return; // scope 0 at $DIR/sibling_ptr.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs new file mode 100644 index 000000000..87ef00d18 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs @@ -0,0 +1,11 @@ +// unit-test: DataflowConstProp + +// EMIT_MIR sibling_ptr.main.DataflowConstProp.diff +fn main() { + let mut x: (u8, u8) = (0, 0); + unsafe { + let p = std::ptr::addr_of_mut!(x.0); + *p.add(1) = 1; + } + let x1 = x.1; // should not be propagated +} diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff new file mode 100644 index 000000000..cfb2706c1 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff @@ -0,0 +1,52 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/struct.rs:+0:11: +0:11 + let mut _1: S; // in scope 0 at $DIR/struct.rs:+1:9: +1:14 + let mut _3: i32; // in scope 0 at $DIR/struct.rs:+2:13: +2:16 + let mut _5: i32; // in scope 0 at $DIR/struct.rs:+4:13: +4:14 + let mut _6: i32; // in scope 0 at $DIR/struct.rs:+4:17: +4:20 + scope 1 { + debug s => _1; // in scope 1 at $DIR/struct.rs:+1:9: +1:14 + let _2: i32; // in scope 1 at $DIR/struct.rs:+2:9: +2:10 + scope 2 { + debug a => _2; // in scope 2 at $DIR/struct.rs:+2:9: +2:10 + let _4: i32; // in scope 2 at $DIR/struct.rs:+4:9: +4:10 + scope 3 { + debug b => _4; // in scope 3 at $DIR/struct.rs:+4:9: +4:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/struct.rs:+1:9: +1:14 + Deinit(_1); // scope 0 at $DIR/struct.rs:+1:17: +1:21 + (_1.0: i32) = const 1_i32; // scope 0 at $DIR/struct.rs:+1:17: +1:21 + StorageLive(_2); // scope 1 at $DIR/struct.rs:+2:9: +2:10 + StorageLive(_3); // scope 1 at $DIR/struct.rs:+2:13: +2:16 +- _3 = (_1.0: i32); // scope 1 at $DIR/struct.rs:+2:13: +2:16 +- _2 = Add(move _3, const 2_i32); // scope 1 at $DIR/struct.rs:+2:13: +2:20 ++ _3 = const 1_i32; // scope 1 at $DIR/struct.rs:+2:13: +2:16 ++ _2 = const 3_i32; // scope 1 at $DIR/struct.rs:+2:13: +2:20 + StorageDead(_3); // scope 1 at $DIR/struct.rs:+2:19: +2:20 + (_1.0: i32) = const 3_i32; // scope 2 at $DIR/struct.rs:+3:5: +3:12 + StorageLive(_4); // scope 2 at $DIR/struct.rs:+4:9: +4:10 + StorageLive(_5); // scope 2 at $DIR/struct.rs:+4:13: +4:14 +- _5 = _2; // scope 2 at $DIR/struct.rs:+4:13: +4:14 ++ _5 = const 3_i32; // scope 2 at $DIR/struct.rs:+4:13: +4:14 + StorageLive(_6); // scope 2 at $DIR/struct.rs:+4:17: +4:20 +- _6 = (_1.0: i32); // scope 2 at $DIR/struct.rs:+4:17: +4:20 +- _4 = Add(move _5, move _6); // scope 2 at $DIR/struct.rs:+4:13: +4:20 ++ _6 = const 3_i32; // scope 2 at $DIR/struct.rs:+4:17: +4:20 ++ _4 = const 6_i32; // scope 2 at $DIR/struct.rs:+4:13: +4:20 + StorageDead(_6); // scope 2 at $DIR/struct.rs:+4:19: +4:20 + StorageDead(_5); // scope 2 at $DIR/struct.rs:+4:19: +4:20 + _0 = const (); // scope 0 at $DIR/struct.rs:+0:11: +5:2 + StorageDead(_4); // scope 2 at $DIR/struct.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/struct.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/struct.rs:+5:1: +5:2 + return; // scope 0 at $DIR/struct.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/struct.rs b/tests/mir-opt/dataflow-const-prop/struct.rs new file mode 100644 index 000000000..841b279e0 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/struct.rs @@ -0,0 +1,11 @@ +// unit-test: DataflowConstProp + +struct S(i32); + +// EMIT_MIR struct.main.DataflowConstProp.diff +fn main() { + let mut s = S(1); + let a = s.0 + 2; + s.0 = 3; + let b = a + s.0; +} diff --git a/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff new file mode 100644 index 000000000..8018400e7 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff @@ -0,0 +1,40 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/terminator.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/terminator.rs:+1:9: +1:10 + let _2: (); // in scope 0 at $DIR/terminator.rs:+3:5: +3:15 + let mut _3: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:14 + let mut _4: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:10 + scope 1 { + debug a => _1; // in scope 1 at $DIR/terminator.rs:+1:9: +1:10 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/terminator.rs:+1:9: +1:10 + _1 = const 1_i32; // scope 0 at $DIR/terminator.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/terminator.rs:+3:5: +3:15 + StorageLive(_3); // scope 1 at $DIR/terminator.rs:+3:9: +3:14 + StorageLive(_4); // scope 1 at $DIR/terminator.rs:+3:9: +3:10 +- _4 = _1; // scope 1 at $DIR/terminator.rs:+3:9: +3:10 +- _3 = Add(move _4, const 1_i32); // scope 1 at $DIR/terminator.rs:+3:9: +3:14 ++ _4 = const 1_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:10 ++ _3 = const 2_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:14 + StorageDead(_4); // scope 1 at $DIR/terminator.rs:+3:13: +3:14 +- _2 = foo(move _3) -> bb1; // scope 1 at $DIR/terminator.rs:+3:5: +3:15 ++ _2 = foo(const 2_i32) -> bb1; // scope 1 at $DIR/terminator.rs:+3:5: +3:15 + // mir::Constant + // + span: $DIR/terminator.rs:9:5: 9:8 + // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 1 at $DIR/terminator.rs:+3:14: +3:15 + StorageDead(_2); // scope 1 at $DIR/terminator.rs:+3:15: +3:16 + _0 = const (); // scope 0 at $DIR/terminator.rs:+0:11: +4:2 + StorageDead(_1); // scope 0 at $DIR/terminator.rs:+4:1: +4:2 + return; // scope 0 at $DIR/terminator.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/terminator.rs b/tests/mir-opt/dataflow-const-prop/terminator.rs new file mode 100644 index 000000000..d151f666a --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/terminator.rs @@ -0,0 +1,10 @@ +// unit-test: DataflowConstProp + +fn foo(n: i32) {} + +// EMIT_MIR terminator.main.DataflowConstProp.diff +fn main() { + let a = 1; + // Checks that we propagate into terminators. + foo(a + 1); +} diff --git a/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff new file mode 100644 index 000000000..e028def00 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff @@ -0,0 +1,75 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/tuple.rs:+0:11: +0:11 + let mut _1: (i32, i32); // in scope 0 at $DIR/tuple.rs:+1:9: +1:14 + let mut _3: i32; // in scope 0 at $DIR/tuple.rs:+2:13: +2:22 + let mut _4: i32; // in scope 0 at $DIR/tuple.rs:+2:13: +2:16 + let mut _5: i32; // in scope 0 at $DIR/tuple.rs:+2:19: +2:22 + let mut _7: i32; // in scope 0 at $DIR/tuple.rs:+4:13: +4:22 + let mut _8: i32; // in scope 0 at $DIR/tuple.rs:+4:13: +4:16 + let mut _9: i32; // in scope 0 at $DIR/tuple.rs:+4:19: +4:22 + let mut _10: i32; // in scope 0 at $DIR/tuple.rs:+4:25: +4:26 + scope 1 { + debug a => _1; // in scope 1 at $DIR/tuple.rs:+1:9: +1:14 + let _2: i32; // in scope 1 at $DIR/tuple.rs:+2:9: +2:10 + scope 2 { + debug b => _2; // in scope 2 at $DIR/tuple.rs:+2:9: +2:10 + let _6: i32; // in scope 2 at $DIR/tuple.rs:+4:9: +4:10 + scope 3 { + debug c => _6; // in scope 3 at $DIR/tuple.rs:+4:9: +4:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/tuple.rs:+1:9: +1:14 + Deinit(_1); // scope 0 at $DIR/tuple.rs:+1:17: +1:23 + (_1.0: i32) = const 1_i32; // scope 0 at $DIR/tuple.rs:+1:17: +1:23 + (_1.1: i32) = const 2_i32; // scope 0 at $DIR/tuple.rs:+1:17: +1:23 + StorageLive(_2); // scope 1 at $DIR/tuple.rs:+2:9: +2:10 + StorageLive(_3); // scope 1 at $DIR/tuple.rs:+2:13: +2:22 + StorageLive(_4); // scope 1 at $DIR/tuple.rs:+2:13: +2:16 +- _4 = (_1.0: i32); // scope 1 at $DIR/tuple.rs:+2:13: +2:16 ++ _4 = const 1_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:16 + StorageLive(_5); // scope 1 at $DIR/tuple.rs:+2:19: +2:22 +- _5 = (_1.1: i32); // scope 1 at $DIR/tuple.rs:+2:19: +2:22 +- _3 = Add(move _4, move _5); // scope 1 at $DIR/tuple.rs:+2:13: +2:22 ++ _5 = const 2_i32; // scope 1 at $DIR/tuple.rs:+2:19: +2:22 ++ _3 = const 3_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:22 + StorageDead(_5); // scope 1 at $DIR/tuple.rs:+2:21: +2:22 + StorageDead(_4); // scope 1 at $DIR/tuple.rs:+2:21: +2:22 +- _2 = Add(move _3, const 3_i32); // scope 1 at $DIR/tuple.rs:+2:13: +2:26 ++ _2 = const 6_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:26 + StorageDead(_3); // scope 1 at $DIR/tuple.rs:+2:25: +2:26 + Deinit(_1); // scope 2 at $DIR/tuple.rs:+3:5: +3:15 + (_1.0: i32) = const 2_i32; // scope 2 at $DIR/tuple.rs:+3:5: +3:15 + (_1.1: i32) = const 3_i32; // scope 2 at $DIR/tuple.rs:+3:5: +3:15 + StorageLive(_6); // scope 2 at $DIR/tuple.rs:+4:9: +4:10 + StorageLive(_7); // scope 2 at $DIR/tuple.rs:+4:13: +4:22 + StorageLive(_8); // scope 2 at $DIR/tuple.rs:+4:13: +4:16 +- _8 = (_1.0: i32); // scope 2 at $DIR/tuple.rs:+4:13: +4:16 ++ _8 = const 2_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:16 + StorageLive(_9); // scope 2 at $DIR/tuple.rs:+4:19: +4:22 +- _9 = (_1.1: i32); // scope 2 at $DIR/tuple.rs:+4:19: +4:22 +- _7 = Add(move _8, move _9); // scope 2 at $DIR/tuple.rs:+4:13: +4:22 ++ _9 = const 3_i32; // scope 2 at $DIR/tuple.rs:+4:19: +4:22 ++ _7 = const 5_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:22 + StorageDead(_9); // scope 2 at $DIR/tuple.rs:+4:21: +4:22 + StorageDead(_8); // scope 2 at $DIR/tuple.rs:+4:21: +4:22 + StorageLive(_10); // scope 2 at $DIR/tuple.rs:+4:25: +4:26 +- _10 = _2; // scope 2 at $DIR/tuple.rs:+4:25: +4:26 +- _6 = Add(move _7, move _10); // scope 2 at $DIR/tuple.rs:+4:13: +4:26 ++ _10 = const 6_i32; // scope 2 at $DIR/tuple.rs:+4:25: +4:26 ++ _6 = const 11_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:26 + StorageDead(_10); // scope 2 at $DIR/tuple.rs:+4:25: +4:26 + StorageDead(_7); // scope 2 at $DIR/tuple.rs:+4:25: +4:26 + _0 = const (); // scope 0 at $DIR/tuple.rs:+0:11: +5:2 + StorageDead(_6); // scope 2 at $DIR/tuple.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/tuple.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/tuple.rs:+5:1: +5:2 + return; // scope 0 at $DIR/tuple.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/tuple.rs b/tests/mir-opt/dataflow-const-prop/tuple.rs new file mode 100644 index 000000000..92c70eab0 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/tuple.rs @@ -0,0 +1,9 @@ +// unit-test: DataflowConstProp + +// EMIT_MIR tuple.main.DataflowConstProp.diff +fn main() { + let mut a = (1, 2); + let b = a.0 + a.1 + 3; + a = (2, 3); + let c = a.0 + a.1 + b; +} diff --git a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff new file mode 100644 index 000000000..cd3b792fb --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff @@ -0,0 +1,76 @@ +- // 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 ++ let mut _4: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17 ++ let _5: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17 + scope 1 { +- debug temp => _6; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17 ++ debug temp => _5; // 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 ++ StorageLive(_4); // scope 0 at $DIR/cycle.rs:+3:11: +3:17 ++ _4 = 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) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 ++ switchInt(move _4) -> [0: 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 +- 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 +- 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 +- 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 +- StorageDead(_9); // scope 1 at $DIR/cycle.rs:+7:16: +7:17 +- _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6 +- StorageDead(_6); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 ++ StorageLive(_5); // scope 0 at $DIR/cycle.rs:+4:13: +4:17 + StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 ++ StorageDead(_4); // 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 ++ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + return; // scope 0 at $DIR/cycle.rs:+9:2: +9:2 + } + } + diff --git a/tests/mir-opt/dead-store-elimination/cycle.rs b/tests/mir-opt/dead-store-elimination/cycle.rs new file mode 100644 index 000000000..b35ce0bcb --- /dev/null +++ b/tests/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/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff new file mode 100644 index 000000000..89f1846b4 --- /dev/null +++ b/tests/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/tests/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/provenance_soundness.retags.DeadStoreElimination.diff new file mode 100644 index 000000000..b5f98233b --- /dev/null +++ b/tests/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:11: +0:13 + _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/tests/mir-opt/dead-store-elimination/provenance_soundness.rs b/tests/mir-opt/dead-store-elimination/provenance_soundness.rs new file mode 100644 index 000000000..11314e990 --- /dev/null +++ b/tests/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/tests/mir-opt/deaggregator_test.bar.Deaggregator.diff b/tests/mir-opt/deaggregator_test.bar.Deaggregator.diff new file mode 100644 index 000000000..db136485a --- /dev/null +++ b/tests/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/tests/mir-opt/deaggregator_test.rs b/tests/mir-opt/deaggregator_test.rs new file mode 100644 index 000000000..ee59402af --- /dev/null +++ b/tests/mir-opt/deaggregator_test.rs @@ -0,0 +1,17 @@ +// unit-test: Deaggregator + +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/tests/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff b/tests/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff new file mode 100644 index 000000000..f28c2b482 --- /dev/null +++ b/tests/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/tests/mir-opt/deaggregator_test_enum.rs b/tests/mir-opt/deaggregator_test_enum.rs new file mode 100644 index 000000000..ea402dafd --- /dev/null +++ b/tests/mir-opt/deaggregator_test_enum.rs @@ -0,0 +1,19 @@ +// unit-test: Deaggregator + +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/tests/mir-opt/deaggregator_test_enum_2.rs b/tests/mir-opt/deaggregator_test_enum_2.rs new file mode 100644 index 000000000..955c31732 --- /dev/null +++ b/tests/mir-opt/deaggregator_test_enum_2.rs @@ -0,0 +1,21 @@ +// unit-test: Deaggregator +// 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/tests/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff b/tests/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff new file mode 100644 index 000000000..210d3849e --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/deaggregator_test_multiple.rs b/tests/mir-opt/deaggregator_test_multiple.rs new file mode 100644 index 000000000..46305fe21 --- /dev/null +++ b/tests/mir-opt/deaggregator_test_multiple.rs @@ -0,0 +1,17 @@ +// unit-test: Deaggregator +// 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/tests/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff b/tests/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff new file mode 100644 index 000000000..cf5da273c --- /dev/null +++ b/tests/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/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff new file mode 100644 index 000000000..3b1f81175 --- /dev/null +++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff @@ -0,0 +1,100 @@ +- // 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: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + let mut _6: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + let mut _7: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + let mut _8: usize; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + let mut _9: bool; // in scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + + 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 + _2 = core::str::<impl str>::as_bytes(move _3) -> bb1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + // mir::Constant + // + span: $DIR/deduplicate_blocks.rs:5:13: 5:21 + // + literal: Const { ty: for<'a> fn(&'a str) -> &'a [u8] {core::str::<impl str>::as_bytes}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:22: +1:23 + _7 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + _8 = const 4_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + _9 = Ge(move _7, move _8); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + switchInt(move _9) -> [0: bb6, otherwise: bb2]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + } + + bb2: { + switchInt((*_2)[0 of 4]) -> [47: bb3, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb3: { + switchInt((*_2)[1 of 4]) -> [47: bb4, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb4: { + switchInt((*_2)[2 of 4]) -> [47: bb5, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb5: { +- switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 ++ switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb6: { + _4 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + _5 = const 3_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + _6 = Ge(move _4, move _5); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + switchInt(move _6) -> [0: bb10, otherwise: bb7]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + } + + bb7: { + switchInt((*_2)[0 of 3]) -> [47: bb8, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb8: { + switchInt((*_2)[1 of 3]) -> [47: bb9, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb9: { +- switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 ++ switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + } + + bb10: { +- _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19 +- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+5:14: +5:19 +- } +- +- bb11: { + _0 = const false; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 +- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 ++ goto -> bb12; // scope 0 at $DIR/deduplicate_blocks.rs:+2:41: +2:46 + } + +- bb12: { +- _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39 +- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+3:35: +3:39 +- } +- +- bb13: { ++ bb11: { + _0 = const true; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 +- goto -> bb14; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 ++ goto -> bb12; // scope 0 at $DIR/deduplicate_blocks.rs:+4:35: +4:39 + } + +- bb14: { ++ bb12: { + 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 + } + } + diff --git a/tests/mir-opt/deduplicate_blocks.rs b/tests/mir-opt/deduplicate_blocks.rs new file mode 100644 index 000000000..2b9eed99e --- /dev/null +++ b/tests/mir-opt/deduplicate_blocks.rs @@ -0,0 +1,15 @@ +// unit-test: DeduplicateBlocks + +// 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/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir b/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir new file mode 100644 index 000000000..9597a0c83 --- /dev/null +++ b/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir @@ -0,0 +1,74 @@ +// MIR for `foo` after PreCodegen + +fn foo(_1: Option<String>) -> i32 { + debug s => _1; // in scope 0 at $DIR/string.rs:+0:12: +0:13 + let mut _0: i32; // return place in scope 0 at $DIR/string.rs:+0:34: +0:37 + let mut _2: &std::string::String; // in scope 0 at $DIR/string.rs:+2:14: +2:17 + let mut _3: &str; // in scope 0 at $DIR/string.rs:+2:14: +2:17 + let mut _4: bool; // in scope 0 at $DIR/string.rs:+2:14: +2:17 + let mut _5: isize; // in scope 0 at $DIR/string.rs:+2:9: +2:18 + let _6: std::option::Option<std::string::String>; // in scope 0 at $DIR/string.rs:+3:9: +3:10 + let mut _7: bool; // in scope 0 at $DIR/string.rs:+5:1: +5:2 + scope 1 { + debug s => _6; // in scope 1 at $DIR/string.rs:+3:9: +3:10 + } + + bb0: { + _7 = const false; // scope 0 at $DIR/string.rs:+1:11: +1:12 + _7 = const true; // scope 0 at $DIR/string.rs:+1:11: +1:12 + _5 = discriminant(_1); // scope 0 at $DIR/string.rs:+1:11: +1:12 + switchInt(move _5) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/string.rs:+1:5: +1:12 + } + + bb1: { + StorageLive(_6); // scope 0 at $DIR/string.rs:+3:9: +3:10 + _7 = const false; // scope 0 at $DIR/string.rs:+3:9: +3:10 + _6 = move _1; // scope 0 at $DIR/string.rs:+3:9: +3:10 + _0 = const 4321_i32; // scope 1 at $DIR/string.rs:+3:14: +3:18 + drop(_6) -> bb6; // scope 0 at $DIR/string.rs:+3:17: +3:18 + } + + bb2: { + _2 = &((_1 as Some).0: std::string::String); // scope 0 at $DIR/string.rs:+2:14: +2:17 + _3 = <String as Deref>::deref(move _2) -> bb3; // scope 0 at $DIR/string.rs:+2:14: +2:17 + // mir::Constant + // + span: $DIR/string.rs:9:14: 9:17 + // + literal: Const { ty: for<'a> fn(&'a String) -> &'a <String as Deref>::Target {<String as Deref>::deref}, val: Value(<ZST>) } + } + + bb3: { + _4 = <str as PartialEq>::eq(_3, const "a") -> bb4; // scope 0 at $DIR/string.rs:+2:14: +2:17 + // mir::Constant + // + span: $DIR/string.rs:9:14: 9:17 + // + literal: Const { ty: for<'a, 'b> fn(&'a str, &'b str) -> bool {<str as PartialEq>::eq}, val: Value(<ZST>) } + // mir::Constant + // + span: $DIR/string.rs:9:14: 9:17 + // + literal: Const { ty: &str, val: Value(Slice(..)) } + } + + bb4: { + switchInt(move _4) -> [0: bb1, otherwise: bb5]; // scope 0 at $DIR/string.rs:+2:14: +2:17 + } + + bb5: { + _0 = const 1234_i32; // scope 0 at $DIR/string.rs:+2:22: +2:26 + goto -> bb9; // scope 0 at $DIR/string.rs:+2:22: +2:26 + } + + bb6: { + StorageDead(_6); // scope 0 at $DIR/string.rs:+3:17: +3:18 + goto -> bb9; // scope 0 at $DIR/string.rs:+3:17: +3:18 + } + + bb7: { + return; // scope 0 at $DIR/string.rs:+5:2: +5:2 + } + + bb8: { + drop(_1) -> bb7; // scope 0 at $DIR/string.rs:+5:1: +5:2 + } + + bb9: { + switchInt(_7) -> [0: bb7, otherwise: bb8]; // scope 0 at $DIR/string.rs:+5:1: +5:2 + } +} diff --git a/tests/mir-opt/deref-patterns/string.rs b/tests/mir-opt/deref-patterns/string.rs new file mode 100644 index 000000000..3a99c44aa --- /dev/null +++ b/tests/mir-opt/deref-patterns/string.rs @@ -0,0 +1,12 @@ +// compile-flags: -Z mir-opt-level=0 -C panic=abort + +#![feature(string_deref_patterns)] +#![crate_type = "lib"] + +// EMIT_MIR string.foo.PreCodegen.after.mir +pub fn foo(s: Option<String>) -> i32 { + match s { + Some("a") => 1234, + s => 4321, + } +} diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.diff new file mode 100644 index 000000000..fa3eeedc4 --- /dev/null +++ b/tests/mir-opt/derefer_complex_case.main.Derefer.diff @@ -0,0 +1,105 @@ +- // 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 _; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:6:17: 6: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:6:17: 6: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:6:17: 6:26 + // + literal: Const { ty: for<'a> fn(&'a 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: bb6, 1: 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 ++ _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 + 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:6:29: 6: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/tests/mir-opt/derefer_complex_case.rs b/tests/mir-opt/derefer_complex_case.rs new file mode 100644 index 000000000..dc48cee95 --- /dev/null +++ b/tests/mir-opt/derefer_complex_case.rs @@ -0,0 +1,7 @@ +// unit-test: Derefer +// EMIT_MIR derefer_complex_case.main.Derefer.diff +// ignore-wasm32 + +fn main() { + for &foo in &[42, 43] { drop(foo) } +} diff --git a/tests/mir-opt/derefer_inline_test.main.Derefer.diff b/tests/mir-opt/derefer_inline_test.main.Derefer.diff new file mode 100644 index 000000000..3540df308 --- /dev/null +++ b/tests/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:11:5: 11: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:11:9: 11: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/tests/mir-opt/derefer_inline_test.rs b/tests/mir-opt/derefer_inline_test.rs new file mode 100644 index 000000000..cc06a7dd8 --- /dev/null +++ b/tests/mir-opt/derefer_inline_test.rs @@ -0,0 +1,12 @@ +// unit-test: Derefer +// 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/tests/mir-opt/derefer_terminator_test.main.Derefer.diff b/tests/mir-opt/derefer_terminator_test.main.Derefer.diff new file mode 100644 index 000000000..ab2388d13 --- /dev/null +++ b/tests/mir-opt/derefer_terminator_test.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_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:6:13: 6: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:7:13: 7: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))))) -> [0: bb3, otherwise: bb4]; // 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 ++ _11 = deref_copy (*_10); // 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 ++ switchInt((*_12)) -> [0: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 + } + + bb3: { + _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: { + 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/tests/mir-opt/derefer_terminator_test.rs b/tests/mir-opt/derefer_terminator_test.rs new file mode 100644 index 000000000..d6750c29d --- /dev/null +++ b/tests/mir-opt/derefer_terminator_test.rs @@ -0,0 +1,17 @@ +// unit-test: Derefer +// 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/tests/mir-opt/derefer_test.main.Derefer.diff b/tests/mir-opt/derefer_test.main.Derefer.diff new file mode 100644 index 000000000..87306d818 --- /dev/null +++ b/tests/mir-opt/derefer_test.main.Derefer.diff @@ -0,0 +1,50 @@ +- // 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 ++ _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 + 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 ++ _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 + _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/tests/mir-opt/derefer_test.rs b/tests/mir-opt/derefer_test.rs new file mode 100644 index 000000000..fad0fe8eb --- /dev/null +++ b/tests/mir-opt/derefer_test.rs @@ -0,0 +1,8 @@ +// unit-test: Derefer +// 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/tests/mir-opt/derefer_test_multiple.main.Derefer.diff b/tests/mir-opt/derefer_test_multiple.main.Derefer.diff new file mode 100644 index 000000000..3e40db118 --- /dev/null +++ b/tests/mir-opt/derefer_test_multiple.main.Derefer.diff @@ -0,0 +1,80 @@ +- // 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 ++ _10 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // 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 ++ _12 = deref_copy ((*_11).1: &mut (i32, i32)); // 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 + 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 ++ _13 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // 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 ++ _15 = deref_copy ((*_14).1: &mut (i32, i32)); // 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 + _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/tests/mir-opt/derefer_test_multiple.rs b/tests/mir-opt/derefer_test_multiple.rs new file mode 100644 index 000000000..0b3888b07 --- /dev/null +++ b/tests/mir-opt/derefer_test_multiple.rs @@ -0,0 +1,10 @@ +// unit-test: Derefer +// 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/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff new file mode 100644 index 000000000..9c7296632 --- /dev/null +++ b/tests/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff @@ -0,0 +1,75 @@ +- // MIR for `foo` before DestinationPropagation ++ // MIR for `foo` after DestinationPropagation + + fn foo() -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/branch.rs:+0:13: +0:16 + 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 ++ debug x => _0; // 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 ++ debug y => _0; // 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 ++ nop; // scope 0 at $DIR/branch.rs:+1:9: +1:10 ++ _0 = 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 ++ nop; // 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) -> [0: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22 + } + + bb3: { +- _2 = _1; // scope 1 at $DIR/branch.rs:+4:9: +4:10 ++ 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 +- _2 = _1; // scope 1 at $DIR/branch.rs:+7:9: +7:10 ++ 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 +- _0 = _2; // scope 2 at $DIR/branch.rs:+10:5: +10:6 +- StorageDead(_2); // scope 1 at $DIR/branch.rs:+11:1: +11:2 +- StorageDead(_1); // scope 0 at $DIR/branch.rs:+11:1: +11:2 ++ nop; // scope 2 at $DIR/branch.rs:+10:5: +10:6 ++ nop; // scope 1 at $DIR/branch.rs:+11:1: +11:2 ++ nop; // scope 0 at $DIR/branch.rs:+11:1: +11:2 + return; // scope 0 at $DIR/branch.rs:+11:2: +11:2 + } + } + diff --git a/tests/mir-opt/dest-prop/branch.rs b/tests/mir-opt/dest-prop/branch.rs new file mode 100644 index 000000000..898c908b1 --- /dev/null +++ b/tests/mir-opt/dest-prop/branch.rs @@ -0,0 +1,27 @@ +//! Tests that assignment in both branches of an `if` are eliminated. +// unit-test: DestinationPropagation +fn val() -> i32 { + 1 +} + +fn cond() -> bool { + true +} + +// EMIT_MIR branch.foo.DestinationPropagation.diff +fn foo() -> i32 { + let x = val(); + + let y = if cond() { + x + } else { + val(); + x + }; + + y +} + +fn main() { + foo(); +} diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff new file mode 100644 index 000000000..4343a5935 --- /dev/null +++ b/tests/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 => _1; // 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 + _1 = const 123_i32; // 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/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff new file mode 100644 index 000000000..298991b5a --- /dev/null +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff @@ -0,0 +1,32 @@ +- // MIR for `bar` before DestinationPropagation ++ // MIR for `bar` after DestinationPropagation + + fn bar(_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 _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 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12 ++ _2 = dummy(move _1) -> 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 ++ nop; // 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 + _1 = const 5_u8; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10 + _0 = const (); // 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/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff new file mode 100644 index 000000000..bc88787e6 --- /dev/null +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff @@ -0,0 +1,22 @@ +- // MIR for `baz` before DestinationPropagation ++ // MIR for `baz` after DestinationPropagation + + fn baz(_1: i32) -> i32 { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13 + let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:23: +0:26 + 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 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 +- _1 = move _2; // 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:+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 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10 + _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 + return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff new file mode 100644 index 000000000..d37a9f71d --- /dev/null +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff @@ -0,0 +1,32 @@ +- // 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 ++ nop; // 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 ++ _1 = 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 +- _1 = move _2; // 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:+2:5: +2:17 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17 + _0 = const (); // 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/tests/mir-opt/dest-prop/copy_propagation_arg.rs b/tests/mir-opt/dest-prop/copy_propagation_arg.rs new file mode 100644 index 000000000..31be6c931 --- /dev/null +++ b/tests/mir-opt/dest-prop/copy_propagation_arg.rs @@ -0,0 +1,40 @@ +// Check that DestinationPropagation does not propagate an assignment to a function argument +// (doing so can break usages of the original argument value) +// unit-test: DestinationPropagation +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) -> i32 { + // self-assignment to a function argument should be eliminated + x = 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/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff new file mode 100644 index 000000000..cfc203c5f --- /dev/null +++ b/tests/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff @@ -0,0 +1,77 @@ +- // 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 ++ debug x => _6; // 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 ++ debug y => _6; // 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 ++ debug z => _6; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10 + } + } + } + + 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 ++ nop; // scope 0 at $DIR/cycle.rs:+1:9: +1:14 ++ _6 = 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 +- _2 = _1; // scope 1 at $DIR/cycle.rs:+2:13: +2:14 +- StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10 +- _3 = _2; // scope 2 at $DIR/cycle.rs:+3:13: +3:14 +- StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10 +- _4 = _3; // scope 3 at $DIR/cycle.rs:+4:9: +4:10 +- _1 = move _4; // scope 3 at $DIR/cycle.rs:+4:5: +4:10 +- StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10 ++ nop; // scope 1 at $DIR/cycle.rs:+2:9: +2:10 ++ nop; // scope 1 at $DIR/cycle.rs:+2:13: +2:14 ++ nop; // scope 2 at $DIR/cycle.rs:+3:9: +3:10 ++ nop; // scope 2 at $DIR/cycle.rs:+3:13: +3:14 ++ nop; // 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 ++ nop; // 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 +- _6 = _1; // scope 3 at $DIR/cycle.rs:+6:10: +6:11 ++ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11 ++ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11 + _5 = std::mem::drop::<i32>(move _6) -> bb2; // scope 3 at $DIR/cycle.rs:+6:5: +6:12 + // mir::Constant + // + span: $DIR/cycle.rs:14:5: 14:9 + // + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(<ZST>) } + } + + bb2: { +- StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12 ++ nop; // scope 3 at $DIR/cycle.rs:+6:11: +6:12 + StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13 + _0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +7:2 +- 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 ++ nop; // scope 2 at $DIR/cycle.rs:+7:1: +7:2 ++ nop; // scope 1 at $DIR/cycle.rs:+7:1: +7:2 ++ nop; // scope 0 at $DIR/cycle.rs:+7:1: +7:2 + return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dest-prop/cycle.rs b/tests/mir-opt/dest-prop/cycle.rs new file mode 100644 index 000000000..6182878f3 --- /dev/null +++ b/tests/mir-opt/dest-prop/cycle.rs @@ -0,0 +1,15 @@ +//! Tests that cyclic assignments don't hang DestinationPropagation, and result in reasonable code. +// unit-test: DestinationPropagation +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/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir new file mode 100644 index 000000000..63cac133b --- /dev/null +++ b/tests/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir @@ -0,0 +1,34 @@ +// MIR for `f` after DestinationPropagation + +fn f(_1: usize) -> usize { + debug a => _1; // in scope 0 at $DIR/dead_stores_79191.rs:+0:6: +0:11 + let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_79191.rs:+0:23: +0:28 + let _2: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10 + let mut _3: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + let mut _4: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + scope 1 { + debug b => _3; // in scope 1 at $DIR/dead_stores_79191.rs:+1:9: +1:10 + } + + bb0: { + nop; // scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10 + _3 = _1; // scope 0 at $DIR/dead_stores_79191.rs:+1:13: +1:14 + _1 = const 5_usize; // scope 1 at $DIR/dead_stores_79191.rs:+2:5: +2:10 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/dead_stores_79191.rs:+3:5: +3:10 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9 + _0 = id::<usize>(move _1) -> bb1; // scope 1 at $DIR/dead_stores_79191.rs:+4:5: +4:10 + // mir::Constant + // + span: $DIR/dead_stores_79191.rs:12:5: 12:7 + // + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) } + } + + bb1: { + nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:9: +4:10 + nop; // scope 0 at $DIR/dead_stores_79191.rs:+5:1: +5:2 + return; // scope 0 at $DIR/dead_stores_79191.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/dest-prop/dead_stores_79191.rs b/tests/mir-opt/dest-prop/dead_stores_79191.rs new file mode 100644 index 000000000..43e0bf664 --- /dev/null +++ b/tests/mir-opt/dest-prop/dead_stores_79191.rs @@ -0,0 +1,17 @@ +// unit-test: DestinationPropagation + +fn id<T>(x: T) -> T { + x +} + +// EMIT_MIR dead_stores_79191.f.DestinationPropagation.after.mir +fn f(mut a: usize) -> usize { + let b = a; + a = 5; + a = b; + id(a) +} + +fn main() { + f(0); +} diff --git a/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir new file mode 100644 index 000000000..26068931a --- /dev/null +++ b/tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir @@ -0,0 +1,33 @@ +// MIR for `f` after DestinationPropagation + +fn f(_1: usize) -> usize { + debug a => _1; // in scope 0 at $DIR/dead_stores_better.rs:+0:10: +0:15 + let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_better.rs:+0:27: +0:32 + let _2: usize; // in scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10 + let mut _3: usize; // in scope 0 at $DIR/dead_stores_better.rs:+3:9: +3:10 + let mut _4: usize; // in scope 0 at $DIR/dead_stores_better.rs:+4:8: +4:9 + scope 1 { + debug b => _1; // in scope 1 at $DIR/dead_stores_better.rs:+1:9: +1:10 + } + + bb0: { + nop; // scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10 + nop; // scope 0 at $DIR/dead_stores_better.rs:+1:13: +1:14 + nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_better.rs:+3:5: +3:10 + nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10 + nop; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9 + nop; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9 + _0 = id::<usize>(move _1) -> bb1; // scope 1 at $DIR/dead_stores_better.rs:+4:5: +4:10 + // mir::Constant + // + span: $DIR/dead_stores_better.rs:16:5: 16:7 + // + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) } + } + + bb1: { + nop; // scope 1 at $DIR/dead_stores_better.rs:+4:9: +4:10 + nop; // scope 0 at $DIR/dead_stores_better.rs:+5:1: +5:2 + return; // scope 0 at $DIR/dead_stores_better.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/dest-prop/dead_stores_better.rs b/tests/mir-opt/dest-prop/dead_stores_better.rs new file mode 100644 index 000000000..003ad57d8 --- /dev/null +++ b/tests/mir-opt/dest-prop/dead_stores_better.rs @@ -0,0 +1,21 @@ +// This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates +// that that pass enables this one to do more optimizations. + +// unit-test: DestinationPropagation +// compile-flags: -Zmir-enable-passes=+DeadStoreElimination + +fn id<T>(x: T) -> T { + x +} + +// EMIT_MIR dead_stores_better.f.DestinationPropagation.after.mir +pub fn f(mut a: usize) -> usize { + let b = a; + a = 5; + a = b; + id(a) +} + +fn main() { + f(0); +} diff --git a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff new file mode 100644 index 000000000..c2a3a0025 --- /dev/null +++ b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff @@ -0,0 +1,43 @@ +- // MIR for `nrvo` before DestinationPropagation ++ // MIR for `nrvo` after DestinationPropagation + + fn nrvo(_1: for<'a> fn(&'a 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<'a> fn(&'a 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 ++ nop; // scope 1 at $DIR/simple.rs:+2:5: +2:9 ++ nop; // 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 ++ _3 = move _1(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 ++ nop; // 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/tests/mir-opt/dest-prop/simple.rs b/tests/mir-opt/dest-prop/simple.rs new file mode 100644 index 000000000..d4c27228f --- /dev/null +++ b/tests/mir-opt/dest-prop/simple.rs @@ -0,0 +1,14 @@ +//! Copy of `nrvo-simple.rs`, to ensure that full dest-prop handles it too. +// unit-test: DestinationPropagation +// 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/tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff new file mode 100644 index 000000000..fbed31788 --- /dev/null +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.diff @@ -0,0 +1,35 @@ +- // 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 mut _3: 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 => _3; // 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: { + StorageDead(_2); // scope 0 at $DIR/union.rs:+5:29: +5:30 + StorageLive(_3); // scope 1 at $DIR/union.rs:+7:10: +7:26 + StorageDead(_3); // scope 1 at $DIR/union.rs:+7:26: +7:27 + 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/tests/mir-opt/dest-prop/union.rs b/tests/mir-opt/dest-prop/union.rs new file mode 100644 index 000000000..eb6cb09fc --- /dev/null +++ b/tests/mir-opt/dest-prop/union.rs @@ -0,0 +1,16 @@ +//! Tests that we can propagate 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/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff new file mode 100644 index 000000000..9ea756c27 --- /dev/null +++ b/tests/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff @@ -0,0 +1,86 @@ +- // MIR for `f` before DestinationPropagation ++ // MIR for `f` after DestinationPropagation + + fn f(_1: T) -> () { + debug a => _1; // in scope 0 at $DIR/unreachable.rs:+0:19: +0:20 + let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:25: +0:25 + let _2: T; // in scope 0 at $DIR/unreachable.rs:+1:9: +1:10 + let mut _3: bool; // in scope 0 at $DIR/unreachable.rs:+2:8: +2:13 + let _4: (); // in scope 0 at $DIR/unreachable.rs:+3:9: +3:16 + let mut _5: T; // in scope 0 at $DIR/unreachable.rs:+3:11: +3:12 + let mut _6: T; // in scope 0 at $DIR/unreachable.rs:+3:14: +3:15 + let _7: (); // in scope 0 at $DIR/unreachable.rs:+5:9: +5:16 + let mut _8: T; // in scope 0 at $DIR/unreachable.rs:+5:11: +5:12 + let mut _9: T; // in scope 0 at $DIR/unreachable.rs:+5:14: +5:15 + scope 1 { +- debug b => _2; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10 ++ debug b => _1; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/unreachable.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14 ++ nop; // scope 0 at $DIR/unreachable.rs:+1:9: +1:10 ++ nop; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14 + StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 + _3 = const false; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 +- goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 ++ goto -> bb1; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 + } + + bb1: { +- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+3:9: +3:16 +- StorageLive(_5); // scope 1 at $DIR/unreachable.rs:+3:11: +3:12 +- _5 = _1; // scope 1 at $DIR/unreachable.rs:+3:11: +3:12 +- StorageLive(_6); // scope 1 at $DIR/unreachable.rs:+3:14: +3:15 +- _6 = _2; // scope 1 at $DIR/unreachable.rs:+3:14: +3:15 +- _4 = g::<T>(move _5, move _6) -> bb2; // scope 1 at $DIR/unreachable.rs:+3:9: +3:16 +- // mir::Constant +- // + span: $DIR/unreachable.rs:11:9: 11:10 +- // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) } +- } +- +- bb2: { +- StorageDead(_6); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16 +- StorageDead(_5); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16 +- StorageDead(_4); // scope 1 at $DIR/unreachable.rs:+3:16: +3:17 +- _0 = const (); // scope 1 at $DIR/unreachable.rs:+2:14: +4:6 +- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 +- } +- +- bb3: { + StorageLive(_7); // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 +- StorageLive(_8); // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 +- _8 = _2; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 + StorageLive(_9); // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 +- _9 = _2; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 +- _7 = g::<T>(move _8, move _9) -> bb4; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 ++ _9 = _1; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 ++ _7 = g::<T>(move _1, move _9) -> bb2; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 + // mir::Constant + // + span: $DIR/unreachable.rs:13:9: 13:10 + // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) } + } + +- bb4: { ++ bb2: { + StorageDead(_9); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 +- StorageDead(_8); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 + StorageDead(_7); // scope 1 at $DIR/unreachable.rs:+5:16: +5:17 + _0 = const (); // scope 1 at $DIR/unreachable.rs:+4:12: +6:6 +- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 ++ goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 + } + +- bb5: { ++ bb3: { + StorageDead(_3); // scope 1 at $DIR/unreachable.rs:+6:5: +6:6 +- StorageDead(_2); // scope 0 at $DIR/unreachable.rs:+7:1: +7:2 ++ nop; // scope 0 at $DIR/unreachable.rs:+7:1: +7:2 + return; // scope 0 at $DIR/unreachable.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/dest-prop/unreachable.rs b/tests/mir-opt/dest-prop/unreachable.rs new file mode 100644 index 000000000..32b5def98 --- /dev/null +++ b/tests/mir-opt/dest-prop/unreachable.rs @@ -0,0 +1,18 @@ +// Check that unreachable code is removed after the destination propagation. +// Regression test for issue #105428. +// +// compile-flags: --crate-type=lib -Zmir-opt-level=0 +// compile-flags: -Zmir-enable-passes=+ConstProp,+SimplifyConstCondition-after-const-prop,+DestinationPropagation + +// EMIT_MIR unreachable.f.DestinationPropagation.diff +pub fn f<T: Copy>(a: T) { + let b = a; + if false { + g(a, b); + } else { + g(b, b); + } +} + +#[inline(never)] +pub fn g<T: Copy>(_: T, _: T) {} diff --git a/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir b/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir new file mode 100644 index 000000000..d7f66a6bf --- /dev/null +++ b/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir @@ -0,0 +1,17 @@ +// MIR for `const_dividend` after PreCodegen + +fn const_dividend(_1: i32) -> i32 { + debug a => _1; // in scope 0 at $DIR/div_overflow.rs:+0:23: +0:24 + let mut _0: i32; // return place in scope 0 at $DIR/div_overflow.rs:+0:34: +0:37 + let mut _2: bool; // in scope 0 at $DIR/div_overflow.rs:+1:5: +1:12 + + bb0: { + _2 = Eq(_1, const 0_i32); // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12 + assert(!move _2, "attempt to divide `{}` by zero", const 256_i32) -> bb1; // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12 + } + + bb1: { + _0 = Div(const 256_i32, move _1); // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12 + return; // scope 0 at $DIR/div_overflow.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir b/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir new file mode 100644 index 000000000..7b7ab1978 --- /dev/null +++ b/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir @@ -0,0 +1,11 @@ +// MIR for `const_divisor` after PreCodegen + +fn const_divisor(_1: i32) -> i32 { + debug a => _1; // in scope 0 at $DIR/div_overflow.rs:+0:22: +0:23 + let mut _0: i32; // return place in scope 0 at $DIR/div_overflow.rs:+0:33: +0:36 + + bb0: { + _0 = Div(move _1, const 256_i32); // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12 + return; // scope 0 at $DIR/div_overflow.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/div_overflow.rs b/tests/mir-opt/div_overflow.rs new file mode 100644 index 000000000..10ce5bc0f --- /dev/null +++ b/tests/mir-opt/div_overflow.rs @@ -0,0 +1,18 @@ +// compile-flags: -Copt-level=0 -Coverflow-checks=yes + +// Tests that division with a const does not emit a panicking branch for overflow + +// EMIT_MIR div_overflow.const_divisor.PreCodegen.after.mir +pub fn const_divisor(a: i32) -> i32 { + a / 256 +} + +// EMIT_MIR div_overflow.const_dividend.PreCodegen.after.mir +pub fn const_dividend(a: i32) -> i32 { + 256 / a +} + +fn main() { + const_divisor(123); + const_dividend(123); +} diff --git a/tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..98a02ee38 --- /dev/null +++ b/tests/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: 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) -> [0: 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: 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: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + } + diff --git a/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..aa75c44b8 --- /dev/null +++ b/tests/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: bb1, 1: 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) -> [0: 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: 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: 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: bb3, 1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + } + diff --git a/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..cea6ff7cd --- /dev/null +++ b/tests/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: 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) -> [0: 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: 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: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + } + } + diff --git a/tests/mir-opt/early_otherwise_branch.rs b/tests/mir-opt/early_otherwise_branch.rs new file mode 100644 index 000000000..7be9fbd03 --- /dev/null +++ b/tests/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/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..b90d70ce4 --- /dev/null +++ b/tests/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: 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) -> [0: 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: 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: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ switchInt(move _8) -> [1: 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: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + } + } + diff --git a/tests/mir-opt/early_otherwise_branch_3_element_tuple.rs b/tests/mir-opt/early_otherwise_branch_3_element_tuple.rs new file mode 100644 index 000000000..76055e133 --- /dev/null +++ b/tests/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/tests/mir-opt/early_otherwise_branch_68867.rs b/tests/mir-opt/early_otherwise_branch_68867.rs new file mode 100644 index 000000000..a6a56f3a9 --- /dev/null +++ b/tests/mir-opt/early_otherwise_branch_68867.rs @@ -0,0 +1,33 @@ +// unit-test: EarlyOtherwiseBranch + +// FIXME: This test was broken by the derefer change. + +// 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 +#[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/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..9edd1a39f --- /dev/null +++ b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -0,0 +1,231 @@ +- // 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 + _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 + switchInt(move _11) -> [0: bb1, 1: bb3, 2: bb4, 3: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb1: { + _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 + switchInt(move _7) -> [0: 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 + Deinit(_33); // 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 + ((_0 as Err).0: ()) = move _33; // 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 + goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2 + } + + bb3: { + _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 + switchInt(move _8) -> [1: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb4: { + _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 + switchInt(move _9) -> [2: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + } + + bb5: { + _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 + switchInt(move _10) -> [3: 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 + _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 + StorageLive(_13); // 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 + 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 + _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 + StorageLive(_18); // 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 + 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 + _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 + StorageLive(_23); // 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 + 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 + _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 + StorageLive(_28); // 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 + 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 + goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2 + } + + bb11: { + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2 + } + } + diff --git a/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..82d8b2fc5 --- /dev/null +++ b/tests/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: bb1, 1: 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: bb2, 1: 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: bb6, 1: 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/tests/mir-opt/early_otherwise_branch_noopt.rs b/tests/mir-opt/early_otherwise_branch_noopt.rs new file mode 100644 index 000000000..ef766bbd4 --- /dev/null +++ b/tests/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/tests/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..a3fa2529b --- /dev/null +++ b/tests/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: 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: 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/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000..6d0224b54 --- /dev/null +++ b/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff @@ -0,0 +1,38 @@ +- // 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: bb1, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + } + + bb1: { + _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 + switchInt(move _2) -> [1: 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/tests/mir-opt/early_otherwise_branch_soundness.rs b/tests/mir-opt/early_otherwise_branch_soundness.rs new file mode 100644 index 000000000..cd4589232 --- /dev/null +++ b/tests/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/tests/mir-opt/equal_true.opt.InstCombine.diff b/tests/mir-opt/equal_true.opt.InstCombine.diff new file mode 100644 index 000000000..8b542a7c1 --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/equal_true.rs b/tests/mir-opt/equal_true.rs new file mode 100644 index 000000000..717d10c6d --- /dev/null +++ b/tests/mir-opt/equal_true.rs @@ -0,0 +1,11 @@ +// unit-test InstCombine + +// 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/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..ab9550499 --- /dev/null +++ b/tests/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:11 + let _8: u32; // in scope 0 at $DIR/exponential_or.rs:+2:57: +2:58 + 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:11 + debug z => _8; // in scope 1 at $DIR/exponential_or.rs:+2:57: +2:58 + } + + bb0: { + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential_or.rs:+1:11: +1:12 + switchInt((_1.0: u32)) -> [1: bb2, 4: 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: bb4, 1: 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: bb4, 8: 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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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:11 + _7 = (_1.0: u32); // scope 0 at $DIR/exponential_or.rs:+2:10: +2:11 + StorageLive(_8); // scope 0 at $DIR/exponential_or.rs:+2:57: +2:58 + _8 = (_1.3: u32); // scope 0 at $DIR/exponential_or.rs:+2:57: +2:58 + 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/tests/mir-opt/exponential_or.rs b/tests/mir-opt/exponential_or.rs new file mode 100644 index 000000000..0b8be8385 --- /dev/null +++ b/tests/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/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir b/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir new file mode 100644 index 000000000..c63433d36 --- /dev/null +++ b/tests/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/tests/mir-opt/fn_ptr_shim.rs b/tests/mir-opt/fn_ptr_shim.rs new file mode 100644 index 000000000..64fbdc9de --- /dev/null +++ b/tests/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/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff new file mode 100644 index 000000000..c1c2cde71 --- /dev/null +++ b/tests/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<'a> fn(&'a 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) -> [0: 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<'a> fn(&'a 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: 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 (IntToInt); // 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<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c 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<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c 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/tests/mir-opt/funky_arms.rs b/tests/mir-opt/funky_arms.rs new file mode 100644 index 000000000..3e70d85e0 --- /dev/null +++ b/tests/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/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir new file mode 100644 index 000000000..a8e090020 --- /dev/null +++ b/tests/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: +3:6 + let mut _2: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + 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: +3:6 + let mut _8: u32; // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + 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: +3:6 + switchInt(move _8) -> [0: bb7, 3: bb10, otherwise: bb11]; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + 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: +3:6 + } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + 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: +3:6 + } + + bb7: { + goto -> bb9; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + 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: +3:6 + } + + bb10: { + StorageLive(_4); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + StorageLive(_5); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + goto -> bb1; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } + + bb11: { + return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + } +} diff --git a/tests/mir-opt/generator_drop_cleanup.rs b/tests/mir-opt/generator_drop_cleanup.rs new file mode 100644 index 000000000..82c1292cb --- /dev/null +++ b/tests/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/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir new file mode 100644 index 000000000..cfbe0aaf2 --- /dev/null +++ b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir @@ -0,0 +1,124 @@ +// 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 + _3 = Foo(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 + _4 = Bar(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 + _6 = (); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14 + _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // 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: bb10]; // 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: bb9]; // 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 + goto -> bb4; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb4: { + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> [return: bb5, unwind: bb14]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb5: { + return; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:6: +6:6 + } + + bb6: { + 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: bb7, unwind: bb15]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb7: { + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> [return: bb8, unwind: bb14]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb8: { + generator_drop; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6 + } + + bb9 (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 -> bb12; // scope 2 at no-location + } + + bb10 (cleanup): { + goto -> bb11; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16 + } + + bb11 (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 -> bb12; // scope 2 at no-location + } + + bb12 (cleanup): { + StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + goto -> bb13; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb13 (cleanup): { + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> bb14; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } + + bb14 (cleanup): { + resume; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6 + } + + bb15 (cleanup): { + StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + drop(_1) -> bb14; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6 + } +} diff --git a/tests/mir-opt/generator_storage_dead_unwind.rs b/tests/mir-opt/generator_storage_dead_unwind.rs new file mode 100644 index 000000000..b72170ade --- /dev/null +++ b/tests/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/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir new file mode 100644 index 000000000..b3d3c768a --- /dev/null +++ b/tests/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: +6:6 + 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: +6:6 + 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: +6:6 + 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: +6:6 + switchInt(move _11) -> [0: bb1, 3: bb5, otherwise: bb6]; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + } + + bb1: { + _10 = move _2; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + nop; // scope 0 at $DIR/generator_tiny.rs:+1:13: +1:15 + (((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop) = 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 + _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: +6:6 + StorageLive(_6); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + StorageLive(_7); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + _6 = move _2; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + goto -> bb3; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + } + + bb6: { + unreachable; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + } +} diff --git a/tests/mir-opt/generator_tiny.rs b/tests/mir-opt/generator_tiny.rs new file mode 100644 index 000000000..7dad63a61 --- /dev/null +++ b/tests/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/tests/mir-opt/graphviz.main.built.after.dot b/tests/mir-opt/graphviz.main.built.after.dot new file mode 100644 index 000000000..8d1da7f1b --- /dev/null +++ b/tests/mir-opt/graphviz.main.built.after.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/tests/mir-opt/graphviz.rs b/tests/mir-opt/graphviz.rs new file mode 100644 index 000000000..6906b86c2 --- /dev/null +++ b/tests/mir-opt/graphviz.rs @@ -0,0 +1,5 @@ +// Test graphviz output +// compile-flags: -Z dump-mir-graphviz + +// EMIT_MIR graphviz.main.built.after.dot +fn main() {} diff --git a/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..de4235c9e --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..754c6579a --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..ff23839e2 --- /dev/null +++ b/tests/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) -> [0: 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: 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 (IntToInt); // 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 (IntToInt); // 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/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..5964d76a4 --- /dev/null +++ b/tests/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) -> [0: 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) -> [120: 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/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..98918cc74 --- /dev/null +++ b/tests/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) -> [0: 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: 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/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..db38140b8 --- /dev/null +++ b/tests/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) -> [0: 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: 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) -> [0: 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: 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/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..1a1ac4caa --- /dev/null +++ b/tests/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) -> [0: 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) -> [4294967254: 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/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..fc3f50227 --- /dev/null +++ b/tests/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) -> [0: 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: 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/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs new file mode 100644 index 000000000..398311e6b --- /dev/null +++ b/tests/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/tests/mir-opt/inline/asm_unwind.main.Inline.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.diff new file mode 100644 index 000000000..f1b62ac38 --- /dev/null +++ b/tests/mir-opt/inline/asm_unwind.main.Inline.diff @@ -0,0 +1,45 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/asm_unwind.rs:+0:15: +0:15 + let _1: (); // in scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 ++ scope 1 (inlined foo) { // at $DIR/asm_unwind.rs:21:5: 21:10 ++ let _2: D; // in scope 1 at $DIR/asm_unwind.rs:15:9: 15:11 ++ scope 2 { ++ debug _d => _2; // in scope 2 at $DIR/asm_unwind.rs:15:9: 15:11 ++ scope 3 { ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 +- _1 = foo() -> bb1; // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10 +- // mir::Constant +- // + span: $DIR/asm_unwind.rs:21:5: 21:8 +- // + literal: Const { ty: fn() {foo}, val: Value(<ZST>) } ++ StorageLive(_2); // scope 1 at $DIR/asm_unwind.rs:15:9: 15:11 ++ asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb3]; // scope 3 at $DIR/asm_unwind.rs:16:14: 16:54 + } + + bb1: { ++ drop(_2) -> bb2; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2 ++ } ++ ++ bb2: { ++ StorageDead(_2); // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2 + StorageDead(_1); // scope 0 at $DIR/asm_unwind.rs:+1:10: +1:11 + _0 = const (); // scope 0 at $DIR/asm_unwind.rs:+0:15: +2:2 + return; // scope 0 at $DIR/asm_unwind.rs:+2:2: +2:2 ++ } ++ ++ bb3 (cleanup): { ++ drop(_2) -> bb4; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2 ++ } ++ ++ bb4 (cleanup): { ++ resume; // scope 1 at $DIR/asm_unwind.rs:14:1: 17:2 + } + } + diff --git a/tests/mir-opt/inline/asm_unwind.rs b/tests/mir-opt/inline/asm_unwind.rs new file mode 100644 index 000000000..c03feb433 --- /dev/null +++ b/tests/mir-opt/inline/asm_unwind.rs @@ -0,0 +1,22 @@ +// Tests inlining of `may_unwind` inline assembly. +// +// ignore-wasm32-bare compiled with panic=abort by default +// needs-asm-support +#![feature(asm_unwind)] + +struct D; + +impl Drop for D { + fn drop(&mut self) {} +} + +#[inline(always)] +fn foo() { + let _d = D; + unsafe { std::arch::asm!("", options(may_unwind)) }; +} + +// EMIT_MIR asm_unwind.main.Inline.diff +pub fn main() { + foo(); +} diff --git a/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff b/tests/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff new file mode 100644 index 000000000..8b0300678 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/caller_with_trivial_bound.rs b/tests/mir-opt/inline/caller_with_trivial_bound.rs new file mode 100644 index 000000000..8545db894 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/cycle.f.Inline.diff b/tests/mir-opt/inline/cycle.f.Inline.diff new file mode 100644 index 000000000..75ea69a42 --- /dev/null +++ b/tests/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<'a> extern "rust-call" fn(&'a 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/tests/mir-opt/inline/cycle.g.Inline.diff b/tests/mir-opt/inline/cycle.g.Inline.diff new file mode 100644 index 000000000..5f3ee467c --- /dev/null +++ b/tests/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:5:6: 5:7 ++ let _3: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ let mut _4: &fn() {main}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:6:5: 6: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:6:5: 6:8 ++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ _4 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6: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:7:1: 7:2 ++ } ++ ++ bb3 (cleanup): { ++ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2 ++ } ++ ++ bb4: { ++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8 ++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8 ++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9 ++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2 + } + } + diff --git a/tests/mir-opt/inline/cycle.main.Inline.diff b/tests/mir-opt/inline/cycle.main.Inline.diff new file mode 100644 index 000000000..6b4c63bbd --- /dev/null +++ b/tests/mir-opt/inline/cycle.main.Inline.diff @@ -0,0 +1,57 @@ +- // 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:5:6: 5:7 ++ let _3: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ let mut _4: &fn() {g}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ let mut _5: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8 ++ scope 2 (inlined <fn() {g} as Fn<()>>::call - shim(fn() {g})) { // 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:6:5: 6:8 ++ StorageLive(_4); // scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ _4 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6 ++ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6: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: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:7:1: 7:2 ++ } ++ ++ bb3 (cleanup): { ++ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2 ++ } ++ ++ bb4: { ++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8 ++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8 ++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9 ++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2 + } + } + diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs new file mode 100644 index 000000000..9e8950d8a --- /dev/null +++ b/tests/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/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff new file mode 100644 index 000000000..8ea1a0757 --- /dev/null +++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff @@ -0,0 +1,54 @@ +- // 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:26:36: 26:37 ++ let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn_trait.rs:27:14: 27: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:20:27: 20:28 ++ } ++ } + } + + 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<'a> fn(&'a T) -> &'a <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:27:14: 27:15 ++ _5 = move _4 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15 ++ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _5) -> bb2; // scope 3 at $DIR/dyn_trait.rs:21:5: 21:22 + // mir::Constant +- // + span: $DIR/dyn_trait.rs:34:5: 34:22 +- // + literal: Const { ty: for<'a> fn(&'a <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<'a> fn(&'a dyn Cache<V = <Q as Query>::V>) {<dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache}, val: Value(<ZST>) } + } + + bb2: { ++ StorageDead(_5); // scope 2 at $DIR/dyn_trait.rs:27:15: 27: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/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff b/tests/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff new file mode 100644 index 000000000..7653a5ded --- /dev/null +++ b/tests/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<'a> fn(&'a 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/tests/mir-opt/inline/dyn_trait.rs b/tests/mir-opt/inline/dyn_trait.rs new file mode 100644 index 000000000..6a46e1e07 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff new file mode 100644 index 000000000..a71d73b74 --- /dev/null +++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff @@ -0,0 +1,33 @@ +- // 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:20:27: 20:28 ++ } + + 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 ++ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _2) -> bb1; // scope 1 at $DIR/dyn_trait.rs:21:5: 21:22 + // mir::Constant +- // + span: $DIR/dyn_trait.rs:27:5: 27:13 +- // + literal: Const { ty: for<'a> fn(&'a (dyn Cache<V = <C as Cache>::V> + 'a)) {mk_cycle::<<C as Cache>::V>}, val: Value(<ZST>) } ++ // + span: $DIR/dyn_trait.rs:21:7: 21:20 ++ // + literal: Const { ty: for<'a> fn(&'a dyn Cache<V = <C as Cache>::V>) {<dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache}, val: Value(<ZST>) } + } + + bb1: { + 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/tests/mir-opt/inline/exponential_runtime.main.Inline.diff b/tests/mir-opt/inline/exponential_runtime.main.Inline.diff new file mode 100644 index 000000000..7fd62be7a --- /dev/null +++ b/tests/mir-opt/inline/exponential_runtime.main.Inline.diff @@ -0,0 +1,75 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/exponential_runtime.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ scope 1 (inlined <() as G>::call) { // at $DIR/exponential_runtime.rs:86:5: 86:22 ++ let _2: (); // in scope 1 at $DIR/exponential_runtime.rs:73:9: 73:25 ++ let _3: (); // in scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ let _4: (); // in scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25 ++ scope 2 (inlined <() as F>::call) { // at $DIR/exponential_runtime.rs:73:9: 73:25 ++ let _5: (); // in scope 2 at $DIR/exponential_runtime.rs:61:9: 61:25 ++ let _6: (); // in scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ let _7: (); // in scope 2 at $DIR/exponential_runtime.rs:63:9: 63:25 ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 +- _1 = <() as G>::call() -> bb1; // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22 ++ StorageLive(_2); // scope 1 at $DIR/exponential_runtime.rs:73:9: 73:25 ++ StorageLive(_5); // scope 2 at $DIR/exponential_runtime.rs:61:9: 61:25 ++ _5 = <() as E>::call() -> bb3; // scope 2 at $DIR/exponential_runtime.rs:61:9: 61:25 + // mir::Constant +- // + span: $DIR/exponential_runtime.rs:86:5: 86:20 +- // + literal: Const { ty: fn() {<() as G>::call}, val: Value(<ZST>) } ++ // + span: $DIR/exponential_runtime.rs:61:9: 61:23 ++ // + literal: Const { ty: fn() {<() as E>::call}, val: Value(<ZST>) } + } + + bb1: { ++ StorageDead(_3); // scope 1 at $DIR/exponential_runtime.rs:74:25: 74:26 ++ StorageLive(_4); // scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25 ++ _4 = <() as F>::call() -> bb2; // scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:75:9: 75:23 ++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value(<ZST>) } ++ } ++ ++ bb2: { ++ StorageDead(_4); // scope 1 at $DIR/exponential_runtime.rs:75:25: 75:26 + StorageDead(_1); // scope 0 at $DIR/exponential_runtime.rs:+1:22: +1:23 + _0 = const (); // scope 0 at $DIR/exponential_runtime.rs:+0:11: +2:2 + return; // scope 0 at $DIR/exponential_runtime.rs:+2:2: +2:2 ++ } ++ ++ bb3: { ++ StorageDead(_5); // scope 2 at $DIR/exponential_runtime.rs:61:25: 61:26 ++ StorageLive(_6); // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ _6 = <() as E>::call() -> bb4; // scope 2 at $DIR/exponential_runtime.rs:62:9: 62:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:62:9: 62:23 ++ // + literal: Const { ty: fn() {<() as E>::call}, val: Value(<ZST>) } ++ } ++ ++ bb4: { ++ StorageDead(_6); // scope 2 at $DIR/exponential_runtime.rs:62:25: 62:26 ++ StorageLive(_7); // scope 2 at $DIR/exponential_runtime.rs:63:9: 63:25 ++ _7 = <() as E>::call() -> bb5; // scope 2 at $DIR/exponential_runtime.rs:63:9: 63:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:63:9: 63:23 ++ // + literal: Const { ty: fn() {<() as E>::call}, val: Value(<ZST>) } ++ } ++ ++ bb5: { ++ StorageDead(_7); // scope 2 at $DIR/exponential_runtime.rs:63:25: 63:26 ++ StorageDead(_2); // scope 1 at $DIR/exponential_runtime.rs:73:25: 73:26 ++ StorageLive(_3); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ _3 = <() as F>::call() -> bb1; // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25 ++ // mir::Constant ++ // + span: $DIR/exponential_runtime.rs:74:9: 74:23 ++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value(<ZST>) } + } + } + diff --git a/tests/mir-opt/inline/exponential_runtime.rs b/tests/mir-opt/inline/exponential_runtime.rs new file mode 100644 index 000000000..d9219d76a --- /dev/null +++ b/tests/mir-opt/inline/exponential_runtime.rs @@ -0,0 +1,87 @@ +// Checks that code with exponential runtime does not have exponential behavior in inlining. + +trait A { + fn call(); +} + +trait B { + fn call(); +} +impl<T: A> B for T { + #[inline] + fn call() { + <T as A>::call(); + <T as A>::call(); + <T as A>::call(); + } +} + +trait C { + fn call(); +} +impl<T: B> C for T { + #[inline] + fn call() { + <T as B>::call(); + <T as B>::call(); + <T as B>::call(); + } +} + +trait D { + fn call(); +} +impl<T: C> D for T { + #[inline] + fn call() { + <T as C>::call(); + <T as C>::call(); + <T as C>::call(); + } +} + +trait E { + fn call(); +} +impl<T: D> E for T { + #[inline] + fn call() { + <T as D>::call(); + <T as D>::call(); + <T as D>::call(); + } +} + +trait F { + fn call(); +} +impl<T: E> F for T { + #[inline] + fn call() { + <T as E>::call(); + <T as E>::call(); + <T as E>::call(); + } +} + +trait G { + fn call(); +} +impl<T: F> G for T { + #[inline] + fn call() { + <T as F>::call(); + <T as F>::call(); + <T as F>::call(); + } +} + +impl A for () { + #[inline(never)] + fn call() {} +} + +// EMIT_MIR exponential_runtime.main.Inline.diff +fn main() { + <() as G>::call(); +} diff --git a/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir new file mode 100644 index 000000000..3502c2586 --- /dev/null +++ b/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir @@ -0,0 +1,36 @@ +// 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:16:8: 16:9 + debug y => _4; // in scope 2 at $DIR/inline_any_operand.rs:16:16: 16:17 + } + } + + 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 + _0 = Eq(move _3, move _4); // scope 2 at $DIR/inline_any_operand.rs:17:5: 17: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/tests/mir-opt/inline/inline_any_operand.rs b/tests/mir-opt/inline/inline_any_operand.rs new file mode 100644 index 000000000..fb0de020f --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_async.rs b/tests/mir-opt/inline/inline_async.rs new file mode 100644 index 000000000..5c838159b --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_closure.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure.foo.Inline.after.mir new file mode 100644 index 000000000..9eb3a01ee --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_closure.rs b/tests/mir-opt/inline/inline_closure.rs new file mode 100644 index 000000000..715fd0138 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir new file mode 100644 index 000000000..dd32eb2d8 --- /dev/null +++ b/tests/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir @@ -0,0 +1,52 @@ +// 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 + scope 3 { + debug variable => _8; // 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 + _0 = (*_8); // scope 3 at $DIR/inline_closure_borrows_arg.rs:+3:9: +3:18 + 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/tests/mir-opt/inline/inline_closure_borrows_arg.rs b/tests/mir-opt/inline/inline_closure_borrows_arg.rs new file mode 100644 index 000000000..d76bc33f5 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir new file mode 100644 index 000000000..fd19c2886 --- /dev/null +++ b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -0,0 +1,65 @@ +// 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:24 + let mut _13: &T; // in scope 2 at $DIR/inline_closure_captures.rs:+1:13: +1:24 + } + } + + 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 + _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 + StorageLive(_11); // 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 + 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/tests/mir-opt/inline/inline_closure_captures.rs b/tests/mir-opt/inline/inline_closure_captures.rs new file mode 100644 index 000000000..52b6817e4 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/tests/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff new file mode 100644 index 000000000..e30a5e116 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/tests/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff new file mode 100644 index 000000000..c2b3c46a3 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff new file mode 100644 index 000000000..0ca5a5f70 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff new file mode 100644 index 000000000..00d405c77 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff b/tests/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff new file mode 100644 index 000000000..8b9c86f55 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_compatibility.rs b/tests/mir-opt/inline/inline_compatibility.rs new file mode 100644 index 000000000..30aff0a64 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_cycle.one.Inline.diff b/tests/mir-opt/inline/inline_cycle.one.Inline.diff new file mode 100644 index 000000000..5510cd7bc --- /dev/null +++ b/tests/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:36:9: 36: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/tests/mir-opt/inline/inline_cycle.rs b/tests/mir-opt/inline/inline_cycle.rs new file mode 100644 index 000000000..63ad57de1 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_cycle.two.Inline.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.diff new file mode 100644 index 000000000..64c0065b5 --- /dev/null +++ b/tests/mir-opt/inline/inline_cycle.two.Inline.diff @@ -0,0 +1,41 @@ +- // 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:53:22: 53:23 ++ let _3: (); // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:8 ++ let mut _4: (); // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:8 ++ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) { // at $DIR/inline_cycle.rs:54:5: 54:8 ++ } ++ } + + 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 +- // + literal: Const { ty: fn(fn() {f}) {call::<fn() {f}>}, val: Value(<ZST>) } +- // mir::Constant + // + 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:54:5: 54:8 ++ StorageLive(_4); // scope 1 at $DIR/inline_cycle.rs:54:5: 54:8 ++ _3 = move _2() -> bb1; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL + } + + bb1: { ++ StorageDead(_4); // scope 1 at $DIR/inline_cycle.rs:54:7: 54:8 ++ StorageDead(_3); // scope 1 at $DIR/inline_cycle.rs:54:8: 54: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/tests/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.diff new file mode 100644 index 000000000..52debab4d --- /dev/null +++ b/tests/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:31:9: 31: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/tests/mir-opt/inline/inline_cycle_generic.rs b/tests/mir-opt/inline/inline_cycle_generic.rs new file mode 100644 index 000000000..24b4f3793 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_diverging.f.Inline.diff b/tests/mir-opt/inline/inline_diverging.f.Inline.diff new file mode 100644 index 000000000..b49191f49 --- /dev/null +++ b/tests/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:39:5: 39:12 + } + } + diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.diff new file mode 100644 index 000000000..b787a19f4 --- /dev/null +++ b/tests/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) -> [0: 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 (IntToInt); // 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/tests/mir-opt/inline/inline_diverging.h.Inline.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.diff new file mode 100644 index 000000000..f82fcf4c8 --- /dev/null +++ b/tests/mir-opt/inline/inline_diverging.h.Inline.diff @@ -0,0 +1,87 @@ +- // 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:26:36: 26:37 ++ let _3: !; // in scope 1 at $DIR/inline_diverging.rs:27:9: 27:10 ++ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ let mut _5: (); // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:16 ++ let mut _6: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:14 ++ let mut _7: (); // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:16 ++ let mut _8: !; // in scope 1 at $DIR/inline_diverging.rs:29:6: 29:7 ++ let mut _9: !; // in scope 1 at $DIR/inline_diverging.rs:29:9: 29:10 ++ scope 2 { ++ debug a => _3; // in scope 2 at $DIR/inline_diverging.rs:27:9: 27:10 ++ scope 3 { ++ debug b => _9; // in scope 3 at $DIR/inline_diverging.rs:28:9: 28:10 ++ } ++ } ++ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline_diverging.rs:27:13: 27:16 ++ } ++ } + + 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(_9); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22 ++ StorageLive(_3); // scope 1 at $DIR/inline_diverging.rs:27:9: 27:10 ++ StorageLive(_4); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ _4 = &_2; // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14 ++ StorageLive(_5); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:16 ++ _3 = move (*_4)() -> [return: bb6, unwind: bb4]; // scope 4 at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ } ++ ++ bb1: { ++ StorageDead(_7); // scope 2 at $DIR/inline_diverging.rs:28:15: 28:16 ++ StorageDead(_6); // scope 2 at $DIR/inline_diverging.rs:28:15: 28:16 ++ StorageLive(_8); // scope 3 at $DIR/inline_diverging.rs:29:6: 29:7 ++ _8 = move _3; // scope 3 at $DIR/inline_diverging.rs:29:6: 29:7 ++ Deinit(_1); // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11 ++ (_1.0: !) = move _8; // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11 ++ (_1.1: !) = move _9; // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11 ++ StorageDead(_8); // scope 3 at $DIR/inline_diverging.rs:29:10: 29:11 ++ StorageDead(_3); // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2 ++ drop(_2) -> bb2; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2 ++ } ++ ++ bb2: { ++ unreachable; // scope 0 at $DIR/inline_diverging.rs:30:2: 30:2 ++ } ++ ++ bb3 (cleanup): { ++ drop(_3) -> bb4; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2 ++ } ++ ++ bb4 (cleanup): { ++ drop(_2) -> bb5; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2 ++ } ++ ++ bb5 (cleanup): { ++ resume; // scope 1 at $DIR/inline_diverging.rs:26:1: 30:2 ++ } ++ ++ bb6: { ++ StorageDead(_5); // scope 1 at $DIR/inline_diverging.rs:27:15: 27:16 ++ StorageDead(_4); // scope 1 at $DIR/inline_diverging.rs:27:15: 27:16 ++ StorageLive(_6); // scope 2 at $DIR/inline_diverging.rs:28:13: 28:14 ++ _6 = &_2; // scope 2 at $DIR/inline_diverging.rs:28:13: 28:14 ++ StorageLive(_7); // scope 2 at $DIR/inline_diverging.rs:28:13: 28:16 ++ _9 = <fn() -> ! {sleep} as Fn<()>>::call(move _6, move _7) -> [return: bb1, unwind: bb3]; // scope 2 at $DIR/inline_diverging.rs:28:13: 28:16 ++ // mir::Constant ++ // + span: $DIR/inline_diverging.rs:28:13: 28:14 ++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() -> ! {sleep}, ()) -> <fn() -> ! {sleep} as FnOnce<()>>::Output {<fn() -> ! {sleep} as Fn<()>>::call}, val: Value(<ZST>) } + } + } + diff --git a/tests/mir-opt/inline/inline_diverging.rs b/tests/mir-opt/inline/inline_diverging.rs new file mode 100644 index 000000000..ae6f814c2 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_generator.main.Inline.diff b/tests/mir-opt/inline/inline_generator.main.Inline.diff new file mode 100644 index 000000000..f27b64c30 --- /dev/null +++ b/tests/mir-opt/inline/inline_generator.main.Inline.diff @@ -0,0 +1,136 @@ +- // 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:33: +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:33: 9:46 ++ debug a => _7; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7 ++ let mut _8: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ let mut _9: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _10: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _11: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _12: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ } + + 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:15:5: 15:41 ++ discriminant(_4) = 0; // scope 2 at $DIR/inline_generator.rs:15:5: 15: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<'a> fn(Pin<&'a 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:33: +1:46 ++ _7 = const false; // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 ++ _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ _9 = discriminant((*_10)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ switchInt(move _9) -> [0: bb3, 1: bb8, 3: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + } + +- bb3: { ++ bb1: { ++ StorageDead(_7); // scope 0 at $DIR/inline_generator.rs:+1:33: +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: { ++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ switchInt(move _7) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 ++ } ++ ++ bb4: { ++ _8 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25 ++ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ } ++ ++ bb5: { ++ _8 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37 ++ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ } ++ ++ bb6: { ++ Deinit(_1); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ discriminant(_1) = 0; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ _11 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ discriminant((*_11)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:11: 15:39 ++ } ++ ++ bb7: { ++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ StorageDead(_8); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39 ++ Deinit(_1); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ ((_1 as Complete).0: bool) = move _7; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ discriminant(_1) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ _12 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ discriminant((*_12)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:41: 15:41 ++ } ++ ++ bb8: { ++ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ } ++ ++ bb9: { ++ unreachable; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + } + } + diff --git a/tests/mir-opt/inline/inline_generator.rs b/tests/mir-opt/inline/inline_generator.rs new file mode 100644 index 000000000..d11b3e548 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff b/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff new file mode 100644 index 000000000..f1988ea4b --- /dev/null +++ b/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff @@ -0,0 +1,60 @@ +- // 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 + let _4: (); // in scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41 ++ scope 1 (inlined instruction_set_default) { // at $DIR/inline_instruction_set.rs:59:5: 59:30 ++ } ++ scope 2 (inlined inline_always_and_using_inline_asm) { // at $DIR/inline_instruction_set.rs:60:5: 60:41 ++ scope 3 { ++ } ++ } + + 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:57:5: 57: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:58:5: 58: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:59:5: 59: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 + StorageLive(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41 +- _4 = inline_always_and_using_inline_asm() -> bb4; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41 +- // mir::Constant +- // + span: $DIR/inline_instruction_set.rs:60:5: 60:39 +- // + literal: Const { ty: fn() {inline_always_and_using_inline_asm}, val: Value(<ZST>) } ++ asm!("/* do nothing */", options((empty))) -> bb3; // scope 3 at $DIR/inline_instruction_set.rs:43:14: 43:38 + } + +- bb4: { ++ bb3: { + StorageDead(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:41: +4:42 + _0 = const (); // scope 0 at $DIR/inline_instruction_set.rs:+0:18: +5:2 + return; // scope 0 at $DIR/inline_instruction_set.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs new file mode 100644 index 000000000..5dfb04943 --- /dev/null +++ b/tests/mir-opt/inline/inline_instruction_set.rs @@ -0,0 +1,61 @@ +// Checks that only functions with the compatible instruction_set attributes are inlined. +// +// A function is "compatible" when the *callee* has the same attribute or no attribute. +// +// 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() {} + +#[inline(always)] +fn inline_always_and_using_inline_asm() { + unsafe { asm!("/* do nothing */") }; +} + +// EMIT_MIR inline_instruction_set.t32.Inline.diff +#[instruction_set(arm::t32)] +pub fn t32() { + instruction_set_a32(); + instruction_set_t32(); + instruction_set_default(); + inline_always_and_using_inline_asm(); +} + +// EMIT_MIR inline_instruction_set.default.Inline.diff +pub fn default() { + instruction_set_a32(); + instruction_set_t32(); + instruction_set_default(); + inline_always_and_using_inline_asm(); +} diff --git a/tests/mir-opt/inline/inline_instruction_set.t32.Inline.diff b/tests/mir-opt/inline/inline_instruction_set.t32.Inline.diff new file mode 100644 index 000000000..e777b2cc2 --- /dev/null +++ b/tests/mir-opt/inline/inline_instruction_set.t32.Inline.diff @@ -0,0 +1,58 @@ +- // 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:+3:5: +3:30 + let _4: (); // in scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41 ++ scope 1 (inlined instruction_set_t32) { // at $DIR/inline_instruction_set.rs:50:5: 50:26 ++ } ++ scope 2 (inlined instruction_set_default) { // at $DIR/inline_instruction_set.rs:51:5: 51: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:49:5: 49: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:50:5: 50: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:51:5: 51: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 + StorageLive(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41 +- _4 = inline_always_and_using_inline_asm() -> bb4; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41 ++ _4 = inline_always_and_using_inline_asm() -> bb2; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41 + // mir::Constant + // + span: $DIR/inline_instruction_set.rs:52:5: 52:39 + // + literal: Const { ty: fn() {inline_always_and_using_inline_asm}, val: Value(<ZST>) } + } + +- bb4: { ++ bb2: { + StorageDead(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:41: +4:42 + _0 = const (); // scope 0 at $DIR/inline_instruction_set.rs:+0:14: +5:2 + return; // scope 0 at $DIR/inline_instruction_set.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff new file mode 100644 index 000000000..a28da146e --- /dev/null +++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.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: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 ++ let mut _9: 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 + _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: bb5]; // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 ++ StorageLive(_8); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 ++ _8 = &mut (*_7); // 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 ++ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ _10 = const _; // 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 ++ (*_8) = move _9; // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 ++ StorageDead(_9); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43 ++ StorageDead(_8); // 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: bb4]; // 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): { ++ bb3 (cleanup): { + resume; // scope 0 at $DIR/inline_into_box_place.rs:+0:1: +2:2 +- } +- +- bb5 (cleanup): { +- _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)) -> bb4; // 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>) } + } + } + diff --git a/tests/mir-opt/inline/inline_into_box_place.rs b/tests/mir-opt/inline/inline_into_box_place.rs new file mode 100644 index 000000000..232bcc7b2 --- /dev/null +++ b/tests/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 + +#![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/tests/mir-opt/inline/inline_options.main.Inline.after.mir b/tests/mir-opt/inline/inline_options.main.Inline.after.mir new file mode 100644 index 000000000..1c590be94 --- /dev/null +++ b/tests/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:16:23: 16:26 + let _4: (); // in scope 1 at $DIR/inline_options.rs:16:28: 16:31 + let _5: (); // in scope 1 at $DIR/inline_options.rs:16:33: 16: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:16:23: 16:26 + _3 = g() -> bb2; // scope 1 at $DIR/inline_options.rs:16:23: 16: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:16:26: 16:27 + StorageLive(_4); // scope 1 at $DIR/inline_options.rs:16:28: 16:31 + _4 = g() -> bb3; // scope 1 at $DIR/inline_options.rs:16:28: 16: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:16:31: 16:32 + StorageLive(_5); // scope 1 at $DIR/inline_options.rs:16:33: 16:36 + _5 = g() -> bb4; // scope 1 at $DIR/inline_options.rs:16:33: 16: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:16:36: 16: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/tests/mir-opt/inline/inline_options.rs b/tests/mir-opt/inline/inline_options.rs new file mode 100644 index 000000000..477f050b6 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir b/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir new file mode 100644 index 000000000..60149ff36 --- /dev/null +++ b/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir @@ -0,0 +1,68 @@ +// 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<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline_retag.rs:+1:9: +1:10 + let mut _2: for<'a, 'b> fn(&'a i32, &'b 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:16:8: 16:9 + debug y => _6; // in scope 2 at $DIR/inline_retag.rs:16:17: 16:18 + let mut _11: i32; // in scope 2 at $DIR/inline_retag.rs:17:5: 17:7 + let mut _12: i32; // in scope 2 at $DIR/inline_retag.rs:17:11: 17: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<'a, 'b> fn(&'a i32, &'b 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 _; // 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 + _3 = &(*_4); // 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 _; // 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 + _6 = &(*_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 + Retag(_3); // scope 2 at $DIR/inline_retag.rs:16:8: 16:9 + Retag(_6); // scope 2 at $DIR/inline_retag.rs:16:17: 16:18 + StorageLive(_11); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7 + _11 = (*_3); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7 + StorageLive(_12); // scope 2 at $DIR/inline_retag.rs:17:11: 17:13 + _12 = (*_6); // scope 2 at $DIR/inline_retag.rs:17:11: 17:13 + _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline_retag.rs:17:5: 17:13 + StorageDead(_12); // scope 2 at $DIR/inline_retag.rs:17:12: 17:13 + StorageDead(_11); // scope 2 at $DIR/inline_retag.rs:17:12: 17: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/tests/mir-opt/inline/inline_retag.rs b/tests/mir-opt/inline/inline_retag.rs new file mode 100644 index 000000000..c6950f269 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_shims.clone.Inline.diff b/tests/mir-opt/inline/inline_shims.clone.Inline.diff new file mode 100644 index 000000000..09dd35c4c --- /dev/null +++ b/tests/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:7: 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<'a> fn(&'a 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/tests/mir-opt/inline/inline_shims.drop.Inline.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.diff new file mode 100644 index 000000000..36ddb189e --- /dev/null +++ b/tests/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: 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/tests/mir-opt/inline/inline_shims.rs b/tests/mir-opt/inline/inline_shims.rs new file mode 100644 index 000000000..7c8618f71 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_specialization.main.Inline.diff b/tests/mir-opt/inline/inline_specialization.main.Inline.diff new file mode 100644 index 000000000..af08296ed --- /dev/null +++ b/tests/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:14:31: 14: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/tests/mir-opt/inline/inline_specialization.rs b/tests/mir-opt/inline/inline_specialization.rs new file mode 100644 index 000000000..87275b4e5 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_trait_method.rs b/tests/mir-opt/inline/inline_trait_method.rs new file mode 100644 index 000000000..74be53f55 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_trait_method.test.Inline.after.mir b/tests/mir-opt/inline/inline_trait_method.test.Inline.after.mir new file mode 100644 index 000000000..637bf282a --- /dev/null +++ b/tests/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<'a> fn(&'a 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/tests/mir-opt/inline/inline_trait_method_2.rs b/tests/mir-opt/inline/inline_trait_method_2.rs new file mode 100644 index 000000000..378e71a25 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir new file mode 100644 index 000000000..73aea719e --- /dev/null +++ b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir @@ -0,0 +1,28 @@ +// 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:9:9: 9: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 + _0 = <dyn X as X>::y(move _2) -> bb1; // scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10 + // mir::Constant + // + span: $DIR/inline_trait_method_2.rs:10:7: 10:8 + // + literal: Const { ty: for<'a> fn(&'a dyn X) -> bool {<dyn X as X>::y}, val: Value(<ZST>) } + } + + bb1: { + 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/tests/mir-opt/inline/issue_106141.outer.Inline.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.diff new file mode 100644 index 000000000..97361fa5f --- /dev/null +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.diff @@ -0,0 +1,55 @@ +- // MIR for `outer` before Inline ++ // MIR for `outer` after Inline + + fn outer() -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/issue_106141.rs:+0:19: +0:24 ++ scope 1 (inlined inner) { // at $DIR/issue_106141.rs:2:5: 2:12 ++ let mut _1: bool; // in scope 1 at $DIR/issue_106141.rs:13:8: 13:21 ++ let mut _2: bool; // in scope 1 at $DIR/issue_106141.rs:13:8: 13:21 ++ let mut _3: &[bool; 1]; // in scope 1 at $DIR/issue_106141.rs:11:18: 11:25 ++ scope 2 { ++ debug buffer => _3; // in scope 2 at $DIR/issue_106141.rs:11:9: 11:15 ++ scope 3 { ++ debug index => _0; // in scope 3 at $DIR/issue_106141.rs:12:9: 12:14 ++ } ++ } ++ } + + bb0: { +- _0 = inner() -> bb1; // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12 ++ StorageLive(_3); // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12 ++ _3 = const _; // scope 1 at $DIR/issue_106141.rs:11:18: 11:25 + // mir::Constant +- // + span: $DIR/issue_106141.rs:2:5: 2:10 +- // + literal: Const { ty: fn() -> usize {inner}, val: Value(<ZST>) } ++ // + span: $DIR/issue_106141.rs:11:18: 11:25 ++ // + literal: Const { ty: &[bool; 1], val: Unevaluated(inner, [], Some(promoted[0])) } ++ _0 = index() -> bb1; // scope 2 at $DIR/issue_106141.rs:12:17: 12:24 ++ // mir::Constant ++ // + span: $DIR/issue_106141.rs:12:17: 12:22 ++ // + literal: Const { ty: fn() -> usize {index}, val: Value(<ZST>) } + } + + bb1: { ++ StorageLive(_1); // scope 3 at $DIR/issue_106141.rs:13:8: 13:21 ++ _2 = Lt(_0, const 1_usize); // scope 3 at $DIR/issue_106141.rs:13:8: 13:21 ++ assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, _0) -> bb2; // scope 3 at $DIR/issue_106141.rs:13:8: 13:21 ++ } ++ ++ bb2: { ++ _1 = (*_3)[_0]; // scope 3 at $DIR/issue_106141.rs:13:8: 13:21 ++ switchInt(move _1) -> [0: bb3, otherwise: bb4]; // scope 3 at $DIR/issue_106141.rs:13:8: 13:21 ++ } ++ ++ bb3: { ++ _0 = const 0_usize; // scope 3 at $DIR/issue_106141.rs:16:9: 16:10 ++ goto -> bb4; // scope 3 at $DIR/issue_106141.rs:13:5: 17:6 ++ } ++ ++ bb4: { ++ StorageDead(_1); // scope 3 at $DIR/issue_106141.rs:17:5: 17:6 ++ StorageDead(_3); // scope 0 at $DIR/issue_106141.rs:+1:5: +1:12 + return; // scope 0 at $DIR/issue_106141.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/issue_106141.rs b/tests/mir-opt/inline/issue_106141.rs new file mode 100644 index 000000000..c8288b7f3 --- /dev/null +++ b/tests/mir-opt/inline/issue_106141.rs @@ -0,0 +1,24 @@ +pub fn outer() -> usize { + inner() +} + +fn index() -> usize { + loop {} +} + +#[inline] +fn inner() -> usize { + let buffer = &[true]; + let index = index(); + if buffer[index] { + index + } else { + 0 + } +} + +fn main() { + outer(); +} + +// EMIT_MIR issue_106141.outer.Inline.diff diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir new file mode 100644 index 000000000..dc0c32350 --- /dev/null +++ b/tests/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:7: 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/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir new file mode 100644 index 000000000..b6aff3014 --- /dev/null +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -0,0 +1,38 @@ +// 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:7: 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 + _7 = deref_copy (*_4); // 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 + _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/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir new file mode 100644 index 000000000..af830d249 --- /dev/null +++ b/tests/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:7: 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/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir new file mode 100644 index 000000000..4f9342247 --- /dev/null +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -0,0 +1,26 @@ +// 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:7: 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 + _4 = deref_copy (*_3); // 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 + _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/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs new file mode 100644 index 000000000..94f926d39 --- /dev/null +++ b/tests/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/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir new file mode 100644 index 000000000..d99ae1a6c --- /dev/null +++ b/tests/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/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs new file mode 100644 index 000000000..76d806acc --- /dev/null +++ b/tests/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/tests/mir-opt/inline/issue_78442.bar.Inline.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.diff new file mode 100644 index 000000000..51a98465f --- /dev/null +++ b/tests/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<'a> extern "rust-call" fn(&'a 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/tests/mir-opt/inline/issue_78442.bar.RevealAll.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.diff new file mode 100644 index 000000000..e47466c5e --- /dev/null +++ b/tests/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<'a> extern "rust-call" fn(&'a impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(<ZST>) } ++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a 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/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs new file mode 100644 index 000000000..aa8ede2df --- /dev/null +++ b/tests/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/tests/mir-opt/inline/polymorphic_recursion.rs b/tests/mir-opt/inline/polymorphic_recursion.rs new file mode 100644 index 000000000..7388722b7 --- /dev/null +++ b/tests/mir-opt/inline/polymorphic_recursion.rs @@ -0,0 +1,25 @@ +// Make sure that the MIR inliner does not loop indefinitely on polymorphic recursion. +// compile-flags: --crate-type lib + +// Randomize `def_path_hash` by defining them under a module with different names +macro_rules! emit { + ($($m:ident)*) => {$( + pub mod $m { + pub trait Tr { type Next: Tr; } + + pub fn hoge<const N: usize, T: Tr>() { + inner::<N, T>(); + } + + #[inline(always)] + fn inner<const N: usize, T: Tr>() + { + inner::<N, T::Next>(); + inner::<N, T::Next>(); + } + } + )*}; +} + +// Increase the chance of triggering the bug +emit!(m00 m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19); diff --git a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff new file mode 100644 index 000000000..a3cee3ecf --- /dev/null +++ b/tests/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:20:1 - 22: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/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff new file mode 100644 index 000000000..2f6f5f87e --- /dev/null +++ b/tests/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:11:1 - 11: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:12:5 - 13: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:13:12: 13:15 + // + literal: Const { ty: fn() -> bool {bar}, val: Value(<ZST>) } + } + + bb3: { + switchInt(move _2) -> [0: 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:17:1 - 17:2; // scope 0 at /the/src/instrument_coverage.rs:+6:2: +6:2 ++ Coverage::Expression(4294967294) = 4294967295 - 2 for /the/src/instrument_coverage.rs:14:13 - 14: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:15:10 - 15: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/tests/mir-opt/instrument_coverage.rs b/tests/mir-opt/instrument_coverage.rs new file mode 100644 index 000000000..7f6a0a0eb --- /dev/null +++ b/tests/mir-opt/instrument_coverage.rs @@ -0,0 +1,37 @@ +// Test that `-C instrument-coverage` injects Coverage statements. The Coverage Counter statements +// are later converted into LLVM instrprof.increment intrinsics, during codegen. + +// unit-test: InstrumentCoverage +// 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/tests/mir-opt/issue_101973.inner.ConstProp.diff b/tests/mir-opt/issue_101973.inner.ConstProp.diff new file mode 100644 index 000000000..b2706e5a4 --- /dev/null +++ b/tests/mir-opt/issue_101973.inner.ConstProp.diff @@ -0,0 +1,95 @@ +- // MIR for `inner` before ConstProp ++ // MIR for `inner` after ConstProp + + fn inner(_1: u32) -> i64 { + debug fields => _1; // in scope 0 at $DIR/issue_101973.rs:+0:14: +0:20 + let mut _0: i64; // return place in scope 0 at $DIR/issue_101973.rs:+0:30: +0:33 + let mut _2: i32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + let mut _3: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:58 + let mut _4: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:17 + let mut _5: u32; // in scope 0 at $DIR/issue_101973.rs:+1:10: +1:16 + let mut _6: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + let mut _7: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + let mut _8: u32; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _9: u32; // in scope 0 at $DIR/issue_101973.rs:+1:33: +1:39 + let mut _10: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _11: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + scope 1 (inlined imm8) { // at $DIR/issue_101973.rs:14:5: 14:17 + debug x => _5; // in scope 1 at $DIR/issue_101973.rs:5:13: 5:14 + let mut _12: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:27 + let mut _13: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20 + let mut _14: (u32, bool); // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20 + scope 2 { + debug out => _4; // in scope 2 at $DIR/issue_101973.rs:6:9: 6:16 + } + } + scope 3 (inlined core::num::<impl u32>::rotate_right) { // at $DIR/issue_101973.rs:14:18: 14:58 + debug self => _4; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug n => _6; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _15: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _16: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + StorageLive(_3); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:58 + StorageLive(_4); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:17 + StorageLive(_5); // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16 + _5 = _1; // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16 + StorageLive(_12); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 + StorageLive(_13); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + _14 = CheckedShr(_5, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + assert(!move (_14.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + } + + bb1: { + _8 = move (_10.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + StorageDead(_9); // scope 0 at $DIR/issue_101973.rs:+1:44: +1:45 + _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + StorageDead(_8); // scope 0 at $DIR/issue_101973.rs:+1:51: +1:52 + _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + } + + bb2: { + _6 = move (_11.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + StorageDead(_7); // scope 0 at $DIR/issue_101973.rs:+1:56: +1:57 + StorageLive(_15); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _15 = _4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageLive(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _16 = _6; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _3 = rotate_right::<u32>(move _15, move _16) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // + literal: Const { ty: extern "rust-intrinsic" fn(u32, u32) -> u32 {rotate_right::<u32>}, val: Value(<ZST>) } + } + + bb3: { + _13 = move (_14.0: u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 + StorageDead(_13); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 + _4 = BitOr(const 0_u32, move _12); // scope 2 at $DIR/issue_101973.rs:7:5: 7:27 + StorageDead(_12); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 + StorageDead(_5); // scope 0 at $DIR/issue_101973.rs:+1:16: +1:17 + StorageLive(_6); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + StorageLive(_7); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + StorageLive(_8); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + StorageLive(_9); // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39 + _9 = _1; // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39 + _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + } + + bb4: { + StorageDead(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageDead(_15); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageDead(_6); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 + StorageDead(_4); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 + _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 + StorageDead(_3); // scope 0 at $DIR/issue_101973.rs:+1:64: +1:65 + _0 = move _2 as i64 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:72 + StorageDead(_2); // scope 0 at $DIR/issue_101973.rs:+1:71: +1:72 + return; // scope 0 at $DIR/issue_101973.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/issue_101973.rs b/tests/mir-opt/issue_101973.rs new file mode 100644 index 000000000..216659a23 --- /dev/null +++ b/tests/mir-opt/issue_101973.rs @@ -0,0 +1,20 @@ +// compile-flags: -O -C debug-assertions=on +// This needs inlining followed by ConstProp to reproduce, so we cannot use "unit-test". + +#[inline] +pub fn imm8(x: u32) -> u32 { + let mut out = 0u32; + out |= (x >> 0) & 0xff; + out +} + +// EMIT_MIR issue_101973.inner.ConstProp.diff +#[inline(never)] +pub fn inner(fields: u32) -> i64 { + imm8(fields).rotate_right(((fields >> 8) & 0xf) << 1) as i32 as i64 +} + +fn main() { + let val = inner(0xe32cf20f); + assert_eq!(val as u64, 0xfffffffff0000000); +} diff --git a/tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..b0d5b291b --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/issue_38669.rs b/tests/mir-opt/issue_38669.rs new file mode 100644 index 000000000..db3f89472 --- /dev/null +++ b/tests/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/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir new file mode 100644 index 000000000..c2ea3ac50 --- /dev/null +++ b/tests/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) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + } +} diff --git a/tests/mir-opt/issue_41110.rs b/tests/mir-opt/issue_41110.rs new file mode 100644 index 000000000..638dc601e --- /dev/null +++ b/tests/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/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir new file mode 100644 index 000000000..82989c3f0 --- /dev/null +++ b/tests/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) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } +} diff --git a/tests/mir-opt/issue_41697.rs b/tests/mir-opt/issue_41697.rs new file mode 100644 index 000000000..cbd8633a3 --- /dev/null +++ b/tests/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 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/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir b/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir new file mode 100644 index 000000000..8af087d84 --- /dev/null +++ b/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.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/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir new file mode 100644 index 000000000..005042732 --- /dev/null +++ b/tests/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) -> [0: 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: 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: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + + bb20: { + switchInt(_7) -> [0: 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: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + + bb22 (cleanup): { + switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } +} diff --git a/tests/mir-opt/issue_41888.rs b/tests/mir-opt/issue_41888.rs new file mode 100644 index 000000000..c1046c14d --- /dev/null +++ b/tests/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/tests/mir-opt/issue_62289.rs b/tests/mir-opt/issue_62289.rs new file mode 100644 index 000000000..37e3390d5 --- /dev/null +++ b/tests/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/tests/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.mir new file mode 100644 index 000000000..adfa3a773 --- /dev/null +++ b/tests/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: bb3, 1: 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/tests/mir-opt/issue_72181.bar.built.after.mir b/tests/mir-opt/issue_72181.bar.built.after.mir new file mode 100644 index 000000000..ebee89001 --- /dev/null +++ b/tests/mir-opt/issue_72181.bar.built.after.mir @@ -0,0 +1,17 @@ +// MIR for `bar` after built + +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/tests/mir-opt/issue_72181.foo.built.after.mir b/tests/mir-opt/issue_72181.foo.built.after.mir new file mode 100644 index 000000000..90c978520 --- /dev/null +++ b/tests/mir-opt/issue_72181.foo.built.after.mir @@ -0,0 +1,27 @@ +// MIR for `foo` after built + +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/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir new file mode 100644 index 000000000..e86836927 --- /dev/null +++ b/tests/mir-opt/issue_72181.main.built.after.mir @@ -0,0 +1,62 @@ +// MIR for `main` after built + +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/tests/mir-opt/issue_72181.rs b/tests/mir-opt/issue_72181.rs new file mode 100644 index 000000000..6a32d4bbe --- /dev/null +++ b/tests/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 issue_72181.foo.built.after.mir +fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 } + +// EMIT_MIR issue_72181.bar.built.after.mir +fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x } + + +// EMIT_MIR issue_72181.main.built.after.mir +fn main() { + let _ = mem::size_of::<Foo>(); + + let f = [Foo { a: 42 }, Foo { a: 10 }]; + let _ = unsafe { f[0].a }; +} diff --git a/tests/mir-opt/issue_72181_1.f.built.after.mir b/tests/mir-opt/issue_72181_1.f.built.after.mir new file mode 100644 index 000000000..4086da520 --- /dev/null +++ b/tests/mir-opt/issue_72181_1.f.built.after.mir @@ -0,0 +1,29 @@ +// MIR for `f` after built + +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/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir new file mode 100644 index 000000000..2172f3aa9 --- /dev/null +++ b/tests/mir-opt/issue_72181_1.main.built.after.mir @@ -0,0 +1,57 @@ +// MIR for `main` after built + +| 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/tests/mir-opt/issue_72181_1.rs b/tests/mir-opt/issue_72181_1.rs new file mode 100644 index 000000000..8ae2599ec --- /dev/null +++ b/tests/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.built.after.mir +fn f(v: Void) -> ! { + match v {} +} + +// EMIT_MIR issue_72181_1.main.built.after.mir +fn main() { + let v: Void = unsafe { + std::mem::transmute::<(), Void>(()) + }; + + f(v); +} diff --git a/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff new file mode 100644 index 000000000..bf3bcfdb5 --- /dev/null +++ b/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff @@ -0,0 +1,156 @@ +- // 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 _6: i32; // in scope 0 at $DIR/issue_73223.rs:+6:22: +6:27 + let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _8: &i32; // 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: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _13: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _14: i32; // 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: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _19: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _20: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: &i32; // 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 mut _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 + scope 1 { + debug split => _1; // in scope 1 at $DIR/issue_73223.rs:+1:9: +1:14 + let _5: std::option::Option<i32>; // in scope 1 at $DIR/issue_73223.rs:+6:9: +6:14 + scope 3 { + debug _prev => _5; // in scope 3 at $DIR/issue_73223.rs:+6:9: +6:14 + let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _10: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 4 { + debug left_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _10; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _15: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 5 { + debug kind => _15; // 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 -> bb3; // scope 0 at $DIR/issue_73223.rs:+1:17: +1:30 + } + + bb1: { + 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: { + unreachable; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 + } + + bb3: { + 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(_5); // scope 1 at $DIR/issue_73223.rs:+6:9: +6:14 + StorageLive(_6); // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27 + _6 = _1; // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27 + Deinit(_5); // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + ((_5 as Some).0: i32) = move _6; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + discriminant(_5) = 1; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + StorageDead(_6); // scope 1 at $DIR/issue_73223.rs:+6:27: +6:28 + StorageLive(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // 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 + _7 = &_1; // 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 + _23 = const _; // 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])) } + _8 = _23; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = move _8; // 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(_7); // 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 = _24; // 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 = _25; // scope 3 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 + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = (*_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _12 = Eq(move _13, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = Not(move _12); // 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 + switchInt(move _11) -> [0: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb4: { + StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_15) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_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 + _17 = 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(_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 + _19 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = _19; // 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 + StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = _10; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _20 = _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 + Deinit(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_22) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _18, move _20, move _22); // 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<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a i32, &'b i32, Option<Arguments<'c>>) -> ! {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)) } + } + + bb5: { + StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_10); // 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(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_5); // 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/tests/mir-opt/issue_73223.rs b/tests/mir-opt/issue_73223.rs new file mode 100644 index 000000000..be114cab7 --- /dev/null +++ b/tests/mir-opt/issue_73223.rs @@ -0,0 +1,12 @@ +fn main() { + let split = match Some(1) { + Some(v) => v, + None => return, + }; + + let _prev = Some(split); + assert_eq!(split, 1); +} + + +// EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff diff --git a/tests/mir-opt/issue_76432.rs b/tests/mir-opt/issue_76432.rs new file mode 100644 index 000000000..c8b405ca8 --- /dev/null +++ b/tests/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/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000..c24543dae --- /dev/null +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -0,0 +1,84 @@ +- // 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 mut _9: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _10: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _11: bool; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _15: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL + scope 1 { + debug v => _2; // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10 + let _12: &T; // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + scope 2 { + debug v1 => _12; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16 + debug v2 => _13; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24 + debug v3 => _14; // 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 + _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 + _9 = Len((*_2)); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + _10 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 +- _11 = Eq(move _9, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 +- switchInt(move _11) -> [0: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 ++ nop; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 ++ switchInt(move _9) -> [3: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + } + + bb1: { + StorageLive(_15); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL + _15 = 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(_12); // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + _12 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + _13 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + _14 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + 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(_12); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 + 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/tests/mir-opt/issue_78192.f.InstCombine.diff b/tests/mir-opt/issue_78192.f.InstCombine.diff new file mode 100644 index 000000000..116ca304c --- /dev/null +++ b/tests/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/tests/mir-opt/issue_78192.rs b/tests/mir-opt/issue_78192.rs new file mode 100644 index 000000000..39f665402 --- /dev/null +++ b/tests/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/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir new file mode 100644 index 000000000..c3fb90e84 --- /dev/null +++ b/tests/mir-opt/issue_91633.bar.built.after.mir @@ -0,0 +1,39 @@ +// MIR for `bar` after built + +fn bar(_1: Box<[T]>) -> () { + debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14 + let mut _0: (); // return place in scope 0 at $DIR/issue_91633.rs:+1:2: +1:2 + let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:19 + let mut _3: &[T]; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:16 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19 + StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:16 + _3 = &(*_1); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:16 + _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19 + // mir::Constant + // + span: $DIR/issue_91633.rs:15:14: 15:19 + // + literal: Const { ty: for<'a> fn(&'a [T], usize) -> &'a <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:18: +4:19 + StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20 + _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3 + drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3 + } + + bb2: { + return; // scope 0 at $DIR/issue_91633.rs:+5:3: +5:3 + } + + bb3 (cleanup): { + drop(_1) -> bb4; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3 + } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +5:3 + } +} diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir new file mode 100644 index 000000000..4e3dd365e --- /dev/null +++ b/tests/mir-opt/issue_91633.foo.built.after.mir @@ -0,0 +1,57 @@ +// MIR for `foo` after built + +fn foo(_1: Box<[T]>) -> T { + debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:19: +0:21 + let mut _0: T; // return place in scope 0 at $DIR/issue_91633.rs:+0:36: +0:37 + let _2: T; // in scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + let mut _3: &T; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:27 + let _4: usize; // in scope 0 at $DIR/issue_91633.rs:+2:17: +2:18 + let mut _5: usize; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 + let mut _6: bool; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 + scope 1 { + debug f => _2; // in scope 1 at $DIR/issue_91633.rs:+2:10: +2:11 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27 + StorageLive(_4); // scope 0 at $DIR/issue_91633.rs:+2:17: +2:18 + _4 = const 0_usize; // scope 0 at $DIR/issue_91633.rs:+2:17: +2:18 + _5 = Len((*_1)); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 + _6 = Lt(_4, _5); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 + assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19 + } + + bb1: { + _3 = &(*_1)[_4]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27 + _2 = <T as Clone>::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27 + // mir::Constant + // + span: $DIR/issue_91633.rs:28:20: 28:25 + // + literal: Const { ty: for<'a> fn(&'a T) -> T {<T as Clone>::clone}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+2:26: +2:27 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+2:27: +2:28 + _0 = move _2; // scope 1 at $DIR/issue_91633.rs:+3:6: +3:7 + drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + } + + bb4: { + return; // scope 0 at $DIR/issue_91633.rs:+4:3: +4:3 + } + + bb5 (cleanup): { + drop(_1) -> bb6; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +4:3 + } +} diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir new file mode 100644 index 000000000..42486d3a5 --- /dev/null +++ b/tests/mir-opt/issue_91633.fun.built.after.mir @@ -0,0 +1,35 @@ +// MIR for `fun` after built + +fn fun(_1: &[T]) -> &T { + debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14 + let mut _0: &T; // return place in scope 0 at $DIR/issue_91633.rs:+0:25: +0:27 + let _2: &T; // in scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + let _3: usize; // in scope 0 at $DIR/issue_91633.rs:+2:18: +2:19 + let mut _4: usize; // in scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 + let mut _5: bool; // in scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 + scope 1 { + debug f => _2; // in scope 1 at $DIR/issue_91633.rs:+2:10: +2:11 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+2:18: +2:19 + _3 = const 0_usize; // scope 0 at $DIR/issue_91633.rs:+2:18: +2:19 + _4 = Len((*_1)); // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 + _5 = Lt(_3, _4); // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20 + } + + bb1: { + _2 = &(*_1)[_3]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:20 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11 + _0 = &(*_2); // scope 1 at $DIR/issue_91633.rs:+3:6: +3:7 + StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3 + return; // scope 0 at $DIR/issue_91633.rs:+4:3: +4:3 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +4:3 + } +} diff --git a/tests/mir-opt/issue_91633.hey.built.after.mir b/tests/mir-opt/issue_91633.hey.built.after.mir new file mode 100644 index 000000000..ccb06dd59 --- /dev/null +++ b/tests/mir-opt/issue_91633.hey.built.after.mir @@ -0,0 +1,35 @@ +// MIR for `hey` after built + +fn hey(_1: &[T]) -> () { + debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14 + let mut _0: (); // return place in scope 0 at $DIR/issue_91633.rs:+1:2: +1:2 + let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:20 + let _3: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:15: +4:20 + let mut _4: &[T]; // in scope 0 at $DIR/issue_91633.rs:+4:15: +4:17 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20 + StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:20 + StorageLive(_4); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:17 + _4 = &(*_1); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:17 + _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue_91633.rs:+4:15: +4:20 + // mir::Constant + // + span: $DIR/issue_91633.rs:7:15: 7:20 + // + literal: Const { ty: for<'a> fn(&'a [T], usize) -> &'a <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20 + _2 = &(*_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20 + StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:20: +4:21 + _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3 + StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3 + return; // scope 0 at $DIR/issue_91633.rs:+5:3: +5:3 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +5:3 + } +} diff --git a/tests/mir-opt/issue_91633.rs b/tests/mir-opt/issue_91633.rs new file mode 100644 index 000000000..9127cacc9 --- /dev/null +++ b/tests/mir-opt/issue_91633.rs @@ -0,0 +1,31 @@ +// compile-flags: -Z mir-opt-level=0 +// EMIT_MIR issue_91633.hey.built.after.mir +fn hey<T> (it: &[T]) + where + [T] : std::ops::Index<usize>, + { + let _ = &it[0]; + } + +// EMIT_MIR issue_91633.bar.built.after.mir +fn bar<T> (it: Box<[T]>) + where + [T] : std::ops::Index<usize>, + { + let _ = it[0]; + } + +// EMIT_MIR issue_91633.fun.built.after.mir +fn fun<T> (it: &[T]) -> &T + { + let f = &it[0]; + f + } + +// EMIT_MIR issue_91633.foo.built.after.mir +fn foo<T: Clone> (it: Box<[T]>) -> T + { + let f = it[0].clone(); + f + } + fn main(){} diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir new file mode 100644 index 000000000..3e035c18d --- /dev/null +++ b/tests/mir-opt/issue_99325.main.built.after.mir @@ -0,0 +1,295 @@ +// MIR for `main` after built + +| 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(UnevaluatedConst { 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: [] }) }], 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<'a, 'b> fn(&'a &[u8], &'b &[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) -> [0: 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<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a &[u8], &'b &[u8; 4], Option<Arguments<'c>>) -> ! {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<'a, 'b> fn(&'a &[u8], &'b &[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) -> [0: 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<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a &[u8], &'b &[u8; 4], Option<Arguments<'c>>) -> ! {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/tests/mir-opt/issue_99325.rs b/tests/mir-opt/issue_99325.rs new file mode 100644 index 000000000..fe819cddb --- /dev/null +++ b/tests/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.built.after.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/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir new file mode 100644 index 000000000..c17d221f8 --- /dev/null +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -0,0 +1,92 @@ +// 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: std::option::Option<u32>; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 + let mut _3: u32; // in scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 + let mut _9: 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:12: 14:23 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + debug radix => _3; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let mut _4: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let _5: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let mut _6: 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 => _4; // 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:42: 14:50 + debug self => _2; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _8: !; // 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(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 + StorageLive(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageLive(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageLive(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _6 = _1; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _5 = char::methods::<impl char>::to_digit(move _6, 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: { + StorageLive(_2); // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 + _2 = char::methods::<impl char>::to_digit(move _1, 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: { + _7 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _7) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb3: { + _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: { + _4 = &_5; // 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 + _9 = discriminant((*_4)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageDead(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 + switchInt(move _9) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + } + + bb6: { + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + _8 = 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 ((_2 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_2); // 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/tests/mir-opt/issues/issue_59352.rs b/tests/mir-opt/issues/issue_59352.rs new file mode 100644 index 000000000..1e0045555 --- /dev/null +++ b/tests/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/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff new file mode 100644 index 000000000..938047803 --- /dev/null +++ b/tests/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:8:37: 8: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: bb2, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 + } + + bb2: { + switchInt(_2[1 of 4]) -> [0: bb3, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 + } + + bb3: { + switchInt(_2[2 of 4]) -> [0: bb5, 4294901760: 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:11:23: 11: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/tests/mir-opt/issues/issue_75439.rs b/tests/mir-opt/issues/issue_75439.rs new file mode 100644 index 000000000..4c749a150 --- /dev/null +++ b/tests/mir-opt/issues/issue_75439.rs @@ -0,0 +1,19 @@ +// EMIT_MIR issue_75439.foo.MatchBranchSimplification.diff +// ignore-endian-big + +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/tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir new file mode 100644 index 000000000..4ee2dae49 --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/loop_test.rs b/tests/mir-opt/loop_test.rs new file mode 100644 index 000000000..7ded5b575 --- /dev/null +++ b/tests/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/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff new file mode 100644 index 000000000..9bc7060e9 --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff new file mode 100644 index 000000000..cf427cfd1 --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff new file mode 100644 index 000000000..3ed68f5f7 --- /dev/null +++ b/tests/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/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff new file mode 100644 index 000000000..f0e0cdcfd --- /dev/null +++ b/tests/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/tests/mir-opt/lower_array_len.rs b/tests/mir-opt/lower_array_len.rs new file mode 100644 index 000000000..ea0224b21 --- /dev/null +++ b/tests/mir-opt/lower_array_len.rs @@ -0,0 +1,40 @@ +// unit-test: NormalizeArrayLen +// compile-flags: -Zmir-enable-passes=+LowerSliceLenCalls + +// EMIT_MIR lower_array_len.array_bound.NormalizeArrayLen.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 +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 +pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize { + arr.len() +} + +// EMIT_MIR lower_array_len.array_len_by_value.NormalizeArrayLen.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/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir new file mode 100644 index 000000000..701c2ad70 --- /dev/null +++ b/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir @@ -0,0 +1,45 @@ +// MIR for `array_bound` after PreCodegen + +fn array_bound(_1: usize, _2: &[u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:36: +0:41 + debug slice => _2; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:50: +0:55 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:70: +0:72 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27 + let mut _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + let mut _7: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27 + _5 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27 + switchInt(move _3) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + } + + bb1: { + _6 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + _7 = Lt(_1, _6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + } + + bb2: { + _0 = (*_2)[_1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6 + } + + bb3: { + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:11 + goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6 + } + + bb4: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+5:5: +5:6 + return; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:2: +6:2 + } +} diff --git a/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir new file mode 100644 index 000000000..0440cfce2 --- /dev/null +++ b/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir @@ -0,0 +1,58 @@ +// MIR for `array_bound_mut` after PreCodegen + +fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 { + debug index => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:40: +0:45 + debug slice => _2; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:54: +0:59 + let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:78: +0:80 + let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13 + let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27 + let mut _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + let mut _7: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + let _8: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16 + let mut _9: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17 + let mut _10: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17 + + bb0: { + StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + StorageLive(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13 + _4 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13 + StorageLive(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27 + _5 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27 + _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27 + StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27 + switchInt(move _3) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + } + + bb1: { + _6 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + _7 = Lt(_1, _6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + } + + bb2: { + _0 = (*_2)[_1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21 + goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6 + } + + bb3: { + StorageLive(_8); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16 + _8 = const 0_usize; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16 + _9 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17 + _10 = Lt(const 0_usize, _9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17 + assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17 + } + + bb4: { + (*_2)[_8] = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:22 + StorageDead(_8); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:22: +4:23 + _0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:9: +6:11 + goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6 + } + + bb5: { + StorageDead(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+7:5: +7:6 + return; // scope 0 at $DIR/lower_array_len_e2e.rs:+8:2: +8:2 + } +} diff --git a/tests/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir new file mode 100644 index 000000000..4b19f6795 --- /dev/null +++ b/tests/mir-opt/lower_array_len_e2e.array_len.PreCodegen.after.mir @@ -0,0 +1,11 @@ +// MIR for `array_len` after PreCodegen + +fn array_len(_1: &[u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:34: +0:37 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:52: +0:57 + + bb0: { + _0 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +1:14 + return; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir new file mode 100644 index 000000000..4dc0ba9a2 --- /dev/null +++ b/tests/mir-opt/lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir @@ -0,0 +1,11 @@ +// MIR for `array_len_by_value` after PreCodegen + +fn array_len_by_value(_1: [u8; N]) -> usize { + debug arr => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:43: +0:46 + let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:60: +0:65 + + bb0: { + _0 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +1:14 + return; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/lower_array_len_e2e.rs b/tests/mir-opt/lower_array_len_e2e.rs new file mode 100644 index 000000000..d8e4e521e --- /dev/null +++ b/tests/mir-opt/lower_array_len_e2e.rs @@ -0,0 +1,39 @@ +// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts + +// EMIT_MIR lower_array_len_e2e.array_bound.PreCodegen.after.mir +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_e2e.array_bound_mut.PreCodegen.after.mir +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_e2e.array_len.PreCodegen.after.mir +pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize { + arr.len() +} + +// EMIT_MIR lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir +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/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff new file mode 100644 index 000000000..3389db733 --- /dev/null +++ b/tests/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:21:5: 21: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/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff new file mode 100644 index 000000000..d9898d8e0 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff @@ -0,0 +1,26 @@ +- // MIR for `assume` before LowerIntrinsics ++ // MIR for `assume` after LowerIntrinsics + + fn assume() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17 + let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:38 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 +- _1 = std::intrinsics::assume(const true) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:72:9: 72:32 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(bool) {std::intrinsics::assume}, val: Value(<ZST>) } ++ assume(const true); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 + } + + bb1: { + StorageDead(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:38: +2:39 + _0 = const (); // scope 1 at $DIR/lower_intrinsics.rs:+1:5: +3:6 + return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff new file mode 100644 index 000000000..d962ef8cb --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -0,0 +1,119 @@ +- // 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:49:5: 49:41 +- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a 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 _; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:50:42: 50: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:50:5: 50:41 +- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a 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 _; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:51:42: 51: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:51:5: 51:41 +- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a ()) -> <() 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 _; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:52:42: 52: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:52:5: 52:41 +- // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a 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) -> [return: bb5, unwind: bb6]; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2 + } + + bb5: { + return; // scope 0 at $DIR/lower_intrinsics.rs:+5:2: +5:2 + } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/lower_intrinsics.rs:+0:1: +5:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff new file mode 100644 index 000000000..ec15fd1ef --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff @@ -0,0 +1,72 @@ +- // MIR for `f_copy_nonoverlapping` before LowerIntrinsics ++ // MIR for `f_copy_nonoverlapping` after LowerIntrinsics + + fn f_copy_nonoverlapping() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:32: +0:32 + let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + let _3: (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + let mut _4: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + let mut _5: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + let mut _6: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + let _7: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + let mut _8: *mut i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + let mut _9: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + let mut _10: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + let mut _11: &mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + scope 1 { + debug src => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + let mut _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + scope 2 { + debug dst => _2; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + scope 3 { + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + Deinit(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:15: +1:17 + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + Deinit(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:19: +2:21 + StorageLive(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + StorageLive(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + StorageLive(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + StorageLive(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + StorageLive(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _7 = &_1; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _6 = &raw const (*_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _5 = _6; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + _4 = move _5 as *const i32 (PtrToPtr); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + StorageDead(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:58: +4:59 + StorageLive(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + StorageLive(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + StorageLive(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + StorageLive(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _11 = &mut _2; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _10 = &raw mut (*_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _9 = _10; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + _8 = move _9 as *mut i32 (PtrToPtr); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + StorageDead(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:90: +4:91 +- _3 = copy_nonoverlapping::<i32>(move _4, move _8, const 0_usize) -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:65:9: 65:28 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, *mut i32, usize) {copy_nonoverlapping::<i32>}, val: Value(<ZST>) } ++ copy_nonoverlapping(dst = move _8, src = move _4, count = const 0_usize); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 ++ goto -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + } + + bb1: { + StorageDead(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95 + StorageDead(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95 + StorageDead(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + _0 = const (); // scope 3 at $DIR/lower_intrinsics.rs:+3:5: +5:6 + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+6:1: +6:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff new file mode 100644 index 000000000..4cbbc02c9 --- /dev/null +++ b/tests/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:26:5: 26: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/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff new file mode 100644 index 000000000..d8cd5f59a --- /dev/null +++ b/tests/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:37:21: 37: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/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs new file mode 100644 index 000000000..66dae0e46 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.rs @@ -0,0 +1,74 @@ +// unit-test: LowerIntrinsics +// ignore-wasm32 compiled with panic=abort by default + +#![feature(core_intrinsics, 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.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); +} + +extern "rust-intrinsic" { + // Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function + fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); +} + +// EMIT_MIR lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff +pub fn f_copy_nonoverlapping() { + let src = (); + let mut dst = (); + unsafe { + copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0); + } +} + +// EMIT_MIR lower_intrinsics.assume.LowerIntrinsics.diff +pub fn assume() { + unsafe { + std::intrinsics::assume(true); + } +} diff --git a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff new file mode 100644 index 000000000..cf0ab73a5 --- /dev/null +++ b/tests/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:16:5: 16: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/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff new file mode 100644 index 000000000..6f17d4451 --- /dev/null +++ b/tests/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:31:14: 31: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/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff new file mode 100644 index 000000000..22ef75fd8 --- /dev/null +++ b/tests/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:9:14: 9: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:10:14: 10: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:11:14: 11: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/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir new file mode 100644 index 000000000..f6d8bdd74 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir @@ -0,0 +1,27 @@ +// MIR for `f_u64` after PreCodegen + +fn f_u64() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:16: +0:16 + let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 + scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21 + debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23 + let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 + scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 + _2 = f_non_zst::<u64>(const 0_u64) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 + // mir::Constant + // + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18 + // + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:21: 23:22 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 + return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir b/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir new file mode 100644 index 000000000..b672e1a6e --- /dev/null +++ b/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir @@ -0,0 +1,27 @@ +// MIR for `f_unit` after PreCodegen + +fn f_unit() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:17: +0:17 + let mut _1: (); // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18 + scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics_e2e.rs:9:5: 9:19 + debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23 + let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17 + scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18 + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17 + _2 = f_zst::<()>(move _1) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17 + // mir::Constant + // + span: $DIR/lower_intrinsics_e2e.rs:21:9: 21:14 + // + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:17: 21:18 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:18: +1:19 + return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/lower_intrinsics_e2e.rs b/tests/mir-opt/lower_intrinsics_e2e.rs new file mode 100644 index 000000000..872ef59b0 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics_e2e.rs @@ -0,0 +1,32 @@ +// Checks that we do not have any branches in the MIR for the two tested functions. + +// compile-flags: -Cpanic=abort +#![feature(core_intrinsics)] +#![crate_type = "lib"] + +// EMIT_MIR lower_intrinsics_e2e.f_unit.PreCodegen.after.mir +pub fn f_unit() { + f_dispatch(()); +} + + +// EMIT_MIR lower_intrinsics_e2e.f_u64.PreCodegen.after.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) {} diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff new file mode 100644 index 000000000..2b0370cf3 --- /dev/null +++ b/tests/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<'a> fn(&'a [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) -> [0: 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/tests/mir-opt/lower_slice_len.rs b/tests/mir-opt/lower_slice_len.rs new file mode 100644 index 000000000..12955aed1 --- /dev/null +++ b/tests/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/tests/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff new file mode 100644 index 000000000..84e4d35f9 --- /dev/null +++ b/tests/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)) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [0: 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)) -> [0: bb10, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 + } + + bb2: { +- switchInt((_2.1: bool)) -> [0: bb3, otherwise: bb4]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [0: 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)) -> [0: 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) -> [0: bb10, otherwise: bb9]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 ++ switchInt(move _10) -> [0: 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) -> [0: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ switchInt(move _9) -> [0: 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) -> [0: bb15, otherwise: bb14]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 ++ switchInt(move _13) -> [0: 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) -> [0: bb17, otherwise: bb16]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ switchInt(move _12) -> [0: 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/tests/mir-opt/match_arm_scopes.rs b/tests/mir-opt/match_arm_scopes.rs new file mode 100644 index 000000000..7b7de7788 --- /dev/null +++ b/tests/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/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir new file mode 100644 index 000000000..d51dbf425 --- /dev/null +++ b/tests/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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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) -> [4294967295: 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) -> [0: 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/tests/mir-opt/match_test.rs b/tests/mir-opt/match_test.rs new file mode 100644 index 000000000..3a2107790 --- /dev/null +++ b/tests/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/tests/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff new file mode 100644 index 000000000..be91b0bfe --- /dev/null +++ b/tests/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.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: 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 +- Deinit(_6); // 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 + Deinit(_6); // 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/tests/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff new file mode 100644 index 000000000..aa8092ece --- /dev/null +++ b/tests/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff @@ -0,0 +1,55 @@ +- // 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: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26 ++ let mut _4: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + + bb0: { + StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20 +- switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ _4 = move _3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ _2 = Eq(_4, const 0_isize); // 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 ++ switchInt(move _2) -> [0: 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 +- } +- +- 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) -> [0: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- } +- +- bb4: { + Deinit(_0); // scope 0 at $DIR/matches_reduce_branches.rs:+2:9: +2:11 +- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6 ++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6 + } + +- bb5: { ++ bb2: { + _0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:+3:6: +3:6 +- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6 ++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6 + } + +- bb6: { ++ bb3: { + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+3:5: +3:6 + return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff new file mode 100644 index 000000000..193104dd3 --- /dev/null +++ b/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff @@ -0,0 +1,113 @@ +- // 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: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23 + let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 + let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 + let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 + let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 ++ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 ++ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 ++ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 ++ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 + 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:+1:21: +1:23 + Deinit(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23 + StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 + StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 + StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 + StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + _6 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 +- switchInt(move _6) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 +- } +- +- bb1: { +- _5 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:31: +2:35 +- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 +- } +- +- bb2: { +- _5 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50 +- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 +- } +- +- bb3: { ++ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 ++ _7 = move _6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 ++ _5 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50 ++ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 + StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52 +- switchInt(move _5) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 +- } +- +- bb4: { +- _4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:55: +2:59 +- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 +- } +- +- bb5: { +- _4 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74 +- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 +- } +- +- bb6: { ++ StorageLive(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 ++ _8 = move _5; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 ++ _4 = Ne(_8, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74 ++ StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 + StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76 +- switchInt(move _4) -> [0: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 +- } +- +- bb7: { +- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+3:13: +3:17 +- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 +- } +- +- bb8: { +- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18 +- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 +- } +- +- bb9: { +- switchInt(move _3) -> [0: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 +- } +- +- bb10: { ++ StorageLive(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 ++ _9 = move _4; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 ++ _3 = Ne(_9, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18 ++ StorageDead(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 ++ StorageLive(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 ++ _10 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 + StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10 + StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10 +- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17 +- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17 +- } +- +- bb11: { +- StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10 +- StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10 +- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 +- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 +- } +- +- bb12: { ++ _1 = Ne(_10, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19 ++ StorageDead(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+11:6: +11:7 + _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/tests/mir-opt/matches_reduce_branches.rs b/tests/mir-opt/matches_reduce_branches.rs new file mode 100644 index 000000000..a81d5f7b4 --- /dev/null +++ b/tests/mir-opt/matches_reduce_branches.rs @@ -0,0 +1,60 @@ +// unit-test: MatchBranchSimplification + + +// EMIT_MIR matches_reduce_branches.foo.MatchBranchSimplification.diff +// 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/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff b/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff new file mode 100644 index 000000000..3766d99a4 --- /dev/null +++ b/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff @@ -0,0 +1,32 @@ +- // 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: bb3, 1: bb1, otherwise: bb2]; // 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 -> bb4; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + } + + bb2: { + unreachable; // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12 + } + + bb3: { + _0 = const 0_u8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + } + + bb4: { + return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff b/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff new file mode 100644 index 000000000..b5146cd53 --- /dev/null +++ b/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff @@ -0,0 +1,32 @@ +- // 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: bb3, 1: bb1, otherwise: bb2]; // 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 -> bb4; // scope 0 at $DIR/matches_u8.rs:+3:17: +3:18 + } + + bb2: { + unreachable; // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12 + } + + bb3: { + _0 = const 0_i8; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + goto -> bb4; // scope 0 at $DIR/matches_u8.rs:+2:17: +2:18 + } + + bb4: { + return; // scope 0 at $DIR/matches_u8.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/matches_u8.rs b/tests/mir-opt/matches_u8.rs new file mode 100644 index 000000000..422c3a95e --- /dev/null +++ b/tests/mir-opt/matches_u8.rs @@ -0,0 +1,34 @@ +// unit-test: MatchBranchSimplification + + +// 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/tests/mir-opt/multiple_return_terminators.rs b/tests/mir-opt/multiple_return_terminators.rs new file mode 100644 index 000000000..a2b902d14 --- /dev/null +++ b/tests/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/tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff b/tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff new file mode 100644 index 000000000..48a11c950 --- /dev/null +++ b/tests/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/tests/mir-opt/nll/named_lifetimes_basic.rs b/tests/mir-opt/nll/named_lifetimes_basic.rs new file mode 100644 index 000000000..843716033 --- /dev/null +++ b/tests/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/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir new file mode 100644 index 000000000..6cd6d8b77 --- /dev/null +++ b/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir @@ -0,0 +1,47 @@ +// 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 | {bb0[0..=1], '_#1r} +| '_#6r | U0 | {bb0[0..=1], '_#2r} +| '_#7r | U0 | {bb0[0..=1], '_#1r} +| '_#8r | 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: '_#5r 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: '_#7r 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: '_#6r 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: '_#8r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0) +| '_#5r: '_#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) +| '_#6r: '_#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) +| '_#7r: '_#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) +| '_#8r: '_#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: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r 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/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir new file mode 100644 index 000000000..798e45df8 --- /dev/null +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -0,0 +1,111 @@ +// 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 | {bb1[0..=7], bb2[0..=2]} +| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]} +| '_#4r | 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]} +| '_#2r live at {bb1[0]} +| '_#3r live at {bb1[1..=3]} +| '_#4r live at {bb1[4..=7], bb2[0..=2]} +| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0) +| '_#3r: '_#4r 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(Value(Leaf(0x00000003)): usize)]; // 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: &'_#3r 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: &'_#4r 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 = &'_#2r _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) -> [0: 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/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir new file mode 100644 index 000000000..4767bfc76 --- /dev/null +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -0,0 +1,111 @@ +// 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 | {bb1[0..=7], bb2[0..=2]} +| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]} +| '_#4r | 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]} +| '_#2r live at {bb1[0]} +| '_#3r live at {bb1[1..=3]} +| '_#4r live at {bb1[4..=7], bb2[0..=2]} +| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0) +| '_#3r: '_#4r 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(Value(Leaf(0x0000000000000003)): usize)]; // 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: &'_#3r 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: &'_#4r 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 = &'_#2r _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) -> [0: 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/tests/mir-opt/nll/region_subtyping_basic.rs b/tests/mir-opt/nll/region_subtyping_basic.rs new file mode 100644 index 000000000..64332f302 --- /dev/null +++ b/tests/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/tests/mir-opt/no_drop_for_inactive_variant.rs b/tests/mir-opt/no_drop_for_inactive_variant.rs new file mode 100644 index 000000000..34e2b1a13 --- /dev/null +++ b/tests/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/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..69327b7af --- /dev/null +++ b/tests/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: bb1, 1: 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/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir new file mode 100644 index 000000000..0cb34a2f2 --- /dev/null +++ b/tests/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<'a> fn(&'a 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/tests/mir-opt/no_spurious_drop_after_call.rs b/tests/mir-opt/no_spurious_drop_after_call.rs new file mode 100644 index 000000000..bb5bb9aa4 --- /dev/null +++ b/tests/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/tests/mir-opt/not_equal_false.opt.InstCombine.diff b/tests/mir-opt/not_equal_false.opt.InstCombine.diff new file mode 100644 index 000000000..b558c35ac --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/not_equal_false.rs b/tests/mir-opt/not_equal_false.rs new file mode 100644 index 000000000..2ae03da40 --- /dev/null +++ b/tests/mir-opt/not_equal_false.rs @@ -0,0 +1,10 @@ +// unit-test: InstCombine +// 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/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff new file mode 100644 index 000000000..61a16065b --- /dev/null +++ b/tests/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<'a> fn(&'a 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<'a> fn(&'a 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/tests/mir-opt/nrvo_simple.rs b/tests/mir-opt/nrvo_simple.rs new file mode 100644 index 000000000..5786ae621 --- /dev/null +++ b/tests/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/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..e52253486 --- /dev/null +++ b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,60 @@ +// 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 + Deinit(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + (_3.0: usize) = const 0_usize; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41 + Deinit(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42 + (_2.0: Droppy) = 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 + Deinit(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:17: +1:43 + (_1.0: Aligned) = 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 + Deinit(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + (_5.0: usize) = const 0_usize; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28 + Deinit(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29 + (_4.0: Droppy) = 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/tests/mir-opt/packed_struct_drop_aligned.rs b/tests/mir-opt/packed_struct_drop_aligned.rs new file mode 100644 index 000000000..cb6524260 --- /dev/null +++ b/tests/mir-opt/packed_struct_drop_aligned.rs @@ -0,0 +1,17 @@ +// ignore-wasm32-bare compiled with panic=abort by default + + +// 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/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff new file mode 100644 index 000000000..0b3da98a5 --- /dev/null +++ b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff @@ -0,0 +1,74 @@ +- // MIR for `match_guard` before CleanupPostBorrowck ++ // MIR for `match_guard` after CleanupPostBorrowck + + 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: 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: bb3, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 + } + + bb3: { +- falseEdge -> [real: bb4, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 ++ 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) -> [0: 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 +- falseEdge -> [real: bb1, imaginary: bb1]; // 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 + } + } + diff --git a/tests/mir-opt/remove_fake_borrows.rs b/tests/mir-opt/remove_fake_borrows.rs new file mode 100644 index 000000000..d26c6f5d7 --- /dev/null +++ b/tests/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.CleanupPostBorrowck.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/tests/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir b/tests/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir new file mode 100644 index 000000000..8eb0e9c8f --- /dev/null +++ b/tests/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/tests/mir-opt/remove_never_const.rs b/tests/mir-opt/remove_never_const.rs new file mode 100644 index 000000000..160cc9555 --- /dev/null +++ b/tests/mir-opt/remove_never_const.rs @@ -0,0 +1,21 @@ +// 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 +// tests/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)] + +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/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/tests/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff new file mode 100644 index 000000000..ed1d0b87f --- /dev/null +++ b/tests/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 + } + } + } + + 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 = <std::ops::Range<i32> as IntoIterator>::into_iter(move _3) -> bb1; // scope 1 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + // mir::Constant + // + span: $DIR/remove_storage_markers.rs:10:14: 10:19 + // + literal: Const { ty: fn(std::ops::Range<i32>) -> <std::ops::Range<i32> as IntoIterator>::IntoIter {<std::ops::Range<i32> as IntoIterator>::into_iter}, val: Value(<ZST>) } + } + + bb1: { +- 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 -> bb2; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + } + + bb2: { +- 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 + _7 = <std::ops::Range<i32> as Iterator>::next(move _8) -> bb3; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + // mir::Constant + // + span: $DIR/remove_storage_markers.rs:10:14: 10:19 + // + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<i32>) -> Option<<std::ops::Range<i32> as Iterator>::Item> {<std::ops::Range<i32> as Iterator>::next}, val: Value(<ZST>) } + } + + bb3: { +- 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: bb6, 1: bb4, otherwise: bb5]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + } + + bb4: { +- 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 -> bb2; // scope 2 at $DIR/remove_storage_markers.rs:+2:5: +4:6 + } + + bb5: { + unreachable; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + } + + bb6: { + _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 + } + } + diff --git a/tests/mir-opt/remove_storage_markers.rs b/tests/mir-opt/remove_storage_markers.rs new file mode 100644 index 000000000..f00b82691 --- /dev/null +++ b/tests/mir-opt/remove_storage_markers.rs @@ -0,0 +1,13 @@ +// unit-test: RemoveStorageMarkers + +// 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/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff new file mode 100644 index 000000000..07e4dd418 --- /dev/null +++ b/tests/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/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff new file mode 100644 index 000000000..e809ca4e9 --- /dev/null +++ b/tests/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/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff new file mode 100644 index 000000000..087f76dbd --- /dev/null +++ b/tests/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/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff new file mode 100644 index 000000000..933d6895f --- /dev/null +++ b/tests/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/tests/mir-opt/remove_unneeded_drops.rs b/tests/mir-opt/remove_unneeded_drops.rs new file mode 100644 index 000000000..1052f2886 --- /dev/null +++ b/tests/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/tests/mir-opt/remove_zsts.get_union.PreCodegen.after.mir b/tests/mir-opt/remove_zsts.get_union.PreCodegen.after.mir new file mode 100644 index 000000000..12e914e25 --- /dev/null +++ b/tests/mir-opt/remove_zsts.get_union.PreCodegen.after.mir @@ -0,0 +1,10 @@ +// MIR for `get_union` after PreCodegen + +fn get_union() -> Foo { + let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts.rs:+0:19: +0:22 + + bb0: { + Deinit(_0); // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18 + return; // scope 0 at $DIR/remove_zsts.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/remove_zsts.get_union.RemoveZsts.diff b/tests/mir-opt/remove_zsts.get_union.RemoveZsts.diff new file mode 100644 index 000000000..169b7b105 --- /dev/null +++ b/tests/mir-opt/remove_zsts.get_union.RemoveZsts.diff @@ -0,0 +1,19 @@ +- // MIR for `get_union` before RemoveZsts ++ // MIR for `get_union` after RemoveZsts + + fn get_union() -> Foo { + let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts.rs:+0:19: +0:22 + let mut _1: (); // in scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16 +- Deinit(_1); // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16 ++ nop; // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16 + Deinit(_0); // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18 +- (_0.0: ()) = move _1; // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18 ++ nop; // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18 + StorageDead(_1); // scope 0 at $DIR/remove_zsts.rs:+1:17: +1:18 + return; // scope 0 at $DIR/remove_zsts.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/remove_zsts.rs b/tests/mir-opt/remove_zsts.rs new file mode 100644 index 000000000..1cf7ad6e3 --- /dev/null +++ b/tests/mir-opt/remove_zsts.rs @@ -0,0 +1,14 @@ +union Foo { + x: (), + y: u64, +} + +// EMIT_MIR remove_zsts.get_union.RemoveZsts.diff +// EMIT_MIR remove_zsts.get_union.PreCodegen.after.mir +fn get_union() -> Foo { + Foo { x: () } +} + +fn main() { + get_union(); +} diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..19b726e74 --- /dev/null +++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,192 @@ +// 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 + _3 = &raw mut (*_4); // 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:61:17: 61: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 + _10 = &raw const (*_11); // 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:65:28: 65: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 + StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _35 = const _; // 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 + Deinit(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_13.0: &usize) = move _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_13.1: &usize) = 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) -> [0: 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 + Deinit(_27); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_27) = 0; // 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 + _30 = &(*_31); // 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 + _32 = &(*_33); // 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 + Deinit(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_34) = 0; // 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<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a usize, &'b usize, Option<Arguments<'c>>) -> ! {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/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir new file mode 100644 index 000000000..f495f147b --- /dev/null +++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir @@ -0,0 +1,22 @@ +// 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: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _4: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + + bb0: { + _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + Retag([fn entry] _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _3 = &mut (*_2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _4 = <Test as Drop>::drop(move _3) -> 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<'a> fn(&'a 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/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..9e5c119a2 --- /dev/null +++ b/tests/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,21 @@ +// 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: +3:6 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:32: +0:33 + 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 + StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6 + return; // scope 0 at $DIR/retag.rs:+3:6: +3:6 + } +} diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..b853e4505 --- /dev/null +++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,194 @@ +// 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<'a> fn(&'a i32) -> &'a 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<'a> fn(&'a i32) -> &'a 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 + Deinit(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24 + (_5.0: i32) = 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 + 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 + _6 = &mut (*_7); // 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:33:25: 33:28 + // + literal: Const { ty: for<'a, 'x> fn(&'a 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 + 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 + _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 + Deinit(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6 + Retag(_14); // scope 1 at $DIR/retag.rs:+11:31: +14:6 + _13 = move _14 as for<'a> fn(&'a i32) -> &'a 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 + _17 = &(*_18); // 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 + Deinit(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12 + (_21.0: i32) = 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 + 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 _; // scope 7 at $DIR/retag.rs:+18:21: +18:23 + // mir::Constant + // + span: $DIR/retag.rs:48:21: 48: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 + _22 = &(*_23); // 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:48:13: 48:20 + // + literal: Const { ty: for<'a, 'x> fn(&'a 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 + _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:53:5: 53: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/tests/mir-opt/retag.rs b/tests/mir-opt/retag.rs new file mode 100644 index 000000000..86deb0e7c --- /dev/null +++ b/tests/mir-opt/retag.rs @@ -0,0 +1,66 @@ +// unit-test: AddRetag +// 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/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..4b50205fa --- /dev/null +++ b/tests/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,18 @@ +// MIR for `<impl at $DIR/retag.rs:12:1: 12:10>::foo` after SimplifyCfg-elaborate-drops + +fn <impl at $DIR/retag.rs:12:1: 12: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:16: +0:21 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:23: +0:24 + 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 + _0 = &mut (*_3); // 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/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir new file mode 100644 index 000000000..f32a84e4c --- /dev/null +++ b/tests/mir-opt/retag.{impl#0}-foo_shr.SimplifyCfg-elaborate-drops.after.mir @@ -0,0 +1,15 @@ +// MIR for `<impl at $DIR/retag.rs:12:1: 12:10>::foo_shr` after SimplifyCfg-elaborate-drops + +fn <impl at $DIR/retag.rs:12:1: 12: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:20: +0:25 + Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:27: +0:28 + _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/tests/mir-opt/return_an_array.rs b/tests/mir-opt/return_an_array.rs new file mode 100644 index 000000000..bea3c317c --- /dev/null +++ b/tests/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/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff new file mode 100644 index 000000000..e57544e09 --- /dev/null +++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -0,0 +1,156 @@ +- // 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:25:8: 25: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:25:8: 25: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 + _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL +- switchInt(move _10) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb1: { +- 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: bb2, 1: bb4, 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: { + unreachable; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + } + +- bb4: { ++ bb3: { + 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 + } + +- bb5: { ++ bb4: { + 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(_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: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + } + +- bb6: { ++ bb5: { + unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + +- bb7: { ++ bb6: { + 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(_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: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + } + } + diff --git a/tests/mir-opt/separate_const_switch.rs b/tests/mir-opt/separate_const_switch.rs new file mode 100644 index 000000000..c809e5629 --- /dev/null +++ b/tests/mir-opt/separate_const_switch.rs @@ -0,0 +1,31 @@ +#![feature(control_flow_enum)] +#![feature(try_trait_v2)] + +use std::ops::ControlFlow; + +// EMIT_MIR separate_const_switch.too_complex.SeparateConstSwitch.diff +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 +fn identity(x: Result<i32, i32>) -> Result<i32, i32> { + Ok(x?) +} + +fn main() { + too_complex(Ok(0)); + identity(Ok(0)); +} diff --git a/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff new file mode 100644 index 000000000..8cc0c6a18 --- /dev/null +++ b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff @@ -0,0 +1,111 @@ +- // 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: bb3, 1: bb1, otherwise: bb2]; // 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 -> bb4; // 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: bb6, 1: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 + } + + bb2: { + unreachable; // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 + } + + bb3: { + 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 -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 +- } +- +- bb4: { + _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 +- switchInt(move _8) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 ++ switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 + } + +- bb5: { ++ bb4: { + 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 -> bb8; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 ++ goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 + } + +- bb6: { ++ bb5: { + unreachable; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 + } + +- bb7: { ++ bb6: { + 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 -> bb8; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 ++ goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 + } + +- bb8: { ++ bb7: { + 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/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir new file mode 100644 index 000000000..916f99049 --- /dev/null +++ b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir @@ -0,0 +1,52 @@ +// MIR for `ezmap` after PreCodegen + +fn ezmap(_1: Option<i32>) -> Option<i32> { + debug x => _1; // in scope 0 at $DIR/simple_option_map_e2e.rs:+0:14: +0:15 + let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/simple_option_map_e2e.rs:+0:33: +0:44 + let mut _2: [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]; // in scope 0 at $DIR/simple_option_map_e2e.rs:+1:12: +1:21 + scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]>) { // at $DIR/simple_option_map_e2e.rs:14:5: 14:22 + debug slf => _1; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:17: 2:20 + debug f => _2; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:33: 2:34 + let mut _3: isize; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:9: 7:16 + let mut _4: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 + let mut _5: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 + scope 2 { + debug x => _5; // in scope 2 at $DIR/simple_option_map_e2e.rs:7:14: 7:15 + scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map_e2e.rs:7:25: 7:29 + debug n => _5; // in scope 3 at $DIR/simple_option_map_e2e.rs:+1:13: +1:14 + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:12: +1:21 + _3 = discriminant(_1); // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14 + switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 1 at $DIR/simple_option_map_e2e.rs:6:5: 6:14 + } + + bb1: { + Deinit(_0); // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21 + discriminant(_0) = 0; // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21 + goto -> bb4; // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21 + } + + bb2: { + unreachable; // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14 + } + + bb3: { + _5 = move ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15 + StorageLive(_4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 + _4 = Add(move _5, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21 + Deinit(_0); // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30 + ((_0 as Some).0: i32) = move _4; // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30 + discriminant(_0) = 1; // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30 + StorageDead(_4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:29: 7:30 + goto -> bb4; // scope 1 at $DIR/simple_option_map_e2e.rs:10:1: 10:2 + } + + bb4: { + StorageDead(_2); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:21: +1:22 + return; // scope 0 at $DIR/simple_option_map_e2e.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/simple_option_map_e2e.rs b/tests/mir-opt/simple_option_map_e2e.rs new file mode 100644 index 000000000..2acd2a227 --- /dev/null +++ b/tests/mir-opt/simple_option_map_e2e.rs @@ -0,0 +1,19 @@ +#[inline(always)] +fn map<T, U, F>(slf: Option<T>, f: F) -> Option<U> +where + F: FnOnce(T) -> U, +{ + match slf { + Some(x) => Some(f(x)), + None => None, + } +} + +// EMIT_MIR simple_option_map_e2e.ezmap.PreCodegen.after.mir +pub fn ezmap(x: Option<i32>) -> Option<i32> { + map(x, |n| n + 1) +} + +fn main() { + assert_eq!(None, ezmap(None)); +} diff --git a/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff new file mode 100644 index 000000000..cff9afc38 --- /dev/null +++ b/tests/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:27:21: 27: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:23:22: 23: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:24:5: 24: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:28:9: 28:10 + Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11 + discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28: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/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff new file mode 100644 index 000000000..9d38b9350 --- /dev/null +++ b/tests/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:27:21: 27: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:23:22: 23: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:24:5: 24: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:28:9: 28:10 + Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11 + discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28: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/tests/mir-opt/simplify_arm.rs b/tests/mir-opt/simplify_arm.rs new file mode 100644 index 000000000..c247872e2 --- /dev/null +++ b/tests/mir-opt/simplify_arm.rs @@ -0,0 +1,50 @@ +// 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 + +// This pass is broken since deaggregation changed +// ignore-test + +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/tests/mir-opt/simplify_arm_identity.rs b/tests/mir-opt/simplify_arm_identity.rs new file mode 100644 index 000000000..cf6ff57aa --- /dev/null +++ b/tests/mir-opt/simplify_arm_identity.rs @@ -0,0 +1,26 @@ +// 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 + +// This pass is broken since deaggregation changed +// ignore-test + +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/tests/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff b/tests/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff new file mode 100644 index 000000000..8eb1aa1f3 --- /dev/null +++ b/tests/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) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 ++ bb2: { ++ switchInt(move _2) -> [0: 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/tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff b/tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff new file mode 100644 index 000000000..1e66b1f70 --- /dev/null +++ b/tests/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) -> [0: 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/tests/mir-opt/simplify_cfg.rs b/tests/mir-opt/simplify_cfg.rs new file mode 100644 index 000000000..cf7eac440 --- /dev/null +++ b/tests/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/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff new file mode 100644 index 000000000..f9e22866b --- /dev/null +++ b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff @@ -0,0 +1,38 @@ +- // 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) -> [0: 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 + goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6 + } + + bb3: { + 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/tests/mir-opt/simplify_if.rs b/tests/mir-opt/simplify_if.rs new file mode 100644 index 000000000..2d093d926 --- /dev/null +++ b/tests/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/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..1be27e963 --- /dev/null +++ b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,33 @@ +- // MIR for `c` before SimplifyLocals-before-const-prop ++ // MIR for `c` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..981738030 --- /dev/null +++ b/tests/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,19 @@ +- // MIR for `d1` before SimplifyLocals-before-const-prop ++ // MIR for `d1` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..b152dc8cc --- /dev/null +++ b/tests/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,29 @@ +- // MIR for `d2` before SimplifyLocals-before-const-prop ++ // MIR for `d2` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..9ca1dbbd0 --- /dev/null +++ b/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,21 @@ +- // MIR for `expose_addr` before SimplifyLocals-before-const-prop ++ // MIR for `expose_addr` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..19dacb427 --- /dev/null +++ b/tests/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,31 @@ +- // MIR for `r` before SimplifyLocals-before-const-prop ++ // MIR for `r` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals.rs b/tests/mir-opt/simplify_locals.rs new file mode 100644 index 000000000..7bbc0481c --- /dev/null +++ b/tests/mir-opt/simplify_locals.rs @@ -0,0 +1,81 @@ +// unit-test: SimplifyLocals-before-const-prop + + +#![feature(thread_local)] + +#[derive(Copy, Clone)] +enum E { + A, + B, +} + +// EMIT_MIR simplify_locals.c.SimplifyLocals-before-const-prop.diff +fn c() { + let bytes = [0u8; 10]; + // Unused cast + let _: &[u8] = &bytes; +} + +// EMIT_MIR simplify_locals.d1.SimplifyLocals-before-const-prop.diff +fn d1() { + // Unused set discriminant + let _ = E::A; +} + +// EMIT_MIR simplify_locals.d2.SimplifyLocals-before-const-prop.diff +fn d2() { + // Unused set discriminant + {(10, E::A)}.1 = E::B; +} + +// EMIT_MIR simplify_locals.r.SimplifyLocals-before-const-prop.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-before-const-prop.diff +fn t1() { + // Unused thread local + unsafe { X }; +} + +// EMIT_MIR simplify_locals.t2.SimplifyLocals-before-const-prop.diff +fn t2() { + // Unused thread local + unsafe { &mut X }; +} + +// EMIT_MIR simplify_locals.t3.SimplifyLocals-before-const-prop.diff +fn t3() { + // Unused thread local + unsafe { *&mut X }; +} + +// EMIT_MIR simplify_locals.t4.SimplifyLocals-before-const-prop.diff +fn t4() -> u32 { + // Used thread local + unsafe { X + 1 } +} + +// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals-before-const-prop.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/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..1b2e1158e --- /dev/null +++ b/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,22 @@ +- // MIR for `t1` before SimplifyLocals-before-const-prop ++ // MIR for `t1` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..cf019357b --- /dev/null +++ b/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,22 @@ +- // MIR for `t2` before SimplifyLocals-before-const-prop ++ // MIR for `t2` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..90ee21580 --- /dev/null +++ b/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,26 @@ +- // MIR for `t3` before SimplifyLocals-before-const-prop ++ // MIR for `t3` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..9add9a6c5 --- /dev/null +++ b/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,22 @@ +- // MIR for `t4` before SimplifyLocals-before-const-prop ++ // MIR for `t4` after SimplifyLocals-before-const-prop + + 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/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff new file mode 100644 index 000000000..f888c622d --- /dev/null +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff @@ -0,0 +1,62 @@ +- // MIR for `foo` before SimplifyLocals-final ++ // MIR for `foo` after SimplifyLocals-final + + 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: 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: 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/tests/mir-opt/simplify_locals_fixedpoint.rs b/tests/mir-opt/simplify_locals_fixedpoint.rs new file mode 100644 index 000000000..1fdba6e99 --- /dev/null +++ b/tests/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-final.diff diff --git a/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..efb2b0961 --- /dev/null +++ b/tests/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,109 @@ +- // MIR for `main` before SimplifyLocals-before-const-prop ++ // MIR for `main` after SimplifyLocals-before-const-prop + + 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 mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ let mut _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ let _5: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ let mut _6: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ let mut _7: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ let mut _8: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 + 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 +- Deinit(_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 +- Deinit(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- Deinit(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- 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 +- Deinit(_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 +- Deinit(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- Deinit(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- 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 ++ StorageLive(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ Deinit(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ Deinit(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ Deinit(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 ++ StorageDead(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +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:15:5: 15: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 +- Deinit(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- _10 = (_11.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- StorageDead(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 +- _8 = use_u8(move _9) -> 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(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ Deinit(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ _7 = (_8.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 ++ _5 = use_u8(move _6) -> 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:17:5: 17: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(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 + StorageDead(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 ++ StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 + _0 = const (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +5:2 + return; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/simplify_locals_removes_unused_consts.rs b/tests/mir-opt/simplify_locals_removes_unused_consts.rs new file mode 100644 index 000000000..7a03a2837 --- /dev/null +++ b/tests/mir-opt/simplify_locals_removes_unused_consts.rs @@ -0,0 +1,18 @@ +// unit-test: SimplifyLocals-before-const-prop +// 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-before-const-prop.diff +fn main() { + let ((), ()) = ((), ()); + use_zst(((), ())); + + use_u8((Temp { x: 40 }).x + 2); +} diff --git a/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff new file mode 100644 index 000000000..027c983e6 --- /dev/null +++ b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,52 @@ +- // MIR for `map` before SimplifyLocals-before-const-prop ++ // MIR for `map` after SimplifyLocals-before-const-prop + + 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 => _3; // in scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + } + + bb0: { +- _5 = const false; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 +- _5 = const true; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 + _2 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 + switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:5: +1:12 + } + + bb1: { + StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 + _4 = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 + Deinit(_0); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 + ((_0 as Some).0: std::boxed::Box<()>) = move _4; // 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 + StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 + StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 + goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 + } + + bb3: { + 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 -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 + } + + bb4: { +- _6 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 + return; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs new file mode 100644 index 000000000..de6585741 --- /dev/null +++ b/tests/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs @@ -0,0 +1,14 @@ +// unit-test: SimplifyLocals-before-const-prop + +fn map(x: Option<Box<()>>) -> Option<Box<()>> { + match x { + None => None, + Some(x) => Some(x), + } +} + +fn main() { + map(None); +} + +// EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff diff --git a/tests/mir-opt/simplify_match.main.ConstProp.diff b/tests/mir-opt/simplify_match.main.ConstProp.diff new file mode 100644 index 000000000..70bfbf1b3 --- /dev/null +++ b/tests/mir-opt/simplify_match.main.ConstProp.diff @@ -0,0 +1,39 @@ +- // 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) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 ++ switchInt(const false) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 + } + + bb1: { + 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/tests/mir-opt/simplify_match.rs b/tests/mir-opt/simplify_match.rs new file mode 100644 index 000000000..216203f9f --- /dev/null +++ b/tests/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/tests/mir-opt/simplify_try_if_let.rs b/tests/mir-opt/simplify_try_if_let.rs new file mode 100644 index 000000000..fba67de40 --- /dev/null +++ b/tests/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/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff b/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff new file mode 100644 index 000000000..11f6b5337 --- /dev/null +++ b/tests/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/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir new file mode 100644 index 000000000..391b00eff --- /dev/null +++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.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) -> [0: 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) -> [0: 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) -> [0: 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) -> [0: 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 (PtrToPtr); // 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: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + } +} diff --git a/tests/mir-opt/slice_drop_shim.rs b/tests/mir-opt/slice_drop_shim.rs new file mode 100644 index 000000000..344c1af2c --- /dev/null +++ b/tests/mir-opt/slice_drop_shim.rs @@ -0,0 +1,7 @@ +// compile-flags: -Zmir-opt-level=0 + + +// 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/tests/mir-opt/spanview_block.main.built.after.html b/tests/mir-opt/spanview_block.main.built.after.html new file mode 100644 index 000000000..b962d80c5 --- /dev/null +++ b/tests/mir-opt/spanview_block.main.built.after.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html> +<head> +<title>spanview_block.main.built.after</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/tests/mir-opt/spanview_block.rs b/tests/mir-opt/spanview_block.rs new file mode 100644 index 000000000..0ecf35ad6 --- /dev/null +++ b/tests/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.built.after.html +fn main() {} diff --git a/tests/mir-opt/spanview_statement.main.built.after.html b/tests/mir-opt/spanview_statement.main.built.after.html new file mode 100644 index 000000000..43bff7d09 --- /dev/null +++ b/tests/mir-opt/spanview_statement.main.built.after.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html> +<head> +<title>spanview_statement.main.built.after</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/tests/mir-opt/spanview_statement.rs b/tests/mir-opt/spanview_statement.rs new file mode 100644 index 000000000..457052617 --- /dev/null +++ b/tests/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.built.after.html +fn main() {} diff --git a/tests/mir-opt/spanview_terminator.main.built.after.html b/tests/mir-opt/spanview_terminator.main.built.after.html new file mode 100644 index 000000000..aa7e44c15 --- /dev/null +++ b/tests/mir-opt/spanview_terminator.main.built.after.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<html> +<head> +<title>spanview_terminator.main.built.after</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/tests/mir-opt/spanview_terminator.rs b/tests/mir-opt/spanview_terminator.rs new file mode 100644 index 000000000..76fced188 --- /dev/null +++ b/tests/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.built.after.html +fn main() {} diff --git a/tests/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff new file mode 100644 index 000000000..eb8830446 --- /dev/null +++ b/tests/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff @@ -0,0 +1,50 @@ +- // MIR for `dropping` before ScalarReplacementOfAggregates ++ // MIR for `dropping` after ScalarReplacementOfAggregates + + fn dropping() -> () { + let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19 + let _1: Tag; // in scope 0 at $DIR/sroa.rs:+1:5: +1:32 + let mut _2: S; // in scope 0 at $DIR/sroa.rs:+1:5: +1:30 + let mut _3: Tag; // in scope 0 at $DIR/sroa.rs:+1:7: +1:13 + let mut _4: Tag; // in scope 0 at $DIR/sroa.rs:+1:15: +1:21 + let mut _5: Tag; // in scope 0 at $DIR/sroa.rs:+1:23: +1:29 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:5: +1:32 + StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:5: +1:30 + StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:13 + Deinit(_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:13 + (_3.0: usize) = const 0_usize; // scope 0 at $DIR/sroa.rs:+1:7: +1:13 + StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:15: +1:21 + Deinit(_4); // scope 0 at $DIR/sroa.rs:+1:15: +1:21 + (_4.0: usize) = const 1_usize; // scope 0 at $DIR/sroa.rs:+1:15: +1:21 + StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:23: +1:29 + Deinit(_5); // scope 0 at $DIR/sroa.rs:+1:23: +1:29 + (_5.0: usize) = const 2_usize; // scope 0 at $DIR/sroa.rs:+1:23: +1:29 + Deinit(_2); // scope 0 at $DIR/sroa.rs:+1:5: +1:30 + (_2.0: Tag) = move _3; // scope 0 at $DIR/sroa.rs:+1:5: +1:30 + (_2.1: Tag) = move _4; // scope 0 at $DIR/sroa.rs:+1:5: +1:30 + (_2.2: Tag) = move _5; // scope 0 at $DIR/sroa.rs:+1:5: +1:30 + StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:29: +1:30 + StorageDead(_4); // scope 0 at $DIR/sroa.rs:+1:29: +1:30 + StorageDead(_3); // scope 0 at $DIR/sroa.rs:+1:29: +1:30 + _1 = move (_2.1: Tag); // scope 0 at $DIR/sroa.rs:+1:5: +1:32 + drop(_1) -> bb1; // scope 0 at $DIR/sroa.rs:+1:32: +1:33 + } + + bb1: { + drop((_2.0: Tag)) -> bb3; // scope 0 at $DIR/sroa.rs:+1:32: +1:33 + } + + bb2: { + StorageDead(_2); // scope 0 at $DIR/sroa.rs:+1:32: +1:33 + StorageDead(_1); // scope 0 at $DIR/sroa.rs:+1:32: +1:33 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +2:2 + return; // scope 0 at $DIR/sroa.rs:+2:2: +2:2 + } + + bb3: { + drop((_2.2: Tag)) -> bb2; // scope 0 at $DIR/sroa.rs:+1:32: +1:33 + } + } + diff --git a/tests/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff new file mode 100644 index 000000000..a5488c1ec --- /dev/null +++ b/tests/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff @@ -0,0 +1,45 @@ +- // MIR for `enums` before ScalarReplacementOfAggregates ++ // MIR for `enums` after ScalarReplacementOfAggregates + + fn enums(_1: usize) -> usize { + debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:14: +0:15 + let mut _0: usize; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:32 + let mut _2: std::option::Option<usize>; // in scope 0 at $DIR/sroa.rs:+1:22: +1:29 + let mut _3: usize; // in scope 0 at $DIR/sroa.rs:+1:27: +1:28 + let mut _4: isize; // in scope 0 at $DIR/sroa.rs:+1:12: +1:19 + scope 1 { + debug a => _5; // in scope 1 at $DIR/sroa.rs:+1:17: +1:18 + let _5: usize; // in scope 1 at $DIR/sroa.rs:+1:17: +1:18 + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/sroa.rs:+1:22: +1:29 + StorageLive(_3); // scope 1 at $DIR/sroa.rs:+1:27: +1:28 + _3 = _1; // scope 1 at $DIR/sroa.rs:+1:27: +1:28 + Deinit(_2); // scope 1 at $DIR/sroa.rs:+1:22: +1:29 + ((_2 as Some).0: usize) = move _3; // scope 1 at $DIR/sroa.rs:+1:22: +1:29 + discriminant(_2) = 1; // scope 1 at $DIR/sroa.rs:+1:22: +1:29 + StorageDead(_3); // scope 1 at $DIR/sroa.rs:+1:28: +1:29 + _4 = discriminant(_2); // scope 1 at $DIR/sroa.rs:+1:12: +1:19 + switchInt(move _4) -> [1: bb1, otherwise: bb2]; // scope 1 at $DIR/sroa.rs:+1:12: +1:19 + } + + bb1: { + StorageLive(_5); // scope 1 at $DIR/sroa.rs:+1:17: +1:18 + _5 = ((_2 as Some).0: usize); // scope 1 at $DIR/sroa.rs:+1:17: +1:18 + _0 = _5; // scope 1 at $DIR/sroa.rs:+1:32: +1:33 + StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:34: +1:35 + goto -> bb3; // scope 0 at $DIR/sroa.rs:+1:5: +1:46 + } + + bb2: { + _0 = const 0_usize; // scope 0 at $DIR/sroa.rs:+1:43: +1:44 + goto -> bb3; // scope 0 at $DIR/sroa.rs:+1:5: +1:46 + } + + bb3: { + StorageDead(_2); // scope 0 at $DIR/sroa.rs:+2:1: +2:2 + return; // scope 0 at $DIR/sroa.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff new file mode 100644 index 000000000..64559b58f --- /dev/null +++ b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff @@ -0,0 +1,47 @@ +- // MIR for `escaping` before ScalarReplacementOfAggregates ++ // MIR for `escaping` after ScalarReplacementOfAggregates + + fn escaping() -> () { + let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19 + let _1: (); // in scope 0 at $DIR/sroa.rs:+2:5: +2:42 + let mut _2: *const u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41 + let _3: &u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41 + let _4: Escaping; // in scope 0 at $DIR/sroa.rs:+2:8: +2:39 + let mut _5: u32; // in scope 0 at $DIR/sroa.rs:+2:34: +2:37 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/sroa.rs:+2:5: +2:42 + StorageLive(_2); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 + StorageLive(_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 + StorageLive(_4); // scope 0 at $DIR/sroa.rs:+2:8: +2:39 + StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:34: +2:37 + _5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+2:34: +2:37 + // mir::Constant + // + span: $DIR/sroa.rs:78:34: 78:35 + // + literal: Const { ty: fn() -> u32 {g}, val: Value(<ZST>) } + } + + bb1: { + Deinit(_4); // scope 0 at $DIR/sroa.rs:+2:8: +2:39 + (_4.0: u32) = const 1_u32; // scope 0 at $DIR/sroa.rs:+2:8: +2:39 + (_4.1: u32) = const 2_u32; // scope 0 at $DIR/sroa.rs:+2:8: +2:39 + (_4.2: u32) = move _5; // scope 0 at $DIR/sroa.rs:+2:8: +2:39 + StorageDead(_5); // scope 0 at $DIR/sroa.rs:+2:38: +2:39 + _3 = &(_4.0: u32); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 + _2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 + _1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+2:5: +2:42 + // mir::Constant + // + span: $DIR/sroa.rs:78:5: 78:6 + // + literal: Const { ty: fn(*const u32) {f}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_2); // scope 0 at $DIR/sroa.rs:+2:41: +2:42 + StorageDead(_4); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 + StorageDead(_3); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 + StorageDead(_1); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +3:2 + return; // scope 0 at $DIR/sroa.rs:+3:2: +3:2 + } + } + diff --git a/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff new file mode 100644 index 000000000..d4c04d5e6 --- /dev/null +++ b/tests/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff @@ -0,0 +1,87 @@ +- // MIR for `flat` before ScalarReplacementOfAggregates ++ // MIR for `flat` after ScalarReplacementOfAggregates + + fn flat() -> () { + let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:15: +0:15 + let _1: u8; // in scope 0 at $DIR/sroa.rs:+1:15: +1:16 + let _2: (); // in scope 0 at $DIR/sroa.rs:+1:18: +1:19 + let _3: &str; // in scope 0 at $DIR/sroa.rs:+1:21: +1:22 + let _4: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:24: +1:25 + let mut _5: Foo; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 + let mut _6: (); // in scope 0 at $DIR/sroa.rs:+1:45: +1:47 + let mut _7: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:60: +1:68 ++ let mut _8: u8; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ let mut _9: (); // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ let mut _10: &str; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ let mut _11: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70 + scope 1 { + debug a => _1; // in scope 1 at $DIR/sroa.rs:+1:15: +1:16 + debug b => _2; // in scope 1 at $DIR/sroa.rs:+1:18: +1:19 + debug c => _3; // in scope 1 at $DIR/sroa.rs:+1:21: +1:22 + debug d => _4; // in scope 1 at $DIR/sroa.rs:+1:24: +1:25 + scope 2 { + scope 3 { + scope 4 { + scope 5 { + } + } + } + } + } + + bb0: { +- StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ StorageLive(_8); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ StorageLive(_9); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ StorageLive(_10); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ StorageLive(_11); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 + StorageLive(_6); // scope 0 at $DIR/sroa.rs:+1:45: +1:47 + Deinit(_6); // scope 0 at $DIR/sroa.rs:+1:45: +1:47 + StorageLive(_7); // scope 0 at $DIR/sroa.rs:+1:60: +1:68 + Deinit(_7); // scope 0 at $DIR/sroa.rs:+1:60: +1:68 + ((_7 as Some).0: isize) = const -4_isize; // scope 0 at $DIR/sroa.rs:+1:60: +1:68 + discriminant(_7) = 1; // scope 0 at $DIR/sroa.rs:+1:60: +1:68 +- Deinit(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 +- (_5.0: u8) = const 5_u8; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 +- (_5.1: ()) = move _6; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 +- (_5.2: &str) = const "a"; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ Deinit(_8); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ Deinit(_9); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ Deinit(_10); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ Deinit(_11); // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ _8 = const 5_u8; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ _9 = move _6; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ _10 = const "a"; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 + // mir::Constant + // + span: $DIR/sroa.rs:57:52: 57:55 + // + literal: Const { ty: &str, val: Value(Slice(..)) } +- (_5.3: std::option::Option<isize>) = move _7; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 ++ _11 = move _7; // scope 0 at $DIR/sroa.rs:+1:30: +1:70 + StorageDead(_7); // scope 0 at $DIR/sroa.rs:+1:69: +1:70 + StorageDead(_6); // scope 0 at $DIR/sroa.rs:+1:69: +1:70 + StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:15: +1:16 +- _1 = (_5.0: u8); // scope 0 at $DIR/sroa.rs:+1:15: +1:16 ++ _1 = _8; // scope 0 at $DIR/sroa.rs:+1:15: +1:16 + StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:18: +1:19 +- _2 = (_5.1: ()); // scope 0 at $DIR/sroa.rs:+1:18: +1:19 ++ _2 = _9; // scope 0 at $DIR/sroa.rs:+1:18: +1:19 + StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:21: +1:22 +- _3 = (_5.2: &str); // scope 0 at $DIR/sroa.rs:+1:21: +1:22 ++ _3 = _10; // scope 0 at $DIR/sroa.rs:+1:21: +1:22 + StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:24: +1:25 +- _4 = (_5.3: std::option::Option<isize>); // scope 0 at $DIR/sroa.rs:+1:24: +1:25 +- StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ _4 = _11; // scope 0 at $DIR/sroa.rs:+1:24: +1:25 ++ StorageDead(_8); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ StorageDead(_9); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ StorageDead(_10); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 ++ StorageDead(_11); // scope 0 at $DIR/sroa.rs:+1:70: +1:71 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:15: +6:2 + StorageDead(_4); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 + StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 + StorageDead(_2); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 + return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs new file mode 100644 index 000000000..ff8deb40d --- /dev/null +++ b/tests/mir-opt/sroa.rs @@ -0,0 +1,88 @@ +// unit-test: ScalarReplacementOfAggregates +// compile-flags: -Cpanic=abort +// no-prefer-dynamic + +struct Tag(usize); + +#[repr(C)] +struct S(Tag, Tag, Tag); + +impl Drop for Tag { + #[inline(never)] + fn drop(&mut self) {} +} + +// EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff +pub fn dropping() { + S(Tag(0), Tag(1), Tag(2)).1; +} + +// EMIT_MIR sroa.enums.ScalarReplacementOfAggregates.diff +pub fn enums(a: usize) -> usize { + if let Some(a) = Some(a) { a } else { 0 } +} + +// EMIT_MIR sroa.structs.ScalarReplacementOfAggregates.diff +pub fn structs(a: f32) -> f32 { + struct U { + _foo: usize, + a: f32, + } + + U { _foo: 0, a }.a +} + +// EMIT_MIR sroa.unions.ScalarReplacementOfAggregates.diff +pub fn unions(a: f32) -> u32 { + union Repr { + f: f32, + u: u32, + } + unsafe { Repr { f: a }.u } +} + +struct Foo { + a: u8, + b: (), + c: &'static str, + d: Option<isize>, +} + +fn g() -> u32 { + 3 +} + +// EMIT_MIR sroa.flat.ScalarReplacementOfAggregates.diff +pub fn flat() { + let Foo { a, b, c, d } = Foo { a: 5, b: (), c: "a", d: Some(-4) }; + let _ = a; + let _ = b; + let _ = c; + let _ = d; +} + +#[repr(C)] +struct Escaping { + a: u32, + b: u32, + c: u32, +} + +fn f(a: *const u32) { + println!("{}", unsafe { *a.add(2) }); +} + +// EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff +pub fn escaping() { + // Verify this struct is not flattened. + f(&Escaping { a: 1, b: 2, c: g() }.a); +} + +fn main() { + dropping(); + enums(5); + structs(5.); + unions(5.); + flat(); + escaping(); +} diff --git a/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff new file mode 100644 index 000000000..69d74c351 --- /dev/null +++ b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff @@ -0,0 +1,34 @@ +- // MIR for `structs` before ScalarReplacementOfAggregates ++ // MIR for `structs` after ScalarReplacementOfAggregates + + fn structs(_1: f32) -> f32 { + debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:16: +0:17 + let mut _0: f32; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:30 + let mut _2: structs::U; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 + let mut _3: f32; // in scope 0 at $DIR/sroa.rs:+6:18: +6:19 ++ let mut _4: usize; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ let mut _5: f32; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 + StorageLive(_3); // scope 0 at $DIR/sroa.rs:+6:18: +6:19 + _3 = _1; // scope 0 at $DIR/sroa.rs:+6:18: +6:19 +- Deinit(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 +- (_2.0: usize) = const 0_usize; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 +- (_2.1: f32) = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ Deinit(_4); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ Deinit(_5); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ _4 = const 0_usize; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ _5 = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 + StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:20: +6:21 +- _0 = (_2.1: f32); // scope 0 at $DIR/sroa.rs:+6:5: +6:23 +- StorageDead(_2); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 ++ _0 = _5; // scope 0 at $DIR/sroa.rs:+6:5: +6:23 ++ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 ++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 + return; // scope 0 at $DIR/sroa.rs:+7:2: +7:2 + } + } + diff --git a/tests/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff new file mode 100644 index 000000000..03ca976df --- /dev/null +++ b/tests/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff @@ -0,0 +1,24 @@ +- // MIR for `unions` before ScalarReplacementOfAggregates ++ // MIR for `unions` after ScalarReplacementOfAggregates + + fn unions(_1: f32) -> u32 { + debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:15: +0:16 + let mut _0: u32; // return place in scope 0 at $DIR/sroa.rs:+0:26: +0:29 + let mut _2: unions::Repr; // in scope 0 at $DIR/sroa.rs:+5:14: +5:27 + let mut _3: f32; // in scope 0 at $DIR/sroa.rs:+5:24: +5:25 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/sroa.rs:+5:14: +5:27 + StorageLive(_3); // scope 1 at $DIR/sroa.rs:+5:24: +5:25 + _3 = _1; // scope 1 at $DIR/sroa.rs:+5:24: +5:25 + Deinit(_2); // scope 1 at $DIR/sroa.rs:+5:14: +5:27 + (_2.0: f32) = move _3; // scope 1 at $DIR/sroa.rs:+5:14: +5:27 + StorageDead(_3); // scope 1 at $DIR/sroa.rs:+5:26: +5:27 + _0 = (_2.1: u32); // scope 1 at $DIR/sroa.rs:+5:14: +5:29 + StorageDead(_2); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 + return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2 + } + } + diff --git a/tests/mir-opt/storage_ranges.main.nll.0.mir b/tests/mir-opt/storage_ranges.main.nll.0.mir new file mode 100644 index 000000000..8e10e70f1 --- /dev/null +++ b/tests/mir-opt/storage_ranges.main.nll.0.mir @@ -0,0 +1,63 @@ +// 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 | {bb0[10..=11]} +| '_#3r | U0 | {bb0[11]} +| +| Inference Constraints +| '_#0r live at {bb0[0..=22]} +| '_#1r live at {bb0[0..=22]} +| '_#2r live at {bb0[10]} +| '_#3r live at {bb0[11]} +| '_#2r: '_#3r 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/tests/mir-opt/storage_ranges.rs b/tests/mir-opt/storage_ranges.rs new file mode 100644 index 000000000..996051a29 --- /dev/null +++ b/tests/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/tests/mir-opt/tls_access.main.PreCodegen.after.mir b/tests/mir-opt/tls_access.main.PreCodegen.after.mir new file mode 100644 index 000000000..09453b8ba --- /dev/null +++ b/tests/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/tests/mir-opt/tls_access.rs b/tests/mir-opt/tls_access.rs new file mode 100644 index 000000000..19344c868 --- /dev/null +++ b/tests/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/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir b/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir new file mode 100644 index 000000000..b254bfeb7 --- /dev/null +++ b/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir @@ -0,0 +1,71 @@ +// MIR for `new` after PreCodegen + +fn new(_1: Result<T, E>) -> Result<T, E> { + debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15 + let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46 + let mut _2: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 + let mut _3: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22 + let mut _4: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:48: +4:49 + let mut _5: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:46: +5:47 + let mut _6: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37 + let _7: T; // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36 + let mut _8: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:49: +9:50 + scope 1 { + debug v => _4; // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21 + } + scope 2 { + debug e => _5; // in scope 2 at $DIR/try_identity_e2e.rs:+5:21: +5:22 + } + scope 3 { + debug v => _7; // in scope 3 at $DIR/try_identity_e2e.rs:+8:35: +8:36 + } + scope 4 { + debug e => _8; // in scope 4 at $DIR/try_identity_e2e.rs:+9:32: +9:33 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 + _3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20 + switchInt(move _3) -> [0: bb2, 1: bb1, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20 + } + + bb1: { + _5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22 + Deinit(_2); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48 + ((_2 as Break).0: E) = move _5; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48 + discriminant(_2) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48 + _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 + switchInt(move _6) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 + } + + bb2: { + _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21 + Deinit(_2); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50 + ((_2 as Continue).0: T) = move _4; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50 + discriminant(_2) = 0; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50 + _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 + switchInt(move _6) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 + } + + bb3: { + _8 = move ((_2 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33 + Deinit(_0); // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51 + ((_0 as Err).0: E) = move _8; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51 + discriminant(_0) = 1; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51 + StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 + return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 + } + + bb4: { + unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 + } + + bb5: { + _7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36 + Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6 + ((_0 as Ok).0: T) = move _7; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6 + discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6 + StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 + return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 + } +} diff --git a/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir b/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir new file mode 100644 index 000000000..cdbc0681c --- /dev/null +++ b/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir @@ -0,0 +1,40 @@ +// MIR for `old` after PreCodegen + +fn old(_1: Result<T, E>) -> Result<T, E> { + debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15 + let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46 + let mut _2: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18 + let _3: T; // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17 + let mut _4: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:34: +4:35 + scope 1 { + debug v => _3; // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17 + } + scope 2 { + debug e => _4; // in scope 2 at $DIR/try_identity_e2e.rs:+4:17: +4:18 + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16 + switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16 + } + + bb1: { + _4 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18 + Deinit(_0); // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36 + ((_0 as Err).0: E) = move _4; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36 + discriminant(_0) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36 + return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2 + } + + bb2: { + unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16 + } + + bb3: { + _3 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17 + Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6 + ((_0 as Ok).0: T) = move _3; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6 + discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6 + return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2 + } +} diff --git a/tests/mir-opt/try_identity_e2e.rs b/tests/mir-opt/try_identity_e2e.rs new file mode 100644 index 000000000..00cb80f50 --- /dev/null +++ b/tests/mir-opt/try_identity_e2e.rs @@ -0,0 +1,34 @@ +// Track the status of MIR optimizations simplifying `Ok(res?)` for both the old and new desugarings +// of that syntax. + +use std::ops::ControlFlow; + +// EMIT_MIR try_identity_e2e.new.PreCodegen.after.mir +fn new<T, E>(x: Result<T, E>) -> Result<T, E> { + Ok( + match { + match x { + Ok(v) => ControlFlow::Continue(v), + Err(e) => ControlFlow::Break(e), + } + } { + ControlFlow::Continue(v) => v, + ControlFlow::Break(e) => return Err(e), + } + ) +} + +// EMIT_MIR try_identity_e2e.old.PreCodegen.after.mir +fn old<T, E>(x: Result<T, E>) -> Result<T, E> { + Ok( + match x { + Ok(v) => v, + Err(e) => return Err(e), + } + ) +} + +fn main() { + let _ = new::<(), ()>(Ok(())); + let _ = old::<(), ()>(Ok(())); +} diff --git a/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir new file mode 100644 index 000000000..b4fb330f3 --- /dev/null +++ b/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir @@ -0,0 +1,16 @@ +// MIR for `process_never` after SimplifyLocals-final + +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: { + unreachable; // scope 0 at $DIR/uninhabited_enum.rs:+0:39: +2:2 + } +} diff --git a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir new file mode 100644 index 000000000..2af864998 --- /dev/null +++ b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir @@ -0,0 +1,18 @@ +// MIR for `process_void` after SimplifyLocals-final + +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/tests/mir-opt/uninhabited_enum.rs b/tests/mir-opt/uninhabited_enum.rs new file mode 100644 index 000000000..19db54815 --- /dev/null +++ b/tests/mir-opt/uninhabited_enum.rs @@ -0,0 +1,19 @@ +#![feature(never_type)] + +pub enum Void {} + +// EMIT_MIR uninhabited_enum.process_never.SimplifyLocals-final.after.mir +#[no_mangle] +pub fn process_never(input: *const !) { + let _input = unsafe { &*input }; +} + +// EMIT_MIR uninhabited_enum.process_void.SimplifyLocals-final.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/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir new file mode 100644 index 000000000..39ec05277 --- /dev/null +++ b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -0,0 +1,75 @@ +// 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 + switchInt(move _3) -> [2: bb1, otherwise: bb2]; // 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 + 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: bb5, 5: bb3, otherwise: bb4]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 + } + + bb2: { + unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + } + + bb3: { + 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 -> bb6; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 + } + + bb4: { + unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + } + + bb5: { + _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 -> bb6; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 + } + + bb6: { + 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/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff new file mode 100644 index 000000000..598413a1d --- /dev/null +++ b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff @@ -0,0 +1,101 @@ +- // 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: bb3, 1: bb4, 2: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 ++ switchInt(move _3) -> [2: bb1, otherwise: bb2]; // 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 -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+4:23: +4:24 + } + + bb2: { + unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 + } + + bb3: { + _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 -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+2:24: +2:34 + } + + bb4: { + 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 -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+3:33: +3:34 + } + + bb5: { + 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: bb8, 5: bb6, otherwise: bb7]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 + } + + bb6: { + 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 -> bb9; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 + } + + bb7: { + unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 + } + + bb8: { + _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 -> bb9; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 + } + + bb9: { + 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/tests/mir-opt/uninhabited_enum_branching.rs b/tests/mir-opt/uninhabited_enum_branching.rs new file mode 100644 index 000000000..0ef604c30 --- /dev/null +++ b/tests/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/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir new file mode 100644 index 000000000..c8cd6f6c1 --- /dev/null +++ b/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -0,0 +1,104 @@ +// 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: bb3, 3: bb1, otherwise: bb2]; // 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 -> bb4; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24 + } + + bb2: { + unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + } + + bb3: { + 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 -> bb4; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24 + } + + bb4: { + 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: bb7, 3: bb5, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 + } + + bb5: { + 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 -> bb8; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 + } + + bb6: { + unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 + } + + bb7: { + 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 -> bb8; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 + } + + bb8: { + 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/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff new file mode 100644 index 000000000..2aee6d268 --- /dev/null +++ b/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff @@ -0,0 +1,146 @@ +- // 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: bb3, 1: bb4, 2: bb5, 3: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 ++ switchInt(move _5) -> [2: bb5, 3: bb1, otherwise: bb2]; // 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 -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+7:23: +7:24 + } + + bb2: { + unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 + } + + bb3: { + _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 -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+4:24: +4:34 + } + + bb4: { + 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 -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+5:33: +5:34 + } + + bb5: { + 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 -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+6:23: +6:24 + } + + bb6: { + 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: bb9, 1: bb10, 2: bb11, 3: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 ++ switchInt(move _10) -> [2: bb11, 3: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 + } + + bb7: { + 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 -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 + } + + bb8: { + unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 + } + + bb9: { + _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 -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34 + } + + bb10: { + 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 -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34 + } + + bb11: { + 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 -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 + } + + bb12: { + 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/tests/mir-opt/uninhabited_enum_branching2.rs b/tests/mir-opt/uninhabited_enum_branching2.rs new file mode 100644 index 000000000..e22e94314 --- /dev/null +++ b/tests/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/tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff new file mode 100644 index 000000000..58e085dd0 --- /dev/null +++ b/tests/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: bb3, 2: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 ++ switchInt(move _2) -> [1: bb3, 2: 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/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff new file mode 100644 index 000000000..e765851eb --- /dev/null +++ b/tests/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: bb2, 1: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 ++ switchInt(move _2) -> [1: 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/tests/mir-opt/uninhabited_fallthrough_elimination.rs b/tests/mir-opt/uninhabited_fallthrough_elimination.rs new file mode 100644 index 000000000..0853883f8 --- /dev/null +++ b/tests/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/tests/mir-opt/unreachable.main.UnreachablePropagation.diff b/tests/mir-opt/unreachable.main.UnreachablePropagation.diff new file mode 100644 index 000000000..848bff1d4 --- /dev/null +++ b/tests/mir-opt/unreachable.main.UnreachablePropagation.diff @@ -0,0 +1,70 @@ +- // 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: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 ++ switchInt(move _2) -> [1: bb2, otherwise: bb3]; // 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) -> [0: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 ++ unreachable; // 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/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs new file mode 100644 index 000000000..6098b525b --- /dev/null +++ b/tests/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/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff new file mode 100644 index 000000000..fb778470e --- /dev/null +++ b/tests/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff @@ -0,0 +1,71 @@ +- // 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: bb2, otherwise: bb6]; // 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) -> [0: bb4, otherwise: 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 + // 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 ++ unreachable; // 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: { + _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/tests/mir-opt/unreachable_diverging.rs b/tests/mir-opt/unreachable_diverging.rs new file mode 100644 index 000000000..bbf28efc7 --- /dev/null +++ b/tests/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/tests/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir b/tests/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir new file mode 100644 index 000000000..5257491f0 --- /dev/null +++ b/tests/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `E::V::{constant#0}` after built + +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/tests/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir b/tests/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir new file mode 100644 index 000000000..ee0296763 --- /dev/null +++ b/tests/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir @@ -0,0 +1,12 @@ +// MIR for `Test::X` after built + +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/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir new file mode 100644 index 000000000..ed9f3bdbd --- /dev/null +++ b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.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<'a> fn(&'a mut Vec<i32>) {<Vec<i32> as Drop>::drop}, val: Value(<ZST>) } + } +} diff --git a/tests/mir-opt/unusual_item_types.rs b/tests/mir-opt/unusual_item_types.rs new file mode 100644 index 000000000..6dad63641 --- /dev/null +++ b/tests/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 + + +struct A; + +// EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir +impl A { + const ASSOCIATED_CONSTANT: i32 = 2; +} + +// See #59021 +// EMIT_MIR unusual_item_types.Test-X-{constructor#0}.built.after.mir +enum Test { + X(usize), + Y { a: usize }, +} + +// EMIT_MIR unusual_item_types.E-V-{constant#0}.built.after.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/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir b/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir new file mode 100644 index 000000000..90444b481 --- /dev/null +++ b/tests/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `<impl at $DIR/unusual_item_types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` after built + +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:40 + } +} diff --git a/tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff b/tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff new file mode 100644 index 000000000..bb1de59d4 --- /dev/null +++ b/tests/mir-opt/while_let_loops.change_loop_body.ConstProp.diff @@ -0,0 +1,46 @@ +- // 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: std::option::Option<u32>; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32 + let mut _3: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25 + 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(_2); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + Deinit(_2); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + discriminant(_2) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 +- _3 = discriminant(_2); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 +- switchInt(move _3) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ _3 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ switchInt(const 0_isize) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + } + + bb1: { + switchInt(((_2 as Some).0: u32)) -> [0: 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 + goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 + } + + bb3: { + goto -> bb4; // scope 1 at no-location + } + + bb4: { + StorageDead(_2); // 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/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir b/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.mir new file mode 100644 index 000000000..15b0aece8 --- /dev/null +++ b/tests/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.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/tests/mir-opt/while_let_loops.rs b/tests/mir-opt/while_let_loops.rs new file mode 100644 index 000000000..fc56cd698 --- /dev/null +++ b/tests/mir-opt/while_let_loops.rs @@ -0,0 +1,14 @@ +// EMIT_MIR while_let_loops.change_loop_body.ConstProp.diff +// EMIT_MIR while_let_loops.change_loop_body.PreCodegen.after.mir + +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/tests/mir-opt/while_storage.rs b/tests/mir-opt/while_storage.rs new file mode 100644 index 000000000..afd083acb --- /dev/null +++ b/tests/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/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir new file mode 100644 index 000000000..b95d91b13 --- /dev/null +++ b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir @@ -0,0 +1,60 @@ +// 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) -> [0: 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) -> [0: 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 -> bb7; // 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: { + 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 + } +} |