about summary refs log tree commit diff
path: root/tests/mir-opt/sroa
diff options
context:
space:
mode:
authorJarl Evanson <evanson.jarl@gmail.com>2024-02-04 12:04:39 -0600
committerJarl Evanson <evanson.jarl@gmail.com>2024-02-04 12:04:39 -0600
commitbae4f177b8767f6acab5474c6fec2734df759a32 (patch)
tree05b444485606019c1f505e6ea72650238e52d6d3 /tests/mir-opt/sroa
parent103159809aa83e00111f3b35be7281b8165681bc (diff)
downloadrust-bae4f177b8767f6acab5474c6fec2734df759a32.tar.gz
rust-bae4f177b8767f6acab5474c6fec2734df759a32.zip
Enable `structs` SROA MIR-opt test
Diffstat (limited to 'tests/mir-opt/sroa')
-rw-r--r--tests/mir-opt/sroa/structs.rs125
1 files changed, 119 insertions, 6 deletions
diff --git a/tests/mir-opt/sroa/structs.rs b/tests/mir-opt/sroa/structs.rs
index 73563e12c94..5ea3795b86e 100644
--- a/tests/mir-opt/sroa/structs.rs
+++ b/tests/mir-opt/sroa/structs.rs
@@ -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.);