| //@ 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() |
| } |
| } |
| } |