[llvm] 7a3c9a8 - [SPIRV] Fix call lowering of "anonymous" functions

Michal Paszkowski via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 10 15:09:34 PDT 2022


Author: Michal Paszkowski
Date: 2022-10-11T00:06:29+02:00
New Revision: 7a3c9a85c5fa614ba43b013fce3445fe1f8fdd3f

URL: https://github.com/llvm/llvm-project/commit/7a3c9a85c5fa614ba43b013fce3445fe1f8fdd3f
DIFF: https://github.com/llvm/llvm-project/commit/7a3c9a85c5fa614ba43b013fce3445fe1f8fdd3f.diff

LOG: [SPIRV] Fix call lowering of "anonymous" functions

The patch fixes lowering of anonymous functions, removes file/linkage
info for builtin call demangling, and adds relevant test demonstrating
a fixed problem.

Differential Revision: https://reviews.llvm.org/D135390

Added: 
    llvm/test/CodeGen/SPIRV/function/internal-anonymous-function.ll

Modified: 
    llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
    llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
    llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp
    llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
    llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
    llvm/lib/Target/SPIRV/SPIRVUtils.cpp
    llvm/lib/Target/SPIRV/SPIRVUtils.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index 13415f2c96b4f..f32d70eb4e711 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -394,7 +394,7 @@ static void addOpsFromMDNode(MDNode *MDN, MCInst &Inst,
       if (ConstantInt *Const = dyn_cast<ConstantInt>(C)) {
         Inst.addOperand(MCOperand::createImm(Const->getZExtValue()));
       } else if (auto *CE = dyn_cast<Function>(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 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
     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 @@ void SPIRVAsmPrinter::outputAnnotations(const Module &M) {
       // the annotated variable.
       Value *AnnotatedVar = CS->getOperand(0)->stripPointerCasts();
       if (!isa<Function>(AnnotatedVar))
-        llvm_unreachable("Unsupported value in llvm.global.annotations");
+        report_fatal_error("Unsupported value in llvm.global.annotations");
       Function *Func = cast<Function>(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
index 18193bf2a9ad5..9cd32cc373952 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -374,7 +374,7 @@ bool SPIRVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
 
   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<const SPIRVSubtarget *>(&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
index 8aaac50c94d78..0fa05d377d9f1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp
@@ -31,7 +31,7 @@ void SPIRVMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI,
     default:
       llvm_unreachable("unknown operand type");
     case MachineOperand::MO_GlobalAddress: {
-      Register FuncReg = MAI->getFuncReg(MO.getGlobal()->getGlobalIdentifier());
+      Register FuncReg = MAI->getFuncReg(dyn_cast<Function>(MO.getGlobal()));
       assert(FuncReg.isValid() && "Cannot find function Id");
       MCOp = MCOperand::createReg(FuncReg);
       break;

diff  --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index bc3f234960f5b..d7f620516df6b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -304,7 +304,7 @@ void SPIRVModuleAnalysis::collectFuncNames(MachineInstr &MI,
     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/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
index be7c1a4446450..2cbec9b543c6c 100644
--- 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 @@ struct ModuleAnalysisInfo {
   // The table maps MBB number to SPIR-V unique ID register.
   DenseMap<int, Register> 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/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 9eeccb5a39370..07bcdbdc05da2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -351,4 +351,11 @@ bool isSpecialOpaqueType(const Type *Ty) {
     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/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h
index 5006caedd81d3..e4e07dc68a37d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.h
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h
@@ -90,5 +90,7 @@ std::string getOclOrSpirvBuiltinDemangledName(StringRef Name);
 
 // 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/test/CodeGen/SPIRV/function/internal-anonymous-function.ll b/llvm/test/CodeGen/SPIRV/function/internal-anonymous-function.ll
new file mode 100644
index 0000000000000..761091924d56b
--- /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
+}


        


More information about the llvm-commits mailing list