This is an automated email from the ASF dual-hosted git repository. kparzysz pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push: new b1ab4dc1d5 [LLVM] Validate generated LLVM module before optimization (#14564) b1ab4dc1d5 is described below commit b1ab4dc1d5e45cd18cb6a81062e22361746084c9 Author: Eric Lunderberg <lunderb...@users.noreply.github.com> AuthorDate: Wed Apr 12 13:37:25 2023 -0500 [LLVM] Validate generated LLVM module before optimization (#14564) * [LLVM] Validate generated LLVM module before optimization Because LLVM's optimizations assume that the generated module is valid, validation should be done before optimization, rather than after. This has the additional benefit of providing error messages from LLVM that more closely relate to the TVM-generated LLVM IR, rather than the optimized LLVM IR. * Resolve linkage/attribute errors found by llvm::Verify * Prioritize AlwaysInline over OptimizeNone --- src/target/llvm/codegen_llvm.cc | 13 ++++++++++++- src/target/llvm/codegen_llvm.h | 6 ++++++ src/target/llvm/codegen_nvptx.cc | 2 +- src/target/llvm/llvm_module.cc | 18 ------------------ 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/target/llvm/codegen_llvm.cc b/src/target/llvm/codegen_llvm.cc index 3fbc93f678..2a8c3226f3 100644 --- a/src/target/llvm/codegen_llvm.cc +++ b/src/target/llvm/codegen_llvm.cc @@ -66,6 +66,7 @@ #include <llvm/IR/Metadata.h> #include <llvm/IR/Module.h> #include <llvm/IR/Type.h> +#include <llvm/IR/Verifier.h> #include <llvm/IRReader/IRReader.h> #include <llvm/Linker/Linker.h> #include <llvm/Pass.h> @@ -310,6 +311,14 @@ void CodeGenLLVM::AddFunctionInternal(const PrimFunc& f, bool ret_void) { } } +void CodeGenLLVM::Verify() const { + std::string verify_errors_storage; + llvm::raw_string_ostream verify_errors(verify_errors_storage); + LOG_IF(FATAL, llvm::verifyModule(*module_, &verify_errors)) + << "LLVM module verification failed with the following errors: \n" + << verify_errors.str(); +} + std::unique_ptr<llvm::Module> CodeGenLLVM::Finish() { this->AddStartupFunction(); for (size_t i = 0; i < link_modules_.size(); ++i) { @@ -317,8 +326,9 @@ std::unique_ptr<llvm::Module> CodeGenLLVM::Finish() { << "Failed to link modules"; } link_modules_.clear(); - // optimize + this->Verify(); this->Optimize(); + this->Verify(); return std::move(module_); } @@ -335,6 +345,7 @@ void CodeGenLLVM::HandleImport(const std::string& code) { mlib->setDataLayout(llvm_target_->GetOrCreateTargetMachine()->createDataLayout()); // mark all the functions as force inline for (llvm::Function& f : mlib->functions()) { + f.removeFnAttr(llvm::Attribute::OptimizeNone); f.removeFnAttr(llvm::Attribute::NoInline); f.addFnAttr(llvm::Attribute::AlwaysInline); f.setLinkage(llvm::GlobalValue::AvailableExternallyLinkage); diff --git a/src/target/llvm/codegen_llvm.h b/src/target/llvm/codegen_llvm.h index b46ae07b84..0d5650c473 100644 --- a/src/target/llvm/codegen_llvm.h +++ b/src/target/llvm/codegen_llvm.h @@ -146,6 +146,12 @@ class CodeGenLLVM : public ExprFunctor<llvm::Value*(const PrimExpr&)>, * \return the created module. */ virtual std::unique_ptr<llvm::Module> Finish(); + + /*! + * \brief Validate the generated module using llvm::verifyModule + */ + void Verify() const; + /*! * \brief Add functions from the (unordered) range to the current module in a deterministic order. * The range consists of objects convertible to PrimFunc. diff --git a/src/target/llvm/codegen_nvptx.cc b/src/target/llvm/codegen_nvptx.cc index e64a2dc5b9..46816eb20c 100644 --- a/src/target/llvm/codegen_nvptx.cc +++ b/src/target/llvm/codegen_nvptx.cc @@ -121,7 +121,7 @@ class CodeGenNVPTX : public CodeGenLLVM { ICHECK(storage_scope.rank == runtime::StorageRank::kShared) << "Can only allocate shared or local memory inside kernel"; buf = AllocateSharedMemory(op->dtype, constant_size, 3, info.alignment, - llvm::GlobalValue::PrivateLinkage); + llvm::GlobalValue::ExternalLinkage); } } diff --git a/src/target/llvm/llvm_module.cc b/src/target/llvm/llvm_module.cc index 4ae0b786b6..2173cad4a7 100644 --- a/src/target/llvm/llvm_module.cc +++ b/src/target/llvm/llvm_module.cc @@ -39,7 +39,6 @@ #include <llvm/IR/MDBuilder.h> #include <llvm/IR/Metadata.h> #include <llvm/IR/Module.h> -#include <llvm/IR/Verifier.h> #include <llvm/IRReader/IRReader.h> #include <llvm/Support/FileSystem.h> #include <llvm/Support/SourceMgr.h> @@ -330,11 +329,6 @@ void LLVMModuleNode::Init(const IRModule& mod, const Target& target) { if (tm->getTargetTriple().isOSDarwin()) { module_->addModuleFlag(llvm::Module::Override, "Dwarf Version", 2); } - std::string verify_errors_storage; - llvm::raw_string_ostream verify_errors(verify_errors_storage); - LOG_IF(FATAL, llvm::verifyModule(*module_, &verify_errors)) - << "LLVM module verification failed with the following errors: \n" - << verify_errors.str(); } void LLVMModuleNode::Init(std::unique_ptr<llvm::Module> module, @@ -514,12 +508,6 @@ runtime::Module CreateLLVMCppMetadataModule(runtime::metadata::Metadata metadata mod->addModuleFlag(llvm::Module::Override, "Dwarf Version", 2); } - std::string verify_errors_storage; - llvm::raw_string_ostream verify_errors(verify_errors_storage); - LOG_IF(FATAL, llvm::verifyModule(*mod, &verify_errors)) - << "LLVM module verification failed with the following errors: \n" - << verify_errors.str(); - auto n = make_object<LLVMModuleNode>(); n->Init(std::move(mod), std::move(llvm_instance)); @@ -560,12 +548,6 @@ runtime::Module CreateLLVMCrtMetadataModule(const Array<runtime::Module>& module mod->addModuleFlag(llvm::Module::Override, "Dwarf Version", 2); } - std::string verify_errors_storage; - llvm::raw_string_ostream verify_errors(verify_errors_storage); - LOG_IF(FATAL, llvm::verifyModule(*mod, &verify_errors)) - << "LLVM module verification failed with the following errors: \n" - << verify_errors.str(); - auto n = make_object<LLVMModuleNode>(); n->Init(std::move(mod), std::move(llvm_instance)); for (auto m : modules) {