| //@ test-mir-pass: SimplifyCfg-final | |
| //@ compile-flags: -Zmir-enable-passes=+DeadStoreElimination-initial | |
| #![feature(core_intrinsics, custom_mir)] | |
| #![crate_type = "lib"] | |
| use std::intrinsics::mir::*; | |
| pub struct Foo { | |
| a: i32, | |
| b: i64, | |
| c: i32, | |
| } | |
| // EMIT_MIR simplifycfg.drop_debuginfo.SimplifyCfg-final.diff | |
| #[custom_mir(dialect = "runtime", phase = "post-cleanup")] | |
| pub fn drop_debuginfo(foo: &Foo, c: bool) -> i32 { | |
| // CHECK-LABEL: fn drop_debuginfo | |
| // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; | |
| // CHECK: bb0: { | |
| // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) | |
| // CHECK-NEXT: _0 = copy ((*_1).2: i32); | |
| // CHECK-NEXT: return; | |
| mir! { | |
| let _foo_a: &i32; | |
| let _foo_b: &i64; | |
| debug foo_a => _foo_a; | |
| debug foo_b => _foo_b; | |
| { | |
| match c { | |
| true => tmp, | |
| _ => ret, | |
| } | |
| } | |
| tmp = { | |
| // Because we don't know if `c` is always true, we must drop this debuginfo. | |
| _foo_a = &(*foo).a; | |
| Goto(ret) | |
| } | |
| ret = { | |
| _foo_b = &(*foo).b; | |
| RET = (*foo).c; | |
| Return() | |
| } | |
| } | |
| } | |
| // EMIT_MIR simplifycfg.preserve_debuginfo_1.SimplifyCfg-final.diff | |
| #[custom_mir(dialect = "runtime", phase = "post-cleanup")] | |
| pub fn preserve_debuginfo_1(foo: &Foo, v: &mut bool) -> i32 { | |
| // CHECK-LABEL: fn preserve_debuginfo_1 | |
| // CHECK: debug foo_a => [[foo_a:_[0-9]+]]; | |
| // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; | |
| // CHECK: debug foo_c => [[foo_c:_[0-9]+]]; | |
| // CHECK: bb0: { | |
| // CHECK-NEXT: (*_2) = const true; | |
| // CHECK-NEXT: DBG: [[foo_a]] = &((*_1).0: i32) | |
| // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) | |
| // CHECK-NEXT: _0 = copy ((*_1).2: i32); | |
| // CHECK-NEXT: DBG: [[foo_c]] = &((*_1).2: i32) | |
| // CHECK-NEXT: return; | |
| mir! { | |
| let _foo_a: &i32; | |
| let _foo_b: &i64; | |
| let _foo_c: &i32; | |
| debug foo_a => _foo_a; | |
| debug foo_b => _foo_b; | |
| debug foo_c => _foo_c; | |
| { | |
| Goto(tmp) | |
| } | |
| tmp = { | |
| *v = true; | |
| _foo_a = &(*foo).a; | |
| Goto(ret) | |
| } | |
| ret = { | |
| _foo_b = &(*foo).b; | |
| RET = (*foo).c; | |
| _foo_c = &(*foo).c; | |
| Return() | |
| } | |
| } | |
| } | |
| // EMIT_MIR simplifycfg.preserve_debuginfo_2.SimplifyCfg-final.diff | |
| #[custom_mir(dialect = "runtime", phase = "post-cleanup")] | |
| pub fn preserve_debuginfo_2(foo: &Foo) -> i32 { | |
| // CHECK-LABEL: fn preserve_debuginfo_2 | |
| // CHECK: debug foo_a => [[foo_a:_[0-9]+]]; | |
| // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; | |
| // CHECK: debug foo_c => [[foo_c:_[0-9]+]]; | |
| // CHECK: bb0: { | |
| // CHECK-NEXT: DBG: [[foo_a]] = &((*_1).0: i32) | |
| // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) | |
| // CHECK-NEXT: _0 = copy ((*_1).2: i32); | |
| // CHECK-NEXT: DBG: [[foo_c]] = &((*_1).2: i32) | |
| // CHECK-NEXT: return; | |
| mir! { | |
| let _foo_a: &i32; | |
| let _foo_b: &i64; | |
| let _foo_c: &i32; | |
| debug foo_a => _foo_a; | |
| debug foo_b => _foo_b; | |
| debug foo_c => _foo_c; | |
| { | |
| Goto(tmp) | |
| } | |
| tmp = { | |
| _foo_a = &(*foo).a; | |
| Goto(ret) | |
| } | |
| ret = { | |
| _foo_b = &(*foo).b; | |
| RET = (*foo).c; | |
| _foo_c = &(*foo).c; | |
| Return() | |
| } | |
| } | |
| } | |
| // EMIT_MIR simplifycfg.preserve_debuginfo_3.SimplifyCfg-final.diff | |
| #[custom_mir(dialect = "runtime", phase = "post-cleanup")] | |
| pub fn preserve_debuginfo_3(foo: &Foo, c: bool) -> i32 { | |
| // CHECK-LABEL: fn preserve_debuginfo_3 | |
| // CHECK: debug foo_a => [[foo_a:_[0-9]+]]; | |
| // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; | |
| // CHECK: debug foo_c => [[foo_c:_[0-9]+]]; | |
| // CHECK: bb0: { | |
| // CHECK-NEXT: switchInt(copy _2) -> [1: bb2, otherwise: bb1]; | |
| // CHECK: bb1: { | |
| // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) | |
| // CHECK-NEXT: _0 = copy ((*_1).2: i32); | |
| // CHECK-NEXT: return; | |
| // CHECK: bb2: { | |
| // CHECK-NEXT: DBG: [[foo_a]] = &((*_1).0: i32) | |
| // CHECK-NEXT: DBG: [[foo_c]] = &((*_1).2: i32) | |
| // CHECK-NEXT: _0 = copy ((*_1).0: i32); | |
| // CHECK-NEXT: return; | |
| mir! { | |
| let _foo_a: &i32; | |
| let _foo_b: &i64; | |
| let _foo_c: &i32; | |
| debug foo_a => _foo_a; | |
| debug foo_b => _foo_b; | |
| debug foo_c => _foo_c; | |
| { | |
| match c { | |
| true => tmp, | |
| _ => ret, | |
| } | |
| } | |
| tmp = { | |
| _foo_a = &(*foo).a; | |
| Goto(ret_1) | |
| } | |
| ret = { | |
| _foo_b = &(*foo).b; | |
| RET = (*foo).c; | |
| Return() | |
| } | |
| ret_1 = { | |
| _foo_c = &(*foo).c; | |
| RET = (*foo).a; | |
| Return() | |
| } | |
| } | |
| } | |
| // EMIT_MIR simplifycfg.preserve_debuginfo_identical_succs.SimplifyCfg-final.diff | |
| #[custom_mir(dialect = "runtime", phase = "post-cleanup")] | |
| pub fn preserve_debuginfo_identical_succs(foo: &Foo, c: bool) -> i32 { | |
| // CHECK-LABEL: fn preserve_debuginfo_identical_succs | |
| // CHECK: debug foo_a => [[foo_a:_[0-9]+]]; | |
| // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; | |
| // CHECK: debug foo_c => [[foo_c:_[0-9]+]]; | |
| // CHECK: bb0: { | |
| // CHECK-NEXT: DBG: [[foo_a]] = &((*_1).0: i32) | |
| // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) | |
| // CHECK-NEXT: _0 = copy ((*_1).2: i32); | |
| // CHECK-NEXT: DBG: [[foo_c]] = &((*_1).2: i32) | |
| // CHECK-NEXT: return; | |
| mir! { | |
| let _foo_a: &i32; | |
| let _foo_b: &i64; | |
| let _foo_c: &i32; | |
| debug foo_a => _foo_a; | |
| debug foo_b => _foo_b; | |
| debug foo_c => _foo_c; | |
| { | |
| match c { | |
| true => tmp, | |
| _ => tmp, | |
| } | |
| } | |
| tmp = { | |
| _foo_a = &(*foo).a; | |
| Goto(ret) | |
| } | |
| ret = { | |
| _foo_b = &(*foo).b; | |
| RET = (*foo).c; | |
| _foo_c = &(*foo).c; | |
| Return() | |
| } | |
| } | |
| } |