diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp index 970b83de5ee33..cc6d122c03512 100644 --- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp @@ -85,9 +85,12 @@ class SPIRVAsmPrinter : public AsmPrinter { void outputModuleSections(); void outputFPFastMathDefaultInfo(); bool isHidden() { - return MF->getFunction() - .getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME) - .isValid(); + const Function &F = MF->getFunction(); + if (F.getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME).isValid()) + return true; + if (F.getName() == "__spirv_globals_entry") + return true; + return false; } void emitInstruction(const MachineInstr *MI) override; @@ -278,6 +281,10 @@ void SPIRVAsmPrinter::outputInstruction(const MachineInstr *MI) { } void SPIRVAsmPrinter::emitInstruction(const MachineInstr *MI) { + const Function &F = MF->getFunction(); + if (F.getName() == "__spirv_globals_entry") { + return; + } SPIRV_MC::verifyInstructionPredicates(MI->getOpcode(), getSubtargetInfo().getFeatureBits()); @@ -295,8 +302,14 @@ void SPIRVAsmPrinter::emitInstruction(const MachineInstr *MI) { } void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType) { - for (const MachineInstr *MI : MAI->getMSInstrs(MSType)) - outputInstruction(MI); + 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))) { + outputInstruction(MI); + } + } } void SPIRVAsmPrinter::outputDebugSourceAndStrings(const Module &M) { diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index 599cc35ca2e9d..7a67cb35d1582 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -3020,6 +3020,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);