about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-09-07 14:02:09 +0000
committerbors <bors@rust-lang.org>2025-09-07 14:02:09 +0000
commit55b9b4d1e1bb5b46c04237a2fb2f8a85f39ef97d (patch)
treedc133ae879bc5bf30c4e7f6083593f1c05069c2d /tests
parentf13ef0d75d834c826c9479a5d244bcfb9891df45 (diff)
parent52f74a5162e20e6b9bc8a94f61009fd9d4f38fdb (diff)
downloadrust-55b9b4d1e1bb5b46c04237a2fb2f8a85f39ef97d.tar.gz
rust-55b9b4d1e1bb5b46c04237a2fb2f8a85f39ef97d.zip
Auto merge of #146289 - cjgillot:gvn-aggregate, r=dianqk
GVN: Allow reusing aggregates if LHS is not a simple local.

This resolves a FIXME in the code. I don't see a reason not to allow this.
Diffstat (limited to 'tests')
-rw-r--r--tests/mir-opt/gvn_overlapping.fields.GVN.diff14
-rw-r--r--tests/mir-opt/gvn_overlapping.rs42
-rw-r--r--tests/mir-opt/gvn_overlapping.stable_projection.GVN.diff19
3 files changed, 73 insertions, 2 deletions
diff --git a/tests/mir-opt/gvn_overlapping.fields.GVN.diff b/tests/mir-opt/gvn_overlapping.fields.GVN.diff
new file mode 100644
index 00000000000..0548f4e42e4
--- /dev/null
+++ b/tests/mir-opt/gvn_overlapping.fields.GVN.diff
@@ -0,0 +1,14 @@
+- // MIR for `fields` before GVN
++ // MIR for `fields` after GVN
+  
+  fn fields(_1: (Adt, Adt)) -> () {
+      let mut _0: ();
+      let mut _2: u32;
+  
+      bb0: {
+          _2 = copy (((_1.0: Adt) as variant#1).0: u32);
+          (_1.1: Adt) = Adt::Some(copy _2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn_overlapping.rs b/tests/mir-opt/gvn_overlapping.rs
index 99113445e68..f148a843561 100644
--- a/tests/mir-opt/gvn_overlapping.rs
+++ b/tests/mir-opt/gvn_overlapping.rs
@@ -2,11 +2,10 @@
 
 #![feature(custom_mir, core_intrinsics)]
 
-// Check that we do not create overlapping assignments.
-
 use std::intrinsics::mir::*;
 
 // EMIT_MIR gvn_overlapping.overlapping.GVN.diff
+/// Check that we do not create overlapping assignments.
 #[custom_mir(dialect = "runtime")]
 fn overlapping(_17: Adt) {
     // CHECK-LABEL: fn overlapping(
@@ -26,6 +25,45 @@ fn overlapping(_17: Adt) {
     }
 }
 
+// EMIT_MIR gvn_overlapping.stable_projection.GVN.diff
+/// Check that we allow dereferences in the RHS if the LHS is a stable projection.
+#[custom_mir(dialect = "runtime")]
+fn stable_projection(_1: (Adt,)) {
+    // CHECK-LABEL: fn stable_projection(
+    // CHECK: let mut _2: *mut Adt;
+    // CHECK: let mut _4: &Adt;
+    // CHECK: (_1.0: Adt) = copy (*_4);
+    mir! {
+        let _2: *mut Adt;
+        let _3: u32;
+        let _4: &Adt;
+        {
+            _2 = core::ptr::addr_of_mut!(_1.0);
+            _4 = &(*_2);
+            _3 = Field(Variant((*_4), 1), 0);
+            _1.0 = Adt::Some(_3);
+            Return()
+        }
+    }
+}
+
+// EMIT_MIR gvn_overlapping.fields.GVN.diff
+/// Check that we do not create assignments between different fields of the same local.
+#[custom_mir(dialect = "runtime")]
+fn fields(_1: (Adt, Adt)) {
+    // CHECK-LABEL: fn fields(
+    // CHECK: _2 = copy (((_1.0: Adt) as variant#1).0: u32);
+    // CHECK-NEXT: (_1.1: Adt) = Adt::Some(copy _2);
+    mir! {
+        let _2: u32;
+        {
+            _2 = Field(Variant(_1.0, 1), 0);
+            _1.1 = Adt::Some(_2);
+            Return()
+        }
+    }
+}
+
 fn main() {
     overlapping(Adt::Some(0));
 }
diff --git a/tests/mir-opt/gvn_overlapping.stable_projection.GVN.diff b/tests/mir-opt/gvn_overlapping.stable_projection.GVN.diff
new file mode 100644
index 00000000000..08835456591
--- /dev/null
+++ b/tests/mir-opt/gvn_overlapping.stable_projection.GVN.diff
@@ -0,0 +1,19 @@
+- // MIR for `stable_projection` before GVN
++ // MIR for `stable_projection` after GVN
+  
+  fn stable_projection(_1: (Adt,)) -> () {
+      let mut _0: ();
+      let mut _2: *mut Adt;
+      let mut _3: u32;
+      let mut _4: &Adt;
+  
+      bb0: {
+          _2 = &raw mut (_1.0: Adt);
+          _4 = &(*_2);
+          _3 = copy (((*_4) as variant#1).0: u32);
+-         (_1.0: Adt) = Adt::Some(copy _3);
++         (_1.0: Adt) = copy (*_4);
+          return;
+      }
+  }
+