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