diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 320765e7af34a..63f033dc683d5 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -203,13 +203,28 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { cx: &PartitioningCx<'_, 'tcx>, partitioning: &mut PostInliningPartitioning<'tcx>, ) { + // Collect symbols used by GlobalAsm. A GlobalAsm effectively acts like + // its own codegen unit and needs to be able to access symbols that it + // imports using sym operands. + let mut global_asm_map: FxHashSet> = Default::default(); + cx.inlining_map.iter_accesses(|accessor, accessees| { + if let MonoItem::GlobalAsm(_) = accessor { + for accessee in accessees { + global_asm_map.insert(*accessee); + } + } + }); + if partitioning.codegen_units.len() == 1 { // Fast path for when there is only one codegen unit. In this case we // can internalize all candidates, since there is nowhere else they // could be accessed from. for cgu in &mut partitioning.codegen_units { for candidate in &partitioning.internalization_candidates { - cgu.items_mut().insert(*candidate, (Linkage::Internal, Visibility::Default)); + if !global_asm_map.contains(candidate) { + cgu.items_mut() + .insert(*candidate, (Linkage::Internal, Visibility::Default)); + } } } @@ -255,6 +270,11 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { } } + // Don't internalize symbols used by GlobalAsm. + if global_asm_map.contains(accessee) { + continue; + } + // If we got here, we did not find any accesses from other CGUs, // so it's fine to make this monomorphization internal. *linkage_and_visibility = (Linkage::Internal, Visibility::Default); diff --git a/src/test/ui/issues/issue-96797.rs b/src/test/ui/issues/issue-96797.rs new file mode 100644 index 0000000000000..c5ac92f7d9517 --- /dev/null +++ b/src/test/ui/issues/issue-96797.rs @@ -0,0 +1,22 @@ +// build-pass +// compile-flags: -O + +// regression test for #96797 + +#![feature(asm_sym)] + +use std::arch::global_asm; + +#[no_mangle] +fn my_func() {} + +global_asm!("call_foobar: jmp {}", sym foobar); + +fn foobar() {} + +fn main() { + extern "Rust" { + fn call_foobar(); + } + unsafe { call_foobar() }; +}