From e1be3ea28def14ea3316d59ebd79587c9459bf56 Mon Sep 17 00:00:00 2001 From: DianQK Date: Sun, 11 Aug 2024 21:19:28 +0800 Subject: [PATCH] Add `-Zlint-llvm-ir` --- compiler/rustc_codegen_llvm/src/back/write.rs | 1 + compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_llvm/src/llvm_util.rs | 4 ++++ compiler/rustc_codegen_ssa/src/back/write.rs | 2 ++ compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 9 ++++++++- compiler/rustc_session/src/options.rs | 2 ++ src/doc/unstable-book/src/compiler-flags/lint-llvm-ir.md | 5 +++++ tests/codegen/cast-target-abi.rs | 2 +- tests/codegen/cffi/ffi-out-of-bounds-loads.rs | 2 +- 10 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/lint-llvm-ir.md diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a1f2433ab6f3b..f747f3139260d 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -573,6 +573,7 @@ pub(crate) unsafe fn llvm_optimize( cgcx.opts.cg.linker_plugin_lto.enabled(), config.no_prepopulate_passes, config.verify_llvm_ir, + config.lint_llvm_ir, using_thin_buffers, config.merge_functions, unroll_loops, diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 80b13c0e1d4b9..579ec517cf0b5 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2217,6 +2217,7 @@ extern "C" { IsLinkerPluginLTO: bool, NoPrepopulatePasses: bool, VerifyIR: bool, + LintIR: bool, UseThinLTOBuffers: bool, MergeFunctions: bool, UnrollLoops: bool, diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 9fd8ca43789dd..f2d06491b7eb9 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -46,6 +46,7 @@ fn require_inited() { unsafe fn configure_llvm(sess: &Session) { let n_args = sess.opts.cg.llvm_args.len() + sess.target.llvm_args.len(); + let llvm_version = get_version(); let mut llvm_c_strs = Vec::with_capacity(n_args + 1); let mut llvm_args = Vec::with_capacity(n_args + 1); @@ -90,6 +91,9 @@ unsafe fn configure_llvm(sess: &Session) { if sess.opts.unstable_opts.print_llvm_passes { add("-debug-pass=Structure", false); } + if llvm_version >= (19, 0, 0) && sess.opts.unstable_opts.lint_llvm_ir { + add("-lint-abort-on-error", false); + } if sess.target.generate_arange_section && !sess.opts.unstable_opts.no_generate_arange_section { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index bea12747a5199..7d352ae9118e8 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -111,6 +111,7 @@ pub struct ModuleConfig { // Miscellaneous flags. These are mostly copied from command-line // options. pub verify_llvm_ir: bool, + pub lint_llvm_ir: bool, pub no_prepopulate_passes: bool, pub no_builtins: bool, pub time_module: bool, @@ -236,6 +237,7 @@ impl ModuleConfig { bc_cmdline: sess.target.bitcode_llvm_cmdline.to_string(), verify_llvm_ir: sess.verify_llvm_ir(), + lint_llvm_ir: sess.opts.unstable_opts.lint_llvm_ir, no_prepopulate_passes: sess.opts.cg.no_prepopulate_passes, no_builtins: no_builtins || sess.target.no_builtins, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 34f2dca7c42ff..db59411637f1a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -793,6 +793,7 @@ fn test_unstable_options_tracking_hash() { tracked!(instrument_xray, Some(InstrumentXRay::default())); tracked!(link_directives, false); tracked!(link_only, true); + tracked!(lint_llvm_ir, true); tracked!(llvm_module_flag, vec![("bar".to_string(), 123, "max".to_string())]); tracked!(llvm_plugins, vec![String::from("plugin_name")]); tracked!(location_detail, LocationDetail { file: true, line: false, column: false }); diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 283c4fbbb7cf4..39d97e175d61a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -713,7 +713,7 @@ extern "C" LLVMRustResult LLVMRustOptimize( LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef, LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage, bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR, - bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops, + bool LintIR, bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage, @@ -842,6 +842,13 @@ extern "C" LLVMRustResult LLVMRustOptimize( }); } + if (LintIR) { + PipelineStartEPCallbacks.push_back( + [](ModulePassManager &MPM, OptimizationLevel Level) { + MPM.addPass(createModuleToFunctionPassAdaptor(LintPass())); + }); + } + if (InstrumentGCOV) { PipelineStartEPCallbacks.push_back( [](ModulePassManager &MPM, OptimizationLevel Level) { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index df72e2430fd50..a41172fc0bd12 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1795,6 +1795,8 @@ options! { "link the `.rlink` file generated by `-Z no-link` (default: no)"), linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED], "a comma-separated list of linker features to enable (+) or disable (-): `lld`"), + lint_llvm_ir: bool = (false, parse_bool, [TRACKED], + "lint LLVM IR (default: no)"), lint_mir: bool = (false, parse_bool, [UNTRACKED], "lint MIR before and after each transformation"), llvm_module_flag: Vec<(String, u32, String)> = (Vec::new(), parse_llvm_module_flag, [TRACKED], diff --git a/src/doc/unstable-book/src/compiler-flags/lint-llvm-ir.md b/src/doc/unstable-book/src/compiler-flags/lint-llvm-ir.md new file mode 100644 index 0000000000000..d31f5d87e79f9 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/lint-llvm-ir.md @@ -0,0 +1,5 @@ +# `lint-llvm-ir` + +--------------------- + +This flag will add `LintPass` to the start of the pipeline and set `-lint-abort-on-error`. diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs index 34e52d38bbea9..57c4c90b85b46 100644 --- a/tests/codegen/cast-target-abi.rs +++ b/tests/codegen/cast-target-abi.rs @@ -1,7 +1,7 @@ // ignore-tidy-linelength //@ revisions:aarch64 loongarch64 powerpc64 sparc64 x86_64 // FIXME: Add `-Cllvm-args=--lint-abort-on-error` after LLVM 19 -//@ compile-flags: -O -C no-prepopulate-passes -C passes=lint +//@ compile-flags: -O -C no-prepopulate-passes -Zlint-llvm-ir //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu //@[aarch64] needs-llvm-components: arm diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs index a4b7c0caa6d46..f365b18850fe1 100644 --- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs +++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs @@ -1,5 +1,5 @@ //@ revisions: linux apple -//@ compile-flags: -C opt-level=0 -C no-prepopulate-passes -C passes=lint +//@ compile-flags: -C opt-level=0 -C no-prepopulate-passes -Zlint-llvm-ir //@[linux] compile-flags: --target x86_64-unknown-linux-gnu //@[linux] needs-llvm-components: x86