forked from OSchip/llvm-project
[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
This commit is contained in:
parent
0121b1a4ac
commit
7a3c9a85c5
|
@ -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 =
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue