diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp --- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp @@ -394,7 +394,7 @@ if (ConstantInt *Const = dyn_cast(C)) { Inst.addOperand(MCOperand::createImm(Const->getZExtValue())); } else if (auto *CE = dyn_cast(C)) { - Register FuncReg = MAI->getFuncReg(CE->getName().str()); + Register FuncReg = MAI->getFuncReg(CE); assert(FuncReg.isValid()); Inst.addOperand(MCOperand::createReg(FuncReg)); } @@ -426,7 +426,7 @@ const Function &F = *FI; if (F.isDeclaration()) continue; - Register FReg = MAI->getFuncReg(F.getGlobalIdentifier()); + Register FReg = MAI->getFuncReg(&F); assert(FReg.isValid()); if (MDNode *Node = F.getMetadata("reqd_work_group_size")) outputExecutionModeFromMDNode(FReg, Node, @@ -464,9 +464,9 @@ // the annotated variable. Value *AnnotatedVar = CS->getOperand(0)->stripPointerCasts(); if (!isa(AnnotatedVar)) - llvm_unreachable("Unsupported value in llvm.global.annotations"); + report_fatal_error("Unsupported value in llvm.global.annotations"); Function *Func = cast(AnnotatedVar); - Register Reg = MAI->getFuncReg(Func->getGlobalIdentifier()); + Register Reg = MAI->getFuncReg(Func); // The second field contains a pointer to a global annotation string. GlobalVariable *GV = diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp --- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp @@ -374,7 +374,7 @@ Register ResVReg = Info.OrigRet.Regs.empty() ? Register(0) : Info.OrigRet.Regs[0]; - std::string FuncName = Info.Callee.getGlobal()->getGlobalIdentifier(); + std::string FuncName = Info.Callee.getGlobal()->getName().str(); std::string DemangledName = getOclOrSpirvBuiltinDemangledName(FuncName); const auto *ST = static_cast(&MF.getSubtarget()); // TODO: check that it's OCL builtin, then apply OpenCL_std. diff --git a/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp b/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp --- a/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp @@ -31,7 +31,7 @@ default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_GlobalAddress: { - Register FuncReg = MAI->getFuncReg(MO.getGlobal()->getGlobalIdentifier()); + Register FuncReg = MAI->getFuncReg(dyn_cast(MO.getGlobal())); assert(FuncReg.isValid() && "Cannot find function Id"); MCOp = MCOperand::createReg(FuncReg); break; diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h @@ -16,6 +16,7 @@ #include "MCTargetDesc/SPIRVBaseInfo.h" #include "SPIRVGlobalRegistry.h" +#include "SPIRVUtils.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" @@ -150,8 +151,9 @@ // The table maps MBB number to SPIR-V unique ID register. DenseMap BBNumToRegMap; - Register getFuncReg(std::string FuncName) { - auto FuncReg = FuncNameMap.find(FuncName); + Register getFuncReg(const Function *F) { + assert(F && "Function is null"); + auto FuncReg = FuncNameMap.find(getFunctionGlobalIdentifier(F)); assert(FuncReg != FuncNameMap.end() && "Cannot find function Id"); return FuncReg->second; } diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -304,7 +304,7 @@ Register GlobalReg = MAI.getRegisterAlias(MI.getMF(), Reg); assert(GlobalReg.isValid()); // TODO: check that it does not conflict with existing entries. - MAI.FuncNameMap[F.getGlobalIdentifier()] = GlobalReg; + MAI.FuncNameMap[getFunctionGlobalIdentifier(&F)] = GlobalReg; } } diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h --- a/llvm/lib/Target/SPIRV/SPIRVUtils.h +++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h @@ -90,5 +90,7 @@ // Check if given LLVM type is a special opaque builtin type. bool isSpecialOpaqueType(const Type *Ty); + +std::string getFunctionGlobalIdentifier(const Function *F); } // namespace llvm #endif // LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp --- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp @@ -351,4 +351,11 @@ return isOpenCLBuiltinType(SType) || isSPIRVBuiltinType(SType); return false; } + +std::string getFunctionGlobalIdentifier(const Function *F) { + StringRef Name = F->hasName() ? F->getName() : ".anonymous"; + GlobalValue::LinkageTypes Linkage = F->getLinkage(); + StringRef ModuleFileName = F->getParent()->getSourceFileName(); + return GlobalValue::getGlobalIdentifier(Name, Linkage, ModuleFileName); +} } // namespace llvm diff --git a/llvm/test/CodeGen/SPIRV/function/internal-anonymous-function.ll b/llvm/test/CodeGen/SPIRV/function/internal-anonymous-function.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/function/internal-anonymous-function.ll @@ -0,0 +1,20 @@ +; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s + +;; Types: +; CHECK-DAG: %[[#F32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#FNF32:]] = OpTypeFunction %[[#F32]] %[[#F32]] +;; Function decl: +; CHECK: %[[#ANON:]] = OpFunction %[[#F32]] None %[[#FNF32]] +; CHECK-NEXT: OpFunctionParameter %[[#F32]] +; CHECK-NEXT: OpLabel +; CHECK-NEXT: OpReturnValue +; CHECK-NEXT: OpFunctionEnd +define internal spir_func float @0(float %a) { + ret float %a +} + +; CHECK: OpFunctionCall %[[#F32]] %[[#ANON]] +define spir_kernel void @foo(float %a) { + %1 = call spir_func float @0(float %a) + ret void +}