Skip to content

Commit 1119421

Browse files
authored
Rollup merge of #72325 - alexcrichton:ignore-linker-plugin-lto, r=nnethercote
Always generated object code for `#![no_builtins]` This commit updates the code generation for `#![no_builtins]` to always produce object files instead of conditionally respecting `-Clinker-plugin-lto` and sometimes producing bitcode. This is intended to address rust-lang/cargo#8239. The issue at hand here is that Cargo has tried to get "smarter" about codegen in whole crate graph scenarios. When LTO is enabled it attempts to avoid codegen on as many crates as possible, opting to pass `-Clinker-plugin-lto` where it can to only generate bitcode. When this is combined with `-Zbuild-std`, however, it means that `compiler-builtins` only generates LLVM bitcode instead of object files. Rustc's own LTO passes then explicitly skip `compiler-builtins` (because it wouldn't work anyway) which means that LLVM bitcode gets sent to the linker, which chokes most of the time. The fix in this PR is to not actually respect `-Clinker-plugin-lto` for `#![no_builtins]` crates. These crates, even if slurped up by the linker rather than rustc, will not work with LTO. They define symbols which are only referenced as part of codegen, so LTO's aggressive internalization would trivially remove the symbols only to have the linker realize later that the symbol is undefined. Since pure-bitcode never makes sense for these libraries, the `-Clinker-plugin-lto` flag is silently ignored.
2 parents 62d4e9e + cc91041 commit 1119421

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

src/librustc_codegen_ssa/back/write.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,22 @@ impl ModuleConfig {
142142
let emit_obj = if !should_emit_obj {
143143
EmitObj::None
144144
} else if sess.target.target.options.obj_is_bitcode
145-
|| sess.opts.cg.linker_plugin_lto.enabled()
145+
|| (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins)
146146
{
147+
// This case is selected if the target uses objects as bitcode, or
148+
// if linker plugin LTO is enabled. In the linker plugin LTO case
149+
// the assumption is that the final link-step will read the bitcode
150+
// and convert it to object code. This may be done by either the
151+
// native linker or rustc itself.
152+
//
153+
// Note, however, that the linker-plugin-lto requested here is
154+
// explicitly ignored for `#![no_builtins]` crates. These crates are
155+
// specifically ignored by rustc's LTO passes and wouldn't work if
156+
// loaded into the linker. These crates define symbols that LLVM
157+
// lowers intrinsics to, and these symbol dependencies aren't known
158+
// until after codegen. As a result any crate marked
159+
// `#![no_builtins]` is assumed to not participate in LTO and
160+
// instead goes on to generate object code.
147161
EmitObj::Bitcode
148162
} else if need_bitcode_in_object(sess) {
149163
EmitObj::ObjectCode(BitcodeSection::Full)

0 commit comments

Comments
 (0)