207 lines
5.8 KiB
Rust
207 lines
5.8 KiB
Rust
//@ 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()
|
|
}
|
|
}
|
|
}
|