Auto merge of #123347 - saethlin:only-allow-upstream-llvm-calls, r=Nilstrieb
Only allow compiler_builtins to call LLVM intrinsics, not any link_name function This is another case of accidental reliance on `inline(never)` like I rooted out in https://github.com/rust-lang/rust/pull/118770. Without this PR, attempting to build some large programs with `-Zcross-crate-inline-threshold=yes` with a sysroot also compiled with that flag will result in linker errors like this: ``` = note: /usr/bin/ld: /tmp/cargo-installNrfN4T/x86_64-unknown-linux-gnu/release/deps/libcompiler_builtins-d2a9b69f4e45b883.rlib(compiler_builtins-d2a9b69f4e45b883.compiler_builtins.dbbc6c2ca970faa4-cgu.0.rcgu.o): in function `core::panicking::panic_fmt': /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panicking.rs:72:(.text.unlikely._ZN4core9panicking9panic_fmt17ha407cc99e97c942fE+0x31): undefined reference to `rust_begin_unwind' ``` With `-Zcross-crate-inline-threshold=yes` we can inline `panic_fmt` into `compiler_builtins`. Then we end up with a call to an upstream monomorphization, but one that has a `link_name` set. But unlike LLVM's magic intrinsic names, this link name is going to make it to the linker, and then we have a problem. This logic looks scuffed, but also we're doing this in 4 other places. Don't know if that means it's good or bad.1684a753db/compiler/rustc_codegen_cranelift/src/abi/mod.rs (L386)
1684a753db/compiler/rustc_ast_passes/src/feature_gate.rs (L306)
1684a753db/compiler/rustc_codegen_ssa/src/codegen_attrs.rs (L609)
1684a753db/compiler/rustc_codegen_gcc/src/declare.rs (L170)
This commit is contained in:
commit
0e682e9875
@ -14,6 +14,7 @@
|
|||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::def_id::LOCAL_CRATE;
|
use rustc_span::def_id::LOCAL_CRATE;
|
||||||
use rustc_span::ErrorGuaranteed;
|
use rustc_span::ErrorGuaranteed;
|
||||||
|
|
||||||
@ -57,13 +58,24 @@ fn custom_coerce_unsize_info<'tcx>(
|
|||||||
/// linkers will optimize such that dead calls to unresolved symbols are not an error, but this is
|
/// linkers will optimize such that dead calls to unresolved symbols are not an error, but this is
|
||||||
/// not guaranteed. So we used this function in codegen backends to ensure we do not generate any
|
/// not guaranteed. So we used this function in codegen backends to ensure we do not generate any
|
||||||
/// unlinkable calls.
|
/// unlinkable calls.
|
||||||
|
///
|
||||||
|
/// Note that calls to LLVM intrinsics are uniquely okay because they won't make it to the linker.
|
||||||
pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>(
|
pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
!instance.def_id().is_local()
|
fn is_llvm_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
|
if let Some(name) = tcx.codegen_fn_attrs(def_id).link_name {
|
||||||
|
name.as_str().starts_with("llvm.")
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let def_id = instance.def_id();
|
||||||
|
!def_id.is_local()
|
||||||
&& tcx.is_compiler_builtins(LOCAL_CRATE)
|
&& tcx.is_compiler_builtins(LOCAL_CRATE)
|
||||||
&& tcx.codegen_fn_attrs(instance.def_id()).link_name.is_none()
|
&& !is_llvm_intrinsic(tcx, def_id)
|
||||||
&& !should_codegen_locally(tcx, instance)
|
&& !should_codegen_locally(tcx, instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user