From 78a16443a3f9b617b83c1dda15b94b3636c2895d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 30 May 2018 22:48:20 +0200 Subject: [PATCH 1/3] Respect -Z no-verify during LTO Currently -Z no-verify only controls IR verification prior to LLVM codegen, while verification is performed unconditionally both before and after linking with (Thin)LTO. --- src/librustc_codegen_llvm/back/lto.rs | 17 +++++++++++------ src/librustc_codegen_llvm/back/write.rs | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 96eda50d788..415dd605220 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -461,9 +461,12 @@ fn run_pass_manager(cgcx: &CodegenContext, unsafe { let pm = llvm::LLVMCreatePassManager(); llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod); - let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _); - assert!(!pass.is_null()); - llvm::LLVMRustAddPass(pm, pass); + + if !config.no_verify { + let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _); + assert!(!pass.is_null()); + llvm::LLVMRustAddPass(pm, pass); + } // When optimizing for LTO we don't actually pass in `-O0`, but we force // it to always happen at least with `-O1`. @@ -494,9 +497,11 @@ fn run_pass_manager(cgcx: &CodegenContext, } }); - let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _); - assert!(!pass.is_null()); - llvm::LLVMRustAddPass(pm, pass); + if !config.no_verify { + let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _); + assert!(!pass.is_null()); + llvm::LLVMRustAddPass(pm, pass); + } time_ext(cgcx.time_passes, None, "LTO passes", || llvm::LLVMRunPassManager(pm, llmod)); diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index baab3c618be..b34dae98d7a 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -232,7 +232,7 @@ pub struct ModuleConfig { emit_obj: bool, // Miscellaneous flags. These are mostly copied from command-line // options. - no_verify: bool, + pub no_verify: bool, no_prepopulate_passes: bool, no_builtins: bool, time_passes: bool, From 22cf833dd1f1afc30192bb9d4e030bacb4de6fc7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 12 Jun 2018 21:05:37 +0200 Subject: [PATCH 2/3] Rename -Z no-verify to -Z verify-llvm-ir This disables IR verification by default. --- src/librustc/session/config.rs | 6 +++--- src/librustc/session/mod.rs | 4 ++-- src/librustc_codegen_llvm/back/lto.rs | 4 ++-- src/librustc_codegen_llvm/back/write.rs | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index f831b006642..482ae02503b 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1152,8 +1152,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "gather codegen statistics"), asm_comments: bool = (false, parse_bool, [TRACKED], "generate comments into the assembly (may change behavior)"), - no_verify: bool = (false, parse_bool, [TRACKED], - "skip LLVM verification"), + verify_llvm_ir: bool = (false, parse_bool, [TRACKED], + "verify LLVM IR"), borrowck_stats: bool = (false, parse_bool, [UNTRACKED], "gather borrowck statistics"), no_landing_pads: bool = (false, parse_bool, [TRACKED], @@ -3097,7 +3097,7 @@ mod tests { assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); - opts.debugging_opts.no_verify = true; + opts.debugging_opts.verify_llvm_ir = true; 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 076d56fb808..64075926b65 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -513,8 +513,8 @@ impl Session { pub fn asm_comments(&self) -> bool { self.opts.debugging_opts.asm_comments } - pub fn no_verify(&self) -> bool { - self.opts.debugging_opts.no_verify + pub fn verify_llvm_ir(&self) -> bool { + self.opts.debugging_opts.verify_llvm_ir } pub fn borrowck_stats(&self) -> bool { self.opts.debugging_opts.borrowck_stats diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 415dd605220..a33f8b569d0 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -462,7 +462,7 @@ fn run_pass_manager(cgcx: &CodegenContext, let pm = llvm::LLVMCreatePassManager(); llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod); - if !config.no_verify { + if config.verify_llvm_ir { let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _); assert!(!pass.is_null()); llvm::LLVMRustAddPass(pm, pass); @@ -497,7 +497,7 @@ fn run_pass_manager(cgcx: &CodegenContext, } }); - if !config.no_verify { + if config.verify_llvm_ir { let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _); assert!(!pass.is_null()); llvm::LLVMRustAddPass(pm, pass); diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index b34dae98d7a..f6e2d68d7fa 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -232,7 +232,7 @@ pub struct ModuleConfig { emit_obj: bool, // Miscellaneous flags. These are mostly copied from command-line // options. - pub no_verify: bool, + pub verify_llvm_ir: bool, no_prepopulate_passes: bool, no_builtins: bool, time_passes: bool, @@ -271,7 +271,7 @@ impl ModuleConfig { embed_bitcode_marker: false, no_integrated_as: false, - no_verify: false, + verify_llvm_ir: false, no_prepopulate_passes: false, no_builtins: false, time_passes: false, @@ -283,7 +283,7 @@ impl ModuleConfig { } fn set_flags(&mut self, sess: &Session, no_builtins: bool) { - self.no_verify = sess.no_verify(); + self.verify_llvm_ir = sess.verify_llvm_ir(); self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes; self.no_builtins = no_builtins || sess.target.target.options.no_builtins; self.time_passes = sess.time_passes(); @@ -542,7 +542,7 @@ unsafe fn optimize(cgcx: &CodegenContext, true }; - if !config.no_verify { assert!(addpass("verify")); } + if config.verify_llvm_ir { assert!(addpass("verify")); } if !config.no_prepopulate_passes { llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod); llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod); From 3f18a41333aabf515d6d343c07f3bbbd154f6018 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 12 Jun 2018 21:21:29 +0200 Subject: [PATCH 3/3] Add verify-llvm-ir flag to config.toml --- config.toml.example | 3 +++ src/bootstrap/bin/rustc.rs | 4 ++++ src/bootstrap/builder.rs | 4 ++++ src/bootstrap/config.rs | 3 +++ 4 files changed, 14 insertions(+) diff --git a/config.toml.example b/config.toml.example index 5054a8f44b9..8cc9c028391 100644 --- a/config.toml.example +++ b/config.toml.example @@ -356,6 +356,9 @@ # Print backtrace on internal compiler errors during bootstrap #backtrace-on-ice = false +# Whether to verify generated LLVM IR +#verify-llvm-ir = false + # ============================================================================= # Options for specific targets # diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 4607ca5cf9f..e81595a8c62 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -283,6 +283,10 @@ fn main() { cmd.arg("--cfg").arg("parallel_queries"); } + if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() { + cmd.arg("-Z").arg("verify-llvm-ir"); + } + let color = match env::var("RUSTC_COLOR") { Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"), Err(_) => 0, diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d482a0d5650..76387796d70 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -898,6 +898,10 @@ impl<'a> Builder<'a> { cargo.env("RUSTC_BACKTRACE_ON_ICE", "1"); } + if self.config.rust_verify_llvm_ir { + cargo.env("RUSTC_VERIFY_LLVM_IR", "1"); + } + cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity)); // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful. diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 47feb8a8ab6..a0f6b786cbd 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -105,6 +105,7 @@ pub struct Config { pub rust_dist_src: bool, pub rust_codegen_backends: Vec>, pub rust_codegen_backends_dir: String, + pub rust_verify_llvm_ir: bool, pub build: Interned, pub hosts: Vec>, @@ -311,6 +312,7 @@ struct Rust { lld: Option, deny_warnings: Option, backtrace_on_ice: Option, + verify_llvm_ir: Option, } /// TOML representation of how each build target is configured. @@ -542,6 +544,7 @@ impl Config { config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from); set(&mut config.deny_warnings, rust.deny_warnings.or(flags.warnings)); set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); + set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); if let Some(ref backends) = rust.codegen_backends { config.rust_codegen_backends = backends.iter()