https://github.com/RiverDave created 
https://github.com/llvm/llvm-project/pull/196245

I found certain unresolved external symbols when compiling polybench (for CUDA) 
specifically for libdevice - Therefore, this patch upstreams 
https://github.com/llvm/clangir/pull/2010/changes.

>From e47a97d0cfdf88b925c7f012b063640a3ff135aa Mon Sep 17 00:00:00 2001
From: David Rivera <[email protected]>
Date: Thu, 7 May 2026 06:18:01 +0000
Subject: [PATCH] [CIR] Add Support for linking modules on cc1

---
 clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 79 +++++++++++++++++++
 clang/test/CIR/CodeGen/link-bitcode-file.c    | 44 +++++++++++
 2 files changed, 123 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/link-bitcode-file.c

diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp 
b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index af38872c5ca98..424fbd4f1186a 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -16,9 +16,15 @@
 #include "clang/CodeGen/BackendUtil.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/Module.h"
+#include "llvm/Linker/Linker.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/IPO/Internalize.h"
 
 using namespace cir;
 using namespace clang;
@@ -70,6 +76,15 @@ class CIRGenConsumer : public clang::ASTConsumer {
   const FrontendOptions &FEOptions;
   CodeGenOptions &CGO;
 
+  struct LinkModule {
+    std::unique_ptr<llvm::Module> Module;
+    bool PropagateAttrs;
+    bool Internalize;
+    unsigned LinkFlags;
+  };
+
+  SmallVector<LinkModule, 4> LinkModules;
+
 public:
   CIRGenConsumer(CIRGenAction::OutputType Action, CompilerInstance &CI,
                  CodeGenOptions &CGO, std::unique_ptr<raw_pwrite_stream> OS)
@@ -160,10 +175,16 @@ class CIRGenConsumer : public clang::ASTConsumer {
       }
 
       llvm::LLVMContext LLVMCtx;
+      if (loadLinkModules(LLVMCtx))
+        return;
+
       std::unique_ptr<llvm::Module> LLVMModule =
           lowerFromCIRToLLVMIR(MlirModule, LLVMCtx, mlirSaveTempsOutFile,
                                &CI.getVirtualFileSystem());
 
+      if (linkInModules(*LLVMModule))
+        return;
+
       BackendAction BEAction = getBackendActionFromOutputType(Action);
       emitBackendOutput(
           CI, CI.getCodeGenOpts(), C.getTargetInfo().getDataLayoutString(),
@@ -173,6 +194,64 @@ class CIRGenConsumer : public clang::ASTConsumer {
     }
   }
 
+  bool loadLinkModules(llvm::LLVMContext &LLVMCtx) {
+    if (!LinkModules.empty())
+      return false;
+
+    for (const CodeGenOptions::BitcodeFileToLink &F :
+         CI.getCodeGenOpts().LinkBitcodeFiles) {
+      auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename);
+      if (!BCBuf) {
+        CI.getDiagnostics().Report(diag::err_cannot_open_file)
+            << F.Filename << BCBuf.getError().message();
+        LinkModules.clear();
+        return true;
+      }
+
+      llvm::Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
+          llvm::getOwningLazyBitcodeModule(std::move(*BCBuf), LLVMCtx);
+      if (!ModuleOrErr) {
+        llvm::handleAllErrors(
+            ModuleOrErr.takeError(), [&](llvm::ErrorInfoBase &EIB) {
+              CI.getDiagnostics().Report(diag::err_cannot_open_file)
+                  << F.Filename << EIB.message();
+            });
+        LinkModules.clear();
+        return true;
+      }
+
+      LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs,
+                             F.Internalize, F.LinkFlags});
+    }
+
+    return false;
+  }
+
+  bool linkInModules(llvm::Module &M) {
+    for (auto &LM : LinkModules) {
+      assert(LM.Module && "LinkModule does not actually have a module");
+
+      bool Err;
+      if (LM.Internalize) {
+        Err = llvm::Linker::linkModules(
+            M, std::move(LM.Module), LM.LinkFlags,
+            [](llvm::Module &M, const llvm::StringSet<> &GVS) {
+              llvm::internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
+                return !GV.hasName() || (GVS.count(GV.getName()) == 0);
+              });
+            });
+      } else {
+        Err = llvm::Linker::linkModules(M, std::move(LM.Module), LM.LinkFlags);
+      }
+
+      if (Err)
+        return true;
+    }
+
+    LinkModules.clear();
+    return false;
+  }
+
   void HandleTagDeclDefinition(TagDecl *D) override {
     PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
                                    Context->getSourceManager(),
diff --git a/clang/test/CIR/CodeGen/link-bitcode-file.c 
b/clang/test/CIR/CodeGen/link-bitcode-file.c
new file mode 100644
index 0000000000000..ca6c070699f81
--- /dev/null
+++ b/clang/test/CIR/CodeGen/link-bitcode-file.c
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -O1 -triple x86_64-unknown-linux-gnu -fclangir -DBITCODE 
-emit-llvm-bc -o %t.bc %s
+// RUN: %clang_cc1 -O1 -triple x86_64-unknown-linux-gnu -fclangir -DBITCODE2 
-emit-llvm-bc -o %t-2.bc %s
+// RUN: %clang_cc1 -O1 -triple x86_64-unknown-linux-gnu -fclangir 
-mlink-bitcode-file %t.bc \
+// RUN:     -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-BC %s
+// RUN: %clang_cc1 -O1 -triple x86_64-unknown-linux-gnu -fclangir 
-mlink-builtin-bitcode %t.bc \
+// RUN:     -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-BUILTIN-BC %s
+// RUN: %clang_cc1 -O1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm 
-o - \
+// RUN:     -mlink-bitcode-file %t.bc -mlink-bitcode-file %t-2.bc %s \
+// RUN:     | FileCheck -check-prefix=CHECK-BC -check-prefix=CHECK-BC2 %s
+// RUN: not %clang_cc1 -O1 -triple x86_64-unknown-linux-gnu -fclangir \
+// RUN:     -mlink-bitcode-file no-such-file.bc -emit-llvm -o - %s 2>&1 \
+// RUN:     | FileCheck -check-prefix=CHECK-NO-FILE %s
+
+int f(void);
+
+#ifdef BITCODE
+
+extern int f2(void);
+
+int f(void) {
+  f2();
+  return 42;
+}
+
+#elif defined(BITCODE2)
+
+int f2(void) { return 43; }
+
+#else
+
+// CHECK-BC-LABEL: define{{.*}} i32 @g
+// CHECK-BC: ret i32 42
+// CHECK-BUILTIN-BC-LABEL: define{{.*}} i32 @g
+// CHECK-BUILTIN-BC: ret i32 42
+int g(void) {
+  return f();
+}
+
+// CHECK-BC-LABEL: define{{.*}} i32 @f
+// CHECK-BC2-LABEL: define{{.*}} i32 @f2
+
+#endif
+
+// CHECK-NO-FILE: fatal error: cannot open file 'no-such-file.bc'

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to