From 8bde2acfc7876148ebfe192780434dbb969eded3 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 16 Jan 2018 15:02:31 -0800 Subject: [PATCH] rustc: Add `-C lto=val` option This commit primarily adds the ability to control what kind of LTO happens when rustc performs LTO, namely allowing values to be specified to the `-C lto` option, such as `-C lto=thin` and `-C lto=fat`. (where "fat" is the previous kind of LTO, throw everything in one giant module) Along the way this also refactors a number of fields which store information about whether LTO/ThinLTO are enabled to unify them all into one field through which everything is dispatched, hopefully removing a number of special cases throughout. This is intended to help mitigate #47409 but will require a backport as well, and this would unfortunately need to be an otherwise insta-stable option. --- src/librustc/session/config.rs | 56 ++++++++--- src/librustc/session/mod.rs | 92 ++++++++++++------- src/librustc_trans/back/link.rs | 22 ++++- src/librustc_trans/back/lto.rs | 36 ++++---- src/librustc_trans/back/write.rs | 88 +++++++++--------- .../run-make/codegen-options-parsing/Makefile | 6 +- src/test/run-pass/fat-lto.rs | 17 ++++ src/test/run-pass/thinlto/all-crates.rs | 17 ++++ .../run-pass/thinlto/thin-lto-inlines2.rs | 2 +- 9 files changed, 221 insertions(+), 115 deletions(-) create mode 100644 src/test/run-pass/fat-lto.rs create mode 100644 src/test/run-pass/thinlto/all-crates.rs diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index da119ba4569..3fac9ce41f1 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -72,6 +72,26 @@ pub enum OptLevel { SizeMin, // -Oz } +#[derive(Clone, Copy, PartialEq, Hash)] +pub enum Lto { + /// Don't do any LTO whatsoever + No, + + /// Do a full crate graph LTO. The flavor is determined by the compiler + /// (currently the default is "fat"). + Yes, + + /// Do a full crate graph LTO with ThinLTO + Thin, + + /// Do a local graph LTO with ThinLTO (only relevant for multiple codegen + /// units). + ThinLocal, + + /// Do a full crate graph LTO with "fat" LTO + Fat, +} + #[derive(Clone, Copy, PartialEq, Hash)] pub enum DebugInfoLevel { NoDebugInfo, @@ -389,7 +409,7 @@ pub struct Options { // commands like `--emit llvm-ir` which they're often incompatible with // if we otherwise use the defaults of rustc. cli_forced_codegen_units: Option [UNTRACKED], - cli_forced_thinlto: Option [UNTRACKED], + cli_forced_thinlto_off: bool [UNTRACKED], } ); @@ -590,7 +610,7 @@ pub fn basic_options() -> Options { debug_assertions: true, actually_rustdoc: false, cli_forced_codegen_units: None, - cli_forced_thinlto: None, + cli_forced_thinlto_off: false, } } @@ -780,11 +800,13 @@ mod $mod_desc { Some("crate=integer"); pub const parse_unpretty: Option<&'static str> = Some("`string` or `string=string`"); + pub const parse_lto: Option<&'static str> = + Some("one of `thin`, `fat`, or omitted"); } #[allow(dead_code)] mod $mod_set { - use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer}; + use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto}; use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; use std::path::PathBuf; @@ -978,6 +1000,16 @@ fn parse_unpretty(slot: &mut Option, v: Option<&str>) -> bool { _ => false, } } + + fn parse_lto(slot: &mut Lto, v: Option<&str>) -> bool { + *slot = match v { + None => Lto::Yes, + Some("thin") => Lto::Thin, + Some("fat") => Lto::Fat, + Some(_) => return false, + }; + true + } } ) } @@ -994,7 +1026,7 @@ fn parse_unpretty(slot: &mut Option, v: Option<&str>) -> bool { "extra arguments to append to the linker invocation (space separated)"), link_dead_code: bool = (false, parse_bool, [UNTRACKED], "don't let linker strip dead code (turning it on can be used for code coverage)"), - lto: bool = (false, parse_bool, [TRACKED], + lto: Lto = (Lto::No, parse_lto, [TRACKED], "perform LLVM link-time optimizations"), target_cpu: Option = (None, parse_opt_string, [TRACKED], "select target processor (rustc --print target-cpus for details)"), @@ -1677,7 +1709,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) let mut cg = build_codegen_options(matches, error_format); let mut codegen_units = cg.codegen_units; - let mut thinlto = None; + let mut disable_thinlto = false; // Issue #30063: if user requests llvm-related output to one // particular path, disable codegen-units. @@ -1699,12 +1731,12 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) } early_warn(error_format, "resetting to default -C codegen-units=1"); codegen_units = Some(1); - thinlto = Some(false); + disable_thinlto = true; } } _ => { codegen_units = Some(1); - thinlto = Some(false); + disable_thinlto = true; } } } @@ -1734,7 +1766,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) (&None, &None) => None, }.map(|m| PathBuf::from(m)); - if cg.lto && incremental.is_some() { + if cg.lto != Lto::No && incremental.is_some() { early_error(error_format, "can't perform LTO when compiling incrementally"); } @@ -1934,7 +1966,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) debug_assertions, actually_rustdoc: false, cli_forced_codegen_units: codegen_units, - cli_forced_thinlto: thinlto, + cli_forced_thinlto_off: disable_thinlto, }, cfg) } @@ -2052,7 +2084,7 @@ mod dep_tracking { use std::hash::Hash; use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; - use super::{Passes, CrateType, OptLevel, DebugInfoLevel, + use super::{Passes, CrateType, OptLevel, DebugInfoLevel, Lto, OutputTypes, Externs, ErrorOutputType, Sanitizer}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; @@ -2107,6 +2139,7 @@ fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { impl_dep_tracking_hash_via_hash!(RelroLevel); impl_dep_tracking_hash_via_hash!(Passes); impl_dep_tracking_hash_via_hash!(OptLevel); + impl_dep_tracking_hash_via_hash!(Lto); impl_dep_tracking_hash_via_hash!(DebugInfoLevel); impl_dep_tracking_hash_via_hash!(UnstableFeatures); impl_dep_tracking_hash_via_hash!(Externs); @@ -2180,6 +2213,7 @@ mod tests { use lint; use middle::cstore; use session::config::{build_configuration, build_session_options_and_crate_config}; + use session::config::Lto; use session::build_session; use std::collections::{BTreeMap, BTreeSet}; use std::iter::FromIterator; @@ -2656,7 +2690,7 @@ fn test_codegen_options_tracking_hash() { // Make sure changing a [TRACKED] option changes the hash opts = reference.clone(); - opts.cg.lto = true; + opts.cg.lto = Lto::Fat; assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 36f716a4a76..02cd6a92eb7 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -498,9 +498,65 @@ pub fn emit_end_regions(&self) -> bool { self.use_mir() } - pub fn lto(&self) -> bool { - self.opts.cg.lto || self.target.target.options.requires_lto + /// Calculates the flavor of LTO to use for this compilation. + pub fn lto(&self) -> config::Lto { + // If our target has codegen requirements ignore the command line + if self.target.target.options.requires_lto { + return config::Lto::Fat + } + + // If the user specified something, return that. If they only said `-C + // lto` and we've for whatever reason forced off ThinLTO via the CLI, + // then ensure we can't use a ThinLTO. + match self.opts.cg.lto { + config::Lto::No => {} + config::Lto::Yes if self.opts.cli_forced_thinlto_off => { + return config::Lto::Fat + } + other => return other, + } + + // Ok at this point the target doesn't require anything and the user + // hasn't asked for anything. Our next decision is whether or not + // we enable "auto" ThinLTO where we use multiple codegen units and + // then do ThinLTO over those codegen units. The logic below will + // either return `No` or `ThinLocal`. + + // If processing command line options determined that we're incompatible + // with ThinLTO (e.g. `-C lto --emit llvm-ir`) then return that option. + if self.opts.cli_forced_thinlto_off { + return config::Lto::No + } + + // If `-Z thinlto` specified process that, but note that this is mostly + // a deprecated option now that `-C lto=thin` exists. + if let Some(enabled) = self.opts.debugging_opts.thinlto { + if enabled { + return config::Lto::ThinLocal + } else { + return config::Lto::No + } + } + + // If there's only one codegen unit and LTO isn't enabled then there's + // no need for ThinLTO so just return false. + if self.codegen_units() == 1 { + return config::Lto::No + } + + // Right now ThinLTO isn't compatible with incremental compilation. + if self.opts.incremental.is_some() { + return config::Lto::No + } + + // Now we're in "defaults" territory. By default we enable ThinLTO for + // optimized compiles (anything greater than O0). + match self.opts.optimize { + config::OptLevel::No => config::Lto::No, + _ => config::Lto::ThinLocal, + } } + /// Returns the panic strategy for this compile session. If the user explicitly selected one /// using '-C panic', use that, otherwise use the panic strategy defined by the target. pub fn panic_strategy(&self) -> PanicStrategy { @@ -804,38 +860,6 @@ pub fn codegen_units(&self) -> usize { // scientific. 16 } - - /// Returns whether ThinLTO is enabled for this compilation - pub fn thinlto(&self) -> bool { - // If processing command line options determined that we're incompatible - // with ThinLTO (e.g. `-C lto --emit llvm-ir`) then return that option. - if let Some(enabled) = self.opts.cli_forced_thinlto { - return enabled - } - - // If explicitly specified, use that with the next highest priority - if let Some(enabled) = self.opts.debugging_opts.thinlto { - return enabled - } - - // If there's only one codegen unit and LTO isn't enabled then there's - // no need for ThinLTO so just return false. - if self.codegen_units() == 1 && !self.lto() { - return false - } - - // Right now ThinLTO isn't compatible with incremental compilation. - if self.opts.incremental.is_some() { - return false - } - - // Now we're in "defaults" territory. By default we enable ThinLTO for - // optimized compiles (anything greater than O0). - match self.opts.optimize { - config::OptLevel::No => false, - _ => true, - } - } } pub fn build_session(sopts: config::Options, diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 923e5549927..f050edcd513 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -16,7 +16,7 @@ use super::rpath; use metadata::METADATA_FILENAME; use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType, PrintRequest}; -use rustc::session::config::RUST_CGU_EXT; +use rustc::session::config::{RUST_CGU_EXT, Lto}; use rustc::session::filesearch; use rustc::session::search_paths::PathKind; use rustc::session::Session; @@ -503,7 +503,8 @@ fn link_staticlib(sess: &Session, }); ab.add_rlib(path, &name.as_str(), - sess.lto() && !ignored_for_lto(sess, &trans.crate_info, cnum), + is_full_lto_enabled(sess) && + !ignored_for_lto(sess, &trans.crate_info, cnum), skip_object_files).unwrap(); all_native_libs.extend(trans.crate_info.native_libraries[&cnum].iter().cloned()); @@ -1211,7 +1212,8 @@ fn add_static_crate(cmd: &mut Linker, lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib) }); - if (!sess.lto() || ignored_for_lto(sess, &trans.crate_info, cnum)) && + if (!is_full_lto_enabled(sess) || + ignored_for_lto(sess, &trans.crate_info, cnum)) && crate_type != config::CrateTypeDylib && !skip_native { cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath)); @@ -1264,7 +1266,7 @@ fn looks_like_rust(s: &str) -> bool { // file, then we don't need the object file as it's part of the // LTO module. Note that `#![no_builtins]` is excluded from LTO, // though, so we let that object file slide. - let skip_because_lto = sess.lto() && + let skip_because_lto = is_full_lto_enabled(sess) && is_rust_object && (sess.target.target.options.no_builtins || !trans.crate_info.is_no_builtins.contains(&cnum)); @@ -1301,7 +1303,7 @@ fn looks_like_rust(s: &str) -> bool { fn add_dynamic_crate(cmd: &mut Linker, sess: &Session, cratepath: &Path) { // If we're performing LTO, then it should have been previously required // that all upstream rust dependencies were available in an rlib format. - assert!(!sess.lto()); + assert!(!is_full_lto_enabled(sess)); // Just need to tell the linker about where the library lives and // what its name is @@ -1409,3 +1411,13 @@ fn link_binaryen(sess: &Session, e)); } } + +fn is_full_lto_enabled(sess: &Session) -> bool { + match sess.lto() { + Lto::Yes | + Lto::Thin | + Lto::Fat => true, + Lto::No | + Lto::ThinLocal => false, + } +} diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index b612247ffcd..9ff5bcf7a33 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -18,7 +18,7 @@ use llvm; use rustc::hir::def_id::LOCAL_CRATE; use rustc::middle::exported_symbols::SymbolExportLevel; -use rustc::session::config; +use rustc::session::config::{self, Lto}; use rustc::util::common::time; use time_graph::Timeline; use {ModuleTranslation, ModuleLlvm, ModuleKind, ModuleSource}; @@ -95,25 +95,22 @@ pub fn cost(&self) -> u64 { } } -pub enum LTOMode { - WholeCrateGraph, - JustThisCrate, -} - pub(crate) fn run(cgcx: &CodegenContext, - modules: Vec, - mode: LTOMode, - timeline: &mut Timeline) + modules: Vec, + timeline: &mut Timeline) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); - let export_threshold = match mode { - LTOMode::WholeCrateGraph => { + let export_threshold = match cgcx.lto { + // We're just doing LTO for our one crate + Lto::ThinLocal => SymbolExportLevel::Rust, + + // We're doing LTO for the entire crate graph + Lto::Yes | Lto::Fat | Lto::Thin => { symbol_export::crates_export_threshold(&cgcx.crate_types) } - LTOMode::JustThisCrate => { - SymbolExportLevel::Rust - } + + Lto::No => panic!("didn't request LTO but we're doing LTO"), }; let symbol_filter = &|&(ref name, _, level): &(String, _, SymbolExportLevel)| { @@ -140,7 +137,7 @@ pub(crate) fn run(cgcx: &CodegenContext, // We save off all the bytecode and LLVM module ids for later processing // with either fat or thin LTO let mut upstream_modules = Vec::new(); - if let LTOMode::WholeCrateGraph = mode { + if cgcx.lto != Lto::ThinLocal { if cgcx.opts.cg.prefer_dynamic { diag_handler.struct_err("cannot prefer dynamic linking when performing LTO") .note("only 'staticlib', 'bin', and 'cdylib' outputs are \ @@ -186,13 +183,16 @@ pub(crate) fn run(cgcx: &CodegenContext, } let arr = symbol_white_list.iter().map(|c| c.as_ptr()).collect::>(); - match mode { - LTOMode::WholeCrateGraph if !cgcx.thinlto => { + match cgcx.lto { + Lto::Yes | // `-C lto` == fat LTO by default + Lto::Fat => { fat_lto(cgcx, &diag_handler, modules, upstream_modules, &arr, timeline) } - _ => { + Lto::Thin | + Lto::ThinLocal => { thin_lto(&diag_handler, modules, upstream_modules, &arr, timeline) } + Lto::No => unreachable!(), } } diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index a013af7a460..a4af080ebf7 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -19,7 +19,7 @@ use rustc::dep_graph::{DepGraph, WorkProductFileKind}; use rustc::middle::cstore::{LinkMeta, EncodedMetadata}; use rustc::session::config::{self, OutputFilenames, OutputType, OutputTypes, Passes, SomePasses, - AllPasses, Sanitizer}; + AllPasses, Sanitizer, Lto}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; use rustc_back::LinkerFlavor; @@ -318,8 +318,7 @@ fn set_flags(&mut self, sess: &Session, no_builtins: bool) { pub struct CodegenContext { // Resouces needed when running LTO pub time_passes: bool, - pub lto: bool, - pub thinlto: bool, + pub lto: Lto, pub no_landing_pads: bool, pub save_temps: bool, pub fewer_names: bool, @@ -576,12 +575,7 @@ fn generate_lto_work(cgcx: &CodegenContext, TRANS_WORK_PACKAGE_KIND, "generate lto") }).unwrap_or(Timeline::noop()); - let mode = if cgcx.lto { - lto::LTOMode::WholeCrateGraph - } else { - lto::LTOMode::JustThisCrate - }; - let lto_modules = lto::run(cgcx, modules, mode, &mut timeline) + let lto_modules = lto::run(cgcx, modules, &mut timeline) .unwrap_or_else(|e| panic!(e)); lto_modules.into_iter().map(|module| { @@ -1280,28 +1274,51 @@ fn execute_work_item(cgcx: &CodegenContext, unsafe { optimize(cgcx, &diag_handler, &mtrans, config, timeline)?; - let lto = cgcx.lto; + // After we've done the initial round of optimizations we need to + // decide whether to synchronously codegen this module or ship it + // back to the coordinator thread for further LTO processing (which + // has to wait for all the initial modules to be optimized). + // + // Here we dispatch based on the `cgcx.lto` and kind of module we're + // translating... + let needs_lto = match cgcx.lto { + Lto::No => false, + + // Here we've got a full crate graph LTO requested. We ignore + // this, however, if the crate type is only an rlib as there's + // no full crate graph to process, that'll happen later. + // + // This use case currently comes up primarily for targets that + // require LTO so the request for LTO is always unconditionally + // passed down to the backend, but we don't actually want to do + // anything about it yet until we've got a final product. + Lto::Yes | Lto::Fat | Lto::Thin => { + cgcx.crate_types.len() != 1 || + cgcx.crate_types[0] != config::CrateTypeRlib + } - let auto_thin_lto = - cgcx.thinlto && - cgcx.total_cgus > 1 && - mtrans.kind != ModuleKind::Allocator; + // When we're automatically doing ThinLTO for multi-codegen-unit + // builds we don't actually want to LTO the allocator modules if + // it shows up. This is due to various linker shenanigans that + // we'll encounter later. + // + // Additionally here's where we also factor in the current LLVM + // version. If it doesn't support ThinLTO we skip this. + Lto::ThinLocal => { + mtrans.kind != ModuleKind::Allocator && + llvm::LLVMRustThinLTOAvailable() + } + }; - // If we're a metadata module we never participate in LTO. - // - // If LTO was explicitly requested on the command line, we always - // LTO everything else. - // - // If LTO *wasn't* explicitly requested and we're not a metdata - // module, then we may automatically do ThinLTO if we've got - // multiple codegen units. Note, however, that the allocator module - // doesn't participate here automatically because of linker - // shenanigans later on. - if mtrans.kind == ModuleKind::Metadata || (!lto && !auto_thin_lto) { + // Metadata modules never participate in LTO regardless of the lto + // settings. + let needs_lto = needs_lto && mtrans.kind != ModuleKind::Metadata; + + if needs_lto { + Ok(WorkItemResult::NeedsLTO(mtrans)) + } else { let module = codegen(cgcx, &diag_handler, mtrans, config, timeline)?; Ok(WorkItemResult::Compiled(module)) - } else { - Ok(WorkItemResult::NeedsLTO(mtrans)) } } } @@ -1377,28 +1394,13 @@ fn start_executing_work(tcx: TyCtxt, each_linked_rlib_for_lto.push((cnum, path.to_path_buf())); })); - let crate_types = sess.crate_types.borrow(); - let only_rlib = crate_types.len() == 1 && - crate_types[0] == config::CrateTypeRlib; - let wasm_import_memory = attr::contains_name(&tcx.hir.krate().attrs, "wasm_import_memory"); let cgcx = CodegenContext { crate_types: sess.crate_types.borrow().clone(), each_linked_rlib_for_lto, - // If we're only building an rlibc then allow the LTO flag to be passed - // but don't actually do anything, the full LTO will happen later - lto: sess.lto() && !only_rlib, - - // Enable ThinLTO if requested, but only if the target we're compiling - // for doesn't require full LTO. Some targets require one LLVM module - // (they effectively don't have a linker) so it's up to us to use LTO to - // link everything together. - thinlto: sess.thinlto() && - !sess.target.target.options.requires_lto && - unsafe { llvm::LLVMRustThinLTOAvailable() }, - + lto: sess.lto(), no_landing_pads: sess.no_landing_pads(), fewer_names: sess.fewer_names(), save_temps: sess.opts.cg.save_temps, diff --git a/src/test/run-make/codegen-options-parsing/Makefile b/src/test/run-make/codegen-options-parsing/Makefile index 81e06043c87..fda96a8b1fb 100644 --- a/src/test/run-make/codegen-options-parsing/Makefile +++ b/src/test/run-make/codegen-options-parsing/Makefile @@ -16,11 +16,11 @@ all: $(RUSTC) -C extra-filename=foo dummy.rs 2>&1 #Option taking no argument $(RUSTC) -C lto= dummy.rs 2>&1 | \ - $(CGREP) 'codegen option `lto` takes no value' + $(CGREP) 'codegen option `lto` - one of `thin`, `fat`, or' $(RUSTC) -C lto=1 dummy.rs 2>&1 | \ - $(CGREP) 'codegen option `lto` takes no value' + $(CGREP) 'codegen option `lto` - one of `thin`, `fat`, or' $(RUSTC) -C lto=foo dummy.rs 2>&1 | \ - $(CGREP) 'codegen option `lto` takes no value' + $(CGREP) 'codegen option `lto` - one of `thin`, `fat`, or' $(RUSTC) -C lto dummy.rs # Should not link dead code... diff --git a/src/test/run-pass/fat-lto.rs b/src/test/run-pass/fat-lto.rs new file mode 100644 index 00000000000..453eede261c --- /dev/null +++ b/src/test/run-pass/fat-lto.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Clto=fat +// no-prefer-dynamic + +fn main() { + println!("hello!"); +} + diff --git a/src/test/run-pass/thinlto/all-crates.rs b/src/test/run-pass/thinlto/all-crates.rs new file mode 100644 index 00000000000..772a9ec8293 --- /dev/null +++ b/src/test/run-pass/thinlto/all-crates.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Clto=thin +// no-prefer-dynamic +// min-llvm-version 4.0 + +fn main() { + println!("hello!"); +} diff --git a/src/test/run-pass/thinlto/thin-lto-inlines2.rs b/src/test/run-pass/thinlto/thin-lto-inlines2.rs index 0e8ad08a5f6..6020f72415d 100644 --- a/src/test/run-pass/thinlto/thin-lto-inlines2.rs +++ b/src/test/run-pass/thinlto/thin-lto-inlines2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z thinlto -C codegen-units=8 -O -C lto +// compile-flags: -C codegen-units=8 -O -C lto=thin // aux-build:thin-lto-inlines-aux.rs // min-llvm-version 4.0 // no-prefer-dynamic -- 2.44.0