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

github-actions bot commented Oct 23, 2025

⚠️ 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/SPIRVAsmPrinter.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/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp index cc6d122c0..ae48f4dd8 100644 --- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp @@ -304,9 +304,10 @@ void SPIRVAsmPrinter::emitInstruction(const MachineInstr *MI) { void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType) { const Function &F = MF->getFunction(); for (const MachineInstr *MI : MAI->getMSInstrs(MSType)) { - if (F.getName() != "__spirv_globals_entry" || ((MI->getOpcode() != SPIRV::OpName)  - && (MI->getOpcode() != SPIRV::OpTypeVoid) - && (MI->getOpcode() != SPIRV::OpTypeFunction))) {  + if (F.getName() != "__spirv_globals_entry" || + ((MI->getOpcode() != SPIRV::OpName) && + (MI->getOpcode() != SPIRV::OpTypeVoid) && + (MI->getOpcode() != SPIRV::OpTypeFunction))) { outputInstruction(MI); } } diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index 7a67cb35d..3b8bfd2eb 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -3029,25 +3029,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(); 
@YixingZhang007 YixingZhang007 force-pushed the solve_external_global_variable_issue branch from ea674a6 to 63ae5de Compare November 12, 2025 17:39
@YixingZhang007 YixingZhang007 force-pushed the solve_external_global_variable_issue branch from 63ae5de to 388e124 Compare November 12, 2025 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

2 participants