From 6aebb2cfec13f42e6dbae95416074f3040054b0d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 5 Jul 2024 22:54:42 +0000 Subject: [PATCH 1/3] Add test. --- tests/ui/mir/alignment/misaligned-constant-gvn.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/ui/mir/alignment/misaligned-constant-gvn.rs 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 0000000000000..363d5c0ed34c6 --- /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 = None; + let transmuted: u64 = unsafe { std::mem::transmute(variant) }; + println!("{transmuted}"); +} From b97f83b27fb23a0930630f23e3c113b8b542a43d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 5 Jul 2024 22:55:09 +0000 Subject: [PATCH 2/3] Verify that allocations output by GVN are sufficiently aligned. --- compiler/rustc_mir_transform/src/gvn.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 2b7d9be6d350b..2c20c75df1f12 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 alignement of the + // allocation is noe enough, fallback to copying into a properly aligned value. + && alloc.inner().align >= op.layout.align.abi + { return Some(ConstValue::Indirect { alloc_id, offset }); } } From 12edc8db876515e6922623006c9b8d0c34b15f51 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 6 Jul 2024 12:45:23 +0200 Subject: [PATCH 3/3] Update compiler/rustc_mir_transform/src/gvn.rs Co-authored-by: Michael Goulet --- compiler/rustc_mir_transform/src/gvn.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 2c20c75df1f12..1002746e553d7 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1396,8 +1396,8 @@ fn op_to_prop_const<'tcx>( // 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 alignement of the - // allocation is noe enough, fallback to copying into a properly aligned value. + // 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 });