Skip to content

Conversation

@YixingZhang007
Copy link
Contributor

@YixingZhang007 YixingZhang007 commented Oct 23, 2025

This PR is still working in progress. Thank you for your understanding!

@YixingZhang007 YixingZhang007 marked this pull request as draft October 23, 2025 14:44
@llvmbot
Copy link
Member

llvmbot commented Oct 23, 2025

@llvm/pr-subscribers-backend-spir-v

Author: None (YixingZhang007)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/164829.diff

1 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (+30)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 9f2e07508a36a..64e076338816f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -3013,6 +3013,36 @@ bool SPIRVEmitIntrinsics::runOnModule(Module &M) {
   parseFunDeclarations(M);
   insertConstantsForFPFastMathDefault(M);
 
+  // If there are no functions but there is at least one global variable,
+  // create a shadow function to "anchor" global handling in codegen.
+  bool HasAnyFunction = false;
+  for (auto &F : M)
+    if (!F.isDeclaration() && !F.isIntrinsic())
+      HasAnyFunction = true;
+
+  Function *ShadowFunc = nullptr;
+  if (!HasAnyFunction) {
+      for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ) {
+          GlobalVariable *GV = &*GI++;
+          if (GV->hasInternalLinkage()) {
+              GV->eraseFromParent();
+              Changed = true;
+          } else if (ShadowFunc == nullptr) {
+              LLVMContext &Ctx = M.getContext();
+              auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
+              ShadowFunc = Function::Create(
+                  FTy, GlobalValue::InternalLinkage, "__spirv_globals_entry", &M);
+
+              // Create a basic block and insert a ret void
+              BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
+              IRBuilder<> B(BB);
+              B.CreateRetVoid();
+
+              Changed = true;
+          }
+      }
+  }
+
   TodoType.clear();
   for (auto &F : M)
     Changed |= runOnFunction(F);

@github-actions
Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff origin/main HEAD --extensions cpp -- llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp --diff_from_common_commit

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from clang-format here.
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index f39670f5a..2182d4ad0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -3025,25 +3025,25 @@ bool SPIRVEmitIntrinsics::runOnModule(Module &M) {
 
   Function *ShadowFunc = nullptr;
   if (!HasAnyFunction) {
-      for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ) {
-          GlobalVariable *GV = &*GI++;
-          if (GV->hasInternalLinkage()) {
-              GV->eraseFromParent();
-              Changed = true;
-          } else if (ShadowFunc == nullptr) {
-              LLVMContext &Ctx = M.getContext();
-              auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
-              ShadowFunc = Function::Create(
-                  FTy, GlobalValue::InternalLinkage, "__spirv_globals_entry", &M);
-
-              // Create a basic block and insert a ret void
-              BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
-              IRBuilder<> B(BB);
-              B.CreateRetVoid();
-
-              Changed = true;
-          }
+    for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE;) {
+      GlobalVariable *GV = &*GI++;
+      if (GV->hasInternalLinkage()) {
+        GV->eraseFromParent();
+        Changed = true;
+      } else if (ShadowFunc == nullptr) {
+        LLVMContext &Ctx = M.getContext();
+        auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
+        ShadowFunc = Function::Create(FTy, GlobalValue::InternalLinkage,
+                                      "__spirv_globals_entry", &M);
+
+        // Create a basic block and insert a ret void
+        BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
+        IRBuilder<> B(BB);
+        B.CreateRetVoid();
+
+        Changed = true;
       }
+    }
   }
 
   TodoType.clear();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants