about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-07-08 16:28:16 +0200
committerGitHub <noreply@github.com>2024-07-08 16:28:16 +0200
commit3e8e8df7c0548f252138a9f2b036a3d7ba758fb0 (patch)
tree17c4f917328123b3e176c58126db568c54913c48
parent5b6eb28bda94180c754dd1a0f3d4f6f81c1494bd (diff)
parent12edc8db876515e6922623006c9b8d0c34b15f51 (diff)
Rollup merge of #127399 - cjgillot:issue-127396, r=oli-obk
Verify that allocations output by GVN are sufficiently aligned.

Fixes #127396

r? `@oli-obk`
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs14
-rw-r--r--tests/ui/mir/alignment/misaligned-constant-gvn.rs8
2 files changed, 17 insertions, 5 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 2b7d9be6d35..1002746e553 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -1391,11 +1391,15 @@ fn op_to_prop_const<'tcx>(
         let (prov, offset) = pointer.into_parts();
         let alloc_id = prov.alloc_id();
         intern_const_alloc_for_constprop(ecx, alloc_id).ok()?;
-        if matches!(ecx.tcx.global_alloc(alloc_id), GlobalAlloc::Memory(_)) {
-            // `alloc_id` may point to a static. Codegen will choke on an `Indirect` with anything
-            // by `GlobalAlloc::Memory`, so do fall through to copying if needed.
-            // FIXME: find a way to treat this more uniformly
-            // (probably by fixing codegen)
+
+        // `alloc_id` may point to a static. Codegen will choke on an `Indirect` with anything
+        // by `GlobalAlloc::Memory`, so do fall through to copying if needed.
+        // FIXME: find a way to treat this more uniformly (probably by fixing codegen)
+        if let GlobalAlloc::Memory(alloc) = ecx.tcx.global_alloc(alloc_id)
+            // Transmuting a constant is just an offset in the allocation. If the alignment of the
+            // allocation is not enough, fallback to copying into a properly aligned value.
+            && alloc.inner().align >= op.layout.align.abi
+        {
             return Some(ConstValue::Indirect { alloc_id, offset });
         }
     }
diff --git a/tests/ui/mir/alignment/misaligned-constant-gvn.rs b/tests/ui/mir/alignment/misaligned-constant-gvn.rs
new file mode 100644
index 00000000000..363d5c0ed34
--- /dev/null
+++ b/tests/ui/mir/alignment/misaligned-constant-gvn.rs
@@ -0,0 +1,8 @@
+//@ build-pass
+//@ compile-flags: -Zmir-opt-level=0 -Zmir-enable-passes=+GVN
+
+fn main() {
+    let variant: Option<u32> = None;
+    let transmuted: u64 = unsafe { std::mem::transmute(variant) };
+    println!("{transmuted}");
+}