blob: 2bd510fd3b9db34f954bfc9ddb84fdbbb24fcd84 [file] [log] [blame]
//@ 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()
}
}
}