Skip to content

Add mir-opt tests to track MIR quality. #110713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

22 changes: 0 additions & 22 deletions tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir

This file was deleted.

22 changes: 0 additions & 22 deletions tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir

This file was deleted.

3 changes: 3 additions & 0 deletions tests/mir-opt/pre-codegen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The goal of this directory is to track the quality of MIR that is given to codegen in a standard `-O` condiguration.

As such, feel free to `--bless` whatever changes you get here, so long as doing so doesn't add substantially more MIR.
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// compile-flags: -Zmir-opt-level=2 -Zinline-mir
// compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0
// ignore-debug: standard library debug assertions add a panic that breaks this optimization

#![crate_type = "lib"]

pub enum Thing {
A,
B,
}

// EMIT_MIR instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir
// EMIT_MIR duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
pub unsafe fn ub_if_b(t: Thing) -> Thing {
match t {
Thing::A => t,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// MIR for `ub_if_b` after PreCodegen

fn ub_if_b(_1: Thing) -> Thing {
debug t => _1; // in scope 0 at $DIR/duplicate_switch_targets.rs:+0:23: +0:24
let mut _0: Thing; // return place in scope 0 at $DIR/duplicate_switch_targets.rs:+0:36: +0:41
let mut _2: isize; // in scope 0 at $DIR/duplicate_switch_targets.rs:+2:9: +2:17
scope 1 (inlined unreachable_unchecked) { // at $DIR/duplicate_switch_targets.rs:15:21: 15:55
scope 2 {
scope 3 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
}
}
}

bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/duplicate_switch_targets.rs:+1:11: +1:12
switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/duplicate_switch_targets.rs:+1:5: +1:12
}

bb1: {
unreachable; // scope 2 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
}

bb2: {
_0 = move _1; // scope 0 at $DIR/duplicate_switch_targets.rs:+2:21: +2:22
return; // scope 0 at $DIR/duplicate_switch_targets.rs:+5:2: +5:2
}
}
26 changes: 26 additions & 0 deletions tests/mir-opt/pre-codegen/intrinsics.f_u64.PreCodegen.after.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// MIR for `f_u64` after PreCodegen

fn f_u64() -> () {
let mut _0: (); // return place in scope 0 at $DIR/intrinsics.rs:+0:16: +0:16
let mut _1: u64; // in scope 0 at $DIR/intrinsics.rs:+1:5: +1:21
scope 1 (inlined f_dispatch::<u64>) { // at $DIR/intrinsics.rs:19:5: 19:21
debug t => const 0_u64; // in scope 1 at $DIR/intrinsics.rs:23:22: 23:23
let _2: (); // in scope 1 at $DIR/intrinsics.rs:27:9: 27:21
scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/intrinsics.rs:24:8: 24:32
}
}

bb0: {
StorageLive(_1); // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21
_1 = const 0_u64; // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21
_2 = f_non_zst::<u64>(move _1) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/intrinsics.rs:27:9: 27:21
// mir::Constant
// + span: $DIR/intrinsics.rs:27:9: 27:18
// + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) }
}

bb1: {
StorageDead(_1); // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21
return; // scope 0 at $DIR/intrinsics.rs:+2:2: +2:2
}
}
22 changes: 22 additions & 0 deletions tests/mir-opt/pre-codegen/intrinsics.f_unit.PreCodegen.after.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// MIR for `f_unit` after PreCodegen

fn f_unit() -> () {
let mut _0: (); // return place in scope 0 at $DIR/intrinsics.rs:+0:17: +0:17
scope 1 (inlined f_dispatch::<()>) { // at $DIR/intrinsics.rs:13:5: 13:19
debug t => const (); // in scope 1 at $DIR/intrinsics.rs:23:22: 23:23
let _1: (); // in scope 1 at $DIR/intrinsics.rs:25:9: 25:17
scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/intrinsics.rs:24:8: 24:32
}
}

bb0: {
_1 = f_zst::<()>(const ()) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/intrinsics.rs:25:9: 25:17
// mir::Constant
// + span: $DIR/intrinsics.rs:25:9: 25:14
// + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) }
}

bb1: {
return; // scope 0 at $DIR/intrinsics.rs:+2:2: +2:2
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
// only-64bit
// ignore-debug

// 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
// EMIT_MIR intrinsics.f_unit.PreCodegen.after.mir
pub fn f_unit() {
f_dispatch(());
}


// EMIT_MIR lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
// EMIT_MIR intrinsics.f_u64.PreCodegen.after.mir
pub fn f_u64() {
f_dispatch(0u64);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// ignore-wasm32 compiled with panic=abort by default
// unit-test
// compile-flags: -C overflow-checks=on

struct Point {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// MIR for `forward_loop` after PreCodegen

fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
debug start => _1; // in scope 0 at $DIR/range_iter.rs:+0:21: +0:26
debug end => _2; // in scope 0 at $DIR/range_iter.rs:+0:33: +0:36
debug f => _3; // in scope 0 at $DIR/range_iter.rs:+0:43: +0:44
let mut _0: (); // return place in scope 0 at $DIR/range_iter.rs:+0:60: +0:60
let mut _4: std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let mut _5: std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let _6: (); // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let mut _8: &mut std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let mut _9: isize; // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6
let mut _11: &impl Fn(u32); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10
let mut _12: (u32,); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13
scope 1 {
debug iter => _5; // in scope 1 at $DIR/range_iter.rs:+1:14: +1:24
let _10: u32; // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10
scope 2 {
debug x => _10; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10
}
scope 4 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) { // at $DIR/range_iter.rs:21:14: 21:24
debug self => _8; // in scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
}
}
scope 3 (inlined <std::ops::Range<u32> as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:21:14: 21:24
debug self => _4; // in scope 3 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}

bb0: {
_4 = std::ops::Range::<u32> { start: _1, end: _2 }; // scope 0 at $DIR/range_iter.rs:+1:14: +1:24
StorageLive(_5); // scope 0 at $DIR/range_iter.rs:+1:14: +1:24
_5 = move _4; // scope 0 at $DIR/range_iter.rs:+1:14: +1:24
goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
}

bb1: {
StorageLive(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
_8 = &mut _5; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
_7 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(_8) -> [return: bb9, unwind: bb7]; // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
// + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<u32>) -> Option<<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) }
}

bb2: {
_10 = ((_7 as Some).0: u32); // scope 1 at $DIR/range_iter.rs:+1:9: +1:10
StorageLive(_11); // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
_11 = &_3; // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
StorageLive(_12); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
_12 = (_10,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
_6 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb7]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
// mir::Constant
// + span: $DIR/range_iter.rs:22:9: 22:10
// + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> <impl Fn(u32) as FnOnce<(u32,)>>::Output {<impl Fn(u32) as Fn<(u32,)>>::call}, val: Value(<ZST>) }
}

bb3: {
unreachable; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
}

bb4: {
StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
StorageDead(_5); // scope 0 at $DIR/range_iter.rs:+3:5: +3:6
drop(_3) -> bb6; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
}

bb5: {
StorageDead(_12); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
StorageDead(_11); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
}

bb6: {
return; // scope 0 at $DIR/range_iter.rs:+4:2: +4:2
}

bb7 (cleanup): {
drop(_3) -> [return: bb8, unwind terminate]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
}

bb8 (cleanup): {
resume; // scope 0 at $DIR/range_iter.rs:+0:1: +4:2
}

bb9: {
_9 = discriminant(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// MIR for `inclusive_loop` after PreCodegen

fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
debug start => _1; // in scope 0 at $DIR/range_iter.rs:+0:23: +0:28
debug end => _2; // in scope 0 at $DIR/range_iter.rs:+0:35: +0:38
debug f => _3; // in scope 0 at $DIR/range_iter.rs:+0:45: +0:46
let mut _0: (); // return place in scope 0 at $DIR/range_iter.rs:+0:62: +0:62
let mut _4: std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let mut _5: std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let _6: (); // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let mut _8: &mut std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let mut _9: isize; // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6
let mut _11: &impl Fn(u32); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10
let mut _12: (u32,); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13
scope 1 {
debug iter => _5; // in scope 1 at $DIR/range_iter.rs:+1:14: +1:25
let _10: u32; // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10
scope 2 {
debug x => _10; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10
}
scope 5 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) { // at $DIR/range_iter.rs:28:14: 28:25
debug self => _8; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
}
}
scope 3 (inlined RangeInclusive::<u32>::new) { // at $DIR/range_iter.rs:28:14: 28:25
debug start => _1; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL
debug end => _2; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL
}
scope 4 (inlined <RangeInclusive<u32> as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:28:14: 28:25
debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}

bb0: {
_4 = RangeInclusive::<u32> { start: _1, end: _2, exhausted: const false }; // scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL
StorageLive(_5); // scope 0 at $DIR/range_iter.rs:+1:14: +1:25
_5 = move _4; // scope 0 at $DIR/range_iter.rs:+1:14: +1:25
goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
}

bb1: {
StorageLive(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
_8 = &mut _5; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
_7 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(_8) -> [return: bb9, unwind: bb7]; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
// + literal: Const { ty: for<'a> fn(&'a mut RangeInclusive<u32>) -> Option<<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::Item> {<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next}, val: Value(<ZST>) }
}

bb2: {
_10 = ((_7 as Some).0: u32); // scope 1 at $DIR/range_iter.rs:+1:9: +1:10
StorageLive(_11); // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
_11 = &_3; // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
StorageLive(_12); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
_12 = (_10,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
_6 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb7]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
// mir::Constant
// + span: $DIR/range_iter.rs:29:9: 29:10
// + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> <impl Fn(u32) as FnOnce<(u32,)>>::Output {<impl Fn(u32) as Fn<(u32,)>>::call}, val: Value(<ZST>) }
}

bb3: {
unreachable; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
}

bb4: {
StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
StorageDead(_5); // scope 0 at $DIR/range_iter.rs:+3:5: +3:6
drop(_3) -> bb6; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
}

bb5: {
StorageDead(_12); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
StorageDead(_11); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
}

bb6: {
return; // scope 0 at $DIR/range_iter.rs:+4:2: +4:2
}

bb7 (cleanup): {
drop(_3) -> [return: bb8, unwind terminate]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
}

bb8 (cleanup): {
resume; // scope 0 at $DIR/range_iter.rs:+0:1: +4:2
}

bb9: {
_9 = discriminant(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
}
}
Loading