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) {

Reply via email to