@@ -18,7 +18,6 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
1818use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
1919use rustc_middle:: ty:: { self , Instance , Ty } ;
2020use rustc_middle:: { bug, span_bug} ;
21- use rustc_monomorphize:: is_call_from_compiler_builtins_to_upstream_monomorphization;
2221use rustc_session:: config:: OptLevel ;
2322use rustc_span:: { source_map:: Spanned , sym, Span } ;
2423use rustc_target:: abi:: call:: { ArgAbi , FnAbi , PassMode , Reg } ;
@@ -1887,3 +1886,31 @@ enum ReturnDest<'tcx, V> {
18871886 /// Store a direct return value to an operand local place.
18881887 DirectOperand ( mir:: Local ) ,
18891888}
1889+
1890+ /// Returns whether a call from the current crate to the [`Instance`] would produce a call
1891+ /// from `compiler_builtins` to a symbol the linker must resolve.
1892+ ///
1893+ /// Such calls from `compiler_bultins` are effectively impossible for the linker to handle. Some
1894+ /// linkers will optimize such that dead calls to unresolved symbols are not an error, but this is
1895+ /// not guaranteed. So we used this function in codegen backends to ensure we do not generate any
1896+ /// unlinkable calls.
1897+ ///
1898+ /// Note that calls to LLVM intrinsics are uniquely okay because they won't make it to the linker.
1899+ fn is_call_from_compiler_builtins_to_upstream_monomorphization < ' tcx > (
1900+ tcx : TyCtxt < ' tcx > ,
1901+ instance : Instance < ' tcx > ,
1902+ ) -> bool {
1903+ fn is_llvm_intrinsic ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
1904+ if let Some ( name) = tcx. codegen_fn_attrs ( def_id) . link_name {
1905+ name. as_str ( ) . starts_with ( "llvm." )
1906+ } else {
1907+ false
1908+ }
1909+ }
1910+
1911+ let def_id = instance. def_id ( ) ;
1912+ !def_id. is_local ( )
1913+ && tcx. is_compiler_builtins ( LOCAL_CRATE )
1914+ && !is_llvm_intrinsic ( tcx, def_id)
1915+ && !tcx. should_codegen_locally ( instance)
1916+ }
0 commit comments