Rollup merge of #120455 - JarlEvanson:sroa-miri-tests, r=cjgillot

Add FileCheck annotations to MIR-opt SROA tests

Part of #116971, adds FileCheck annotations to SROA MIR-opt tests in `tests/mir-opt/sroa` and a few uncategorized files.

r? cjgillot
This commit is contained in:
Guillaume Boisseau 2024-02-07 18:24:42 +01:00 committed by GitHub
commit 65c09546ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 130 additions and 8 deletions

View file

@ -1,4 +1,3 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: RemoveStorageMarkers
@ -8,6 +7,10 @@
// EMIT_MIR remove_storage_markers.main.RemoveStorageMarkers.diff
fn main() {
// CHECK-LABEL: fn main(
// CHECK-NOT: StorageDead
// CHECK-NOT: StorageLive
let mut sum = 0;
for i in 0..10 {
sum += i;

View file

@ -1,10 +1,13 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
#[inline(never)]
fn noop() {}
// EMIT_MIR simplify_if.main.SimplifyConstCondition-after-const-prop.diff
fn main() {
// CHECK-LABEL: fn main(
// CHECK: bb0: {
// CHECK-NEXT: return;
if false {
noop();
}

View file

@ -1,4 +1,3 @@
// skip-filecheck
// unit-test: ScalarReplacementOfAggregates
// compile-flags: -Cpanic=abort
// no-prefer-dynamic
@ -16,6 +15,10 @@ struct Foo<T: Err> {
// EMIT_MIR lifetimes.foo.ScalarReplacementOfAggregates.diff
fn foo<T: Err>() {
// CHECK-LABEL: fn foo(
// CHECK-NOT: [foo:_.*]: Foo
// CHECK-NOT: Box<dyn std::fmt::Display + 'static>
let foo: Foo<T> = Foo {
x: Ok(Box::new(5_u32)),
y: 7_u32,

View file

@ -1,4 +1,3 @@
// skip-filecheck
// unit-test: ScalarReplacementOfAggregates
// compile-flags: -Cpanic=abort
// no-prefer-dynamic
@ -13,28 +12,68 @@ impl Drop for Tag {
fn drop(&mut self) {}
}
/// Check that SROA excludes structs with a `Drop` implementation.
pub fn dropping() {
// CHECK-LABEL: fn dropping(
// CHECK: [[aggregate:_[0-9]+]]: S;
// CHECK: bb0: {
// CHECK: [[aggregate]] = S
S(Tag(0), Tag(1), Tag(2)).1;
}
/// Check that SROA excludes enums.
pub fn enums(a: usize) -> usize {
// CHECK-LABEL: fn enums(
// CHECK: [[enum:_[0-9]+]]: std::option::Option<usize>;
// CHECK: bb0: {
// CHECK: [[enum]] = Option::<usize>::Some
// CHECK: _5 = (([[enum]] as Some).0: usize)
// CHECK: _0 = _5
if let Some(a) = Some(a) { a } else { 0 }
}
/// Check that SROA destructures `U`.
pub fn structs(a: f32) -> f32 {
// CHECK-LABEL: fn structs(
struct U {
_foo: usize,
a: f32,
}
// CHECK: [[ret:_0]]: f32;
// CHECK: [[struct:_[0-9]+]]: structs::U;
// CHECK: [[a_tmp:_[0-9]+]]: f32;
// CHECK: [[foo:_[0-9]+]]: usize;
// CHECK: [[a_ret:_[0-9]+]]: f32;
// CHECK: bb0: {
// CHECK-NOT: [[struct]]
// CHECK: [[a_tmp]] = _1;
// CHECK-NOT: [[struct]]
// CHECK: [[foo]] = const 0_usize;
// CHECK-NOT: [[struct]]
// CHECK: [[a_ret]] = move [[a_tmp]];
// CHECK-NOT: [[struct]]
// CHECK: _0 = [[a_ret]];
// CHECK-NOT: [[struct]]
U { _foo: 0, a }.a
}
/// Check that SROA excludes unions.
pub fn unions(a: f32) -> u32 {
// CHECK-LABEL: fn unions(
union Repr {
f: f32,
u: u32,
}
// CHECK: [[union:_[0-9]+]]: unions::Repr;
// CHECK: bb0: {
// CHECK: [[union]] = Repr {
// CHECK: _0 = ([[union]].1: u32)
unsafe { Repr { f: a }.u }
}
@ -46,11 +85,21 @@ struct Foo {
d: Option<isize>,
}
fn g() -> u32 {
3
}
/// Check that non-escaping uses of a struct are destructured.
pub fn flat() {
// CHECK-LABEL: fn flat(
// CHECK: [[struct:_[0-9]+]]: Foo;
// CHECK: bb0: {
// CHECK: [[init_unit:_[0-9]+]] = ();
// CHECK: [[init_opt_isize:_[0-9]+]] = Option::<isize>::Some
// CHECK: [[destr_five:_[0-9]+]] = const 5_u8;
// CHECK: [[destr_unit:_[0-9]+]] = move [[init_unit]];
// CHECK: [[destr_a:_[0-9]+]] = const "a";
// CHECK: [[destr_opt_isize:_[0-9]+]] = move [[init_opt_isize]];
let Foo { a, b, c, d } = Foo { a: 5, b: (), c: "a", d: Some(-4) };
let _ = a;
let _ = b;
@ -65,6 +114,10 @@ struct Escaping {
c: u32,
}
fn g() -> u32 {
3
}
fn f(a: *const u32) {
println!("{}", unsafe { *a.add(2) });
}
@ -76,10 +129,38 @@ fn f(a: *const u32) {
// of them to `f`. However, this would lead to a miscompilation because `b` and `c`
// might no longer appear right after `a` in memory.
pub fn escaping() {
// CHECK-LABEL: fn escaping(
// CHECK: [[ptr:_[0-9]+]]: *const u32;
// CHECK: [[ref:_[0-9]+]]: &u32;
// CHECK: [[struct:_[0-9]+]]: Escaping;
// CHECK: [[a:_[0-9]+]]: u32;
// CHECK: bb0: {
// CHECK: [[struct]] = Escaping {
// CHECK: [[ref]] = &([[struct]].0
// CHECK: [[ptr]] = &raw const (*[[ref]]);
f(&Escaping { a: 1, b: 2, c: g() }.a);
}
/// Check that copies from an internal struct are destructured and reassigned to
/// the original struct.
fn copies(x: Foo) {
// CHECK-LABEL: fn copies(
// CHECK: [[external:_[0-9]+]]: Foo) ->
// CHECK: [[internal:_[0-9]+]]: Foo;
// CHECK: [[byte:_[0-9]+]]: u8;
// CHECK: [[unit:_[0-9]+]]: ();
// CHECK: [[str:_[0-9]+]]: &str;
// CHECK: [[opt_isize:_[0-9]+]]: std::option::Option<isize>;
// CHECK: bb0: {
// CHECK: [[byte]] = ([[external]].0
// CHECK: [[unit]] = ([[external]].1
// CHECK: [[str]] = ([[external]].2
// CHECK: [[opt_isize]] = ([[external]].3
let y = x;
let t = y.a;
let u = y.c;
@ -87,13 +168,44 @@ fn copies(x: Foo) {
let a = z.b;
}
/// Check that copies from an internal struct are destructured and reassigned to
/// the original struct.
fn ref_copies(x: &Foo) {
// CHECK-LABEL: fn ref_copies(
// CHECK: [[external:_[0-9]+]]: &Foo) ->
// CHECK: [[internal:_[0-9]+]]: Foo;
// CHECK: [[byte:_[0-9]+]]: u8;
// CHECK: [[unit:_[0-9]+]]: ();
// CHECK: [[str:_[0-9]+]]: &str;
// CHECK: [[opt_isize:_[0-9]+]]: std::option::Option<isize>;
// CHECK: bb0: {
// CHECK: [[byte]] = ((*[[external]]).0
// CHECK: [[unit]] = ((*[[external]]).1
// CHECK: [[str]] = ((*[[external]]).2
// CHECK: [[opt_isize]] = ((*[[external]]).3
let y = *x;
let t = y.a;
let u = y.c;
}
/// Check that deaggregated assignments from constants are placed after the constant's
/// assignment. Also check that copying field accesses from the copy of the constant are
/// reassigned to copy from the constant.
fn constant() {
// CHECK-LABEL: constant(
// CHECK: [[constant:_[0-9]+]]: (usize, u8);
// CHECK: [[t:_[0-9]+]]: usize;
// CHECK: [[u:_[0-9]+]]: u8;
// CHECK: bb0: {
// CHECK-NOT: [[constant]]
// CHECK: [[constant]] = const
// CHECK: [[t]] = move ([[constant]].0: usize)
// CHECK: [[u]] = move ([[constant]].1: u8)
const U: (usize, u8) = (5, 9);
let y = U;
let t = y.0;
@ -101,6 +213,7 @@ fn constant() {
}
fn main() {
// CHECK-LABEL: fn main(
dropping();
enums(5);
structs(5.);