Skip to content

Fix mangling issue #2471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions lib/SPIRV/OCLToSPIRV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ bool OCLToSPIRVBase::runOCLToSPIRV(Module &Module) {
std::get<0>(Src) != spv::SourceLanguageOpenCL_CPP &&
std::get<0>(Src) != spv::SourceLanguageCPP_for_OpenCL)
return false;

SrcLang = std::get<0>(Src);
CLVer = std::get<1>(Src);

LLVM_DEBUG(dbgs() << "Enter OCLToSPIRV:\n");
Expand Down Expand Up @@ -203,7 +203,8 @@ void OCLToSPIRVBase::visitCallInst(CallInst &CI) {

auto MangledName = F->getName();
StringRef DemangledName;
if (!oclIsBuiltin(MangledName, DemangledName))

if (!oclIsBuiltin(MangledName, DemangledName, isCpp(SrcLang)))
return;

LLVM_DEBUG(dbgs() << "DemangledName: " << DemangledName << '\n');
Expand Down Expand Up @@ -710,7 +711,7 @@ void OCLToSPIRVBase::transAtomicBuiltin(CallInst *CI,
}

void OCLToSPIRVBase::visitCallBarrier(CallInst *CI) {
auto Lit = getBarrierLiterals(CI);
auto Lit = getBarrierLiterals(CI, isCpp(SrcLang));
// Use sequential consistent memory order by default.
// But if the flags argument is set to 0, we use
// None(Relaxed) memory order.
Expand Down Expand Up @@ -955,7 +956,8 @@ void OCLToSPIRVBase::transBuiltin(CallInst *CI, OCLBuiltinTransInfo &Info) {
} else {
Info.UniqName = getSPIRVFuncName(OC);
}
} else if ((ExtOp = getExtOp(Info.MangledName, Info.UniqName)) != ~0U)
} else if ((ExtOp = getExtOp(Info.MangledName, Info.UniqName,
isCpp(SrcLang))) != ~0U)
Info.UniqName = getSPIRVExtFuncName(SPIRVEIS_OpenCL, ExtOp);
else if (SPIRSPIRVBuiltinVariableMap::find(Info.UniqName, &BVKind)) {
// Map OCL work item builtins to SPV-IR work item builtins.
Expand Down Expand Up @@ -1397,8 +1399,9 @@ void OCLToSPIRVBase::visitCallScalToVec(CallInst *CI, StringRef MangledName,
Type *VecTy = CI->getOperand(VecPos[0])->getType();
auto VecElemCount = cast<VectorType>(VecTy)->getElementCount();
auto Mutator = mutateCallInst(
CI, getSPIRVExtFuncName(SPIRVEIS_OpenCL,
getExtOp(MangledName, DemangledName)));
CI,
getSPIRVExtFuncName(SPIRVEIS_OpenCL, getExtOp(MangledName, DemangledName,
isCpp(SrcLang))));
for (auto I : ScalarPos)
Mutator.mapArg(I, [&](Value *V) {
Instruction *Inst = InsertElementInst::Create(UndefValue::get(VecTy), V,
Expand Down Expand Up @@ -1795,7 +1798,7 @@ void OCLToSPIRVBase::visitSubgroupAVCBuiltinCallWithSampler(

void OCLToSPIRVBase::visitCallSplitBarrierINTEL(CallInst *CI,
StringRef DemangledName) {
auto Lit = getBarrierLiterals(CI);
auto Lit = getBarrierLiterals(CI, isCpp(SrcLang));
Op OpCode =
StringSwitch<Op>(DemangledName)
.Case("intel_work_group_barrier_arrive", OpControlBarrierArriveINTEL)
Expand Down
5 changes: 3 additions & 2 deletions lib/SPIRV/OCLToSPIRV.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class OCLTypeToSPIRVBase;
class OCLToSPIRVBase : public InstVisitor<OCLToSPIRVBase>, BuiltinCallHelper {
public:
OCLToSPIRVBase()
: BuiltinCallHelper(ManglingRules::SPIRV), Ctx(nullptr), CLVer(0),
OCLTypeToSPIRVPtr(nullptr) {}
: BuiltinCallHelper(ManglingRules::SPIRV), Ctx(nullptr), SrcLang(0),
CLVer(0), OCLTypeToSPIRVPtr(nullptr) {}
virtual ~OCLToSPIRVBase() {}
bool runOCLToSPIRV(Module &M);

Expand Down Expand Up @@ -267,6 +267,7 @@ class OCLToSPIRVBase : public InstVisitor<OCLToSPIRVBase>, BuiltinCallHelper {

private:
LLVMContext *Ctx;
unsigned SrcLang;
unsigned CLVer; /// OpenCL version as major*10+minor
std::set<Instruction *> ValuesToDelete;
OCLTypeToSPIRVBase *OCLTypeToSPIRVPtr;
Expand Down
7 changes: 4 additions & 3 deletions lib/SPIRV/OCLTypeToSPIRV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ OCLTypeToSPIRVBase &OCLTypeToSPIRVPass::run(llvm::Module &M,
}

OCLTypeToSPIRVBase::OCLTypeToSPIRVBase()
: BuiltinCallHelper(ManglingRules::None), M(nullptr), Ctx(nullptr) {}
: BuiltinCallHelper(ManglingRules::None), M(nullptr), Ctx(nullptr),
SrcLang(0) {}

bool OCLTypeToSPIRVBase::runOCLTypeToSPIRV(Module &Module) {
LLVM_DEBUG(dbgs() << "Enter OCLTypeToSPIRV:\n");
Expand All @@ -95,7 +96,7 @@ bool OCLTypeToSPIRVBase::runOCLTypeToSPIRV(Module &Module) {
std::get<0>(Src) != spv::SourceLanguageOpenCL_CPP &&
std::get<0>(Src) != spv::SourceLanguageCPP_for_OpenCL)
return false;

SrcLang = std::get<0>(Src);
for (auto &F : Module.functions())
adaptArgumentsByMetadata(&F);

Expand Down Expand Up @@ -199,7 +200,7 @@ void OCLTypeToSPIRVBase::adaptArgumentsBySamplerUse(Module &M) {
continue;
auto MangledName = F.getName();
StringRef DemangledName;
if (!oclIsBuiltin(MangledName, DemangledName, false))
if (!oclIsBuiltin(MangledName, DemangledName, isCpp(SrcLang)))
continue;
if (DemangledName.find(kSPIRVName::SampledImage) == std::string::npos)
continue;
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/OCLTypeToSPIRV.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class OCLTypeToSPIRVBase : protected BuiltinCallHelper {
private:
llvm::Module *M;
llvm::LLVMContext *Ctx;
unsigned SrcLang;
// Map of argument/Function -> adapted type (probably TypedPointerType)
std::unordered_map<llvm::Value *, llvm::Type *> AdaptedTy;
std::set<llvm::Function *> WorkSet; // Functions to be adapted
Expand Down
10 changes: 6 additions & 4 deletions lib/SPIRV/OCLUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,13 +716,13 @@ bool isComputeAtomicOCLBuiltin(StringRef DemangledName) {
.Default(false);
}

BarrierLiterals getBarrierLiterals(CallInst *CI) {
BarrierLiterals getBarrierLiterals(CallInst *CI, bool IsCpp) {
auto N = CI->arg_size();
assert(N == 1 || N == 2);

StringRef DemangledName;
assert(CI->getCalledFunction() && "Unexpected indirect call");
if (!oclIsBuiltin(CI->getCalledFunction()->getName(), DemangledName)) {
if (!oclIsBuiltin(CI->getCalledFunction()->getName(), DemangledName, IsCpp)) {
assert(0 &&
"call must a builtin (work_group_barrier or sub_group_barrier)");
}
Expand All @@ -738,9 +738,11 @@ BarrierLiterals getBarrierLiterals(CallInst *CI) {
Scope);
}

unsigned getExtOp(StringRef OrigName, StringRef GivenDemangledName) {
unsigned getExtOp(StringRef OrigName, StringRef GivenDemangledName,
bool IsCpp) {
std::string DemangledName{GivenDemangledName};
if (DemangledName.empty() || !oclIsBuiltin(OrigName, GivenDemangledName))
if (DemangledName.empty() ||
!oclIsBuiltin(OrigName, GivenDemangledName, IsCpp))
return ~0U;
LLVM_DEBUG(dbgs() << "getExtOp: demangled name: " << DemangledName << '\n');
OCLExtOpKind EOC;
Expand Down
5 changes: 3 additions & 2 deletions lib/SPIRV/OCLUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,13 +411,14 @@ const static char TypePrefix[] = "opencl.intel_sub_group_avc_";
/// not empty.
/// \return instruction index of extended instruction if the OpenCL builtin
/// function is translated to an extended instruction, otherwise ~0U.
unsigned getExtOp(StringRef MangledName, StringRef DemangledName = "");
unsigned getExtOp(StringRef MangledName, StringRef DemangledName = "",
bool IsCpp = false);

/// Get literal arguments of call of atomic_work_item_fence.
AtomicWorkItemFenceLiterals getAtomicWorkItemFenceLiterals(CallInst *CI);

/// Get literal arguments of call of work_group_barrier or sub_group_barrier.
BarrierLiterals getBarrierLiterals(CallInst *CI);
BarrierLiterals getBarrierLiterals(CallInst *CI, bool IsCpp = false);

/// Get number of memory order arguments for atomic builtin function.
size_t getAtomicBuiltinNumMemoryOrderArgs(StringRef Name);
Expand Down
12 changes: 8 additions & 4 deletions lib/SPIRV/SPIRVInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,8 @@ std::string getSPIRVExtFuncName(SPIRVExtInstSetKind Set, unsigned ExtOp,
/// otherwise return OpNop.
/// \param Dec contains decorations decoded from function name if it is
/// not nullptr.
Op getSPIRVFuncOC(StringRef Name, SmallVectorImpl<std::string> *Dec = nullptr);
Op getSPIRVFuncOC(StringRef Name, SmallVectorImpl<std::string> *Dec = nullptr,
bool IsCpp = false);

/// Get SPIR-V builtin variable enum given the canonical builtin name
/// Assume \param Name is in format __spirv_BuiltIn{Name}
Expand Down Expand Up @@ -951,7 +952,8 @@ bool hasLoopMetadata(const Module *M);

// Check if CI is a call to instruction from OpenCL Extended Instruction Set.
// If so, return it's extended opcode in ExtOp.
bool isSPIRVOCLExtInst(const CallInst *CI, OCLExtOpKind *ExtOp);
bool isSPIRVOCLExtInst(const CallInst *CI, OCLExtOpKind *ExtOp,
bool IsCpp = false);

/// Returns true if a function name corresponds to an OpenCL builtin that is not
/// expected to have name mangling.
Expand Down Expand Up @@ -980,11 +982,11 @@ bool lowerBuiltinVariableToCall(GlobalVariable *GV,
bool lowerBuiltinVariablesToCalls(Module *M);

// Transform all builtin calls into variables
bool lowerBuiltinCallsToVariables(Module *M);
bool lowerBuiltinCallsToVariables(Module *M, bool IsCpp = false);

// Transform all builtins into variables or calls
// depending on user specification
bool lowerBuiltins(SPIRVModule *BM, Module *M);
bool lowerBuiltins(SPIRVModule *BM, Module *M, bool IsCpp = false);

/// \brief Post-process OpenCL or SPIRV builtin function returning struct type.
///
Expand All @@ -1003,6 +1005,8 @@ bool postProcessBuiltinsReturningStruct(Module *M, bool IsCpp = false);

bool postProcessBuiltinsWithArrayArguments(Module *M, bool IsCpp = false);

bool isCpp(unsigned SrcLang);

} // namespace SPIRV

#endif // SPIRV_SPIRVINTERNAL_H
4 changes: 3 additions & 1 deletion lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3432,7 +3432,9 @@ bool SPIRVToLLVM::translate() {
if (!transSourceExtension())
return false;
transGeneratorMD();
if (!lowerBuiltins(BM, M))
SPIRVWord Ver = 0;
SourceLanguage SrcLang = BM->getSourceLanguage(&Ver);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not be using a SPIR-V module's source language to affect the translation flow. The SPIR-V specification for OpSource states:

This has no semantic impact and can safely be removed from a module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. But name mangling happens in a different way depending on what the source language is. If we have to unmangle the names. we need to know the source language. May be we can do something in the regularization pass?

Thanks

if (!lowerBuiltins(BM, M, isCpp(SrcLang)))
return false;
if (BM->getDesiredBIsRepresentation() == BIsRepresentation::SPIRVFriendlyIR) {
SPIRVWord SrcLangVer = 0;
Expand Down
6 changes: 3 additions & 3 deletions lib/SPIRV/SPIRVToOCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void SPIRVToOCLBase::visitCallInst(CallInst &CI) {
return;

OCLExtOpKind ExtOp;
if (isSPIRVOCLExtInst(&CI, &ExtOp)) {
if (isSPIRVOCLExtInst(&CI, &ExtOp, isCpp(SrcLang))) {
switch (ExtOp) {
case OpenCLLIB::Vloadn:
case OpenCLLIB::Vloada_halfn:
Expand Down Expand Up @@ -89,8 +89,8 @@ void SPIRVToOCLBase::visitCallInst(CallInst &CI) {
StringRef DemangledName;
Op OC = OpNop;
SPIRVBuiltinVariableKind BuiltinKind = SPIRVBuiltinVariableKind::BuiltInMax;
if (!oclIsBuiltin(MangledName, DemangledName) ||
((OC = getSPIRVFuncOC(DemangledName)) == OpNop &&
if (!oclIsBuiltin(MangledName, DemangledName, isCpp(SrcLang)) ||
((OC = getSPIRVFuncOC(DemangledName, nullptr, isCpp(SrcLang))) == OpNop &&
!getSPIRVBuiltin(DemangledName.str(), BuiltinKind)))
return;
LLVM_DEBUG(dbgs() << "DemangledName = " << DemangledName.str() << '\n'
Expand Down
3 changes: 2 additions & 1 deletion lib/SPIRV/SPIRVToOCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class SPIRVToOCLBase : public InstVisitor<SPIRVToOCLBase>,
public:
SPIRVToOCLBase()
: BuiltinCallHelper(ManglingRules::OpenCL, translateOpaqueType),
M(nullptr), Ctx(nullptr) {}
M(nullptr), Ctx(nullptr), SrcLang(0) {}
virtual ~SPIRVToOCLBase() {}

virtual bool runSPIRVToOCL(Module &M) = 0;
Expand Down Expand Up @@ -292,6 +292,7 @@ class SPIRVToOCLBase : public InstVisitor<SPIRVToOCLBase>,
protected:
Module *M;
LLVMContext *Ctx;
unsigned SrcLang;
};

class SPIRVToOCLLegacy : public ModulePass {
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/SPIRVToOCL12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ bool SPIRVToOCL12Legacy::runOnModule(Module &Module) {
bool SPIRVToOCL12Base::runSPIRVToOCL(Module &Module) {
M = &Module;
Ctx = &M->getContext();
auto Src = getSPIRVSource(&Module);
SrcLang = std::get<0>(Src);

// Lower builtin variables to builtin calls first.
lowerBuiltinVariablesToCalls(M);
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/SPIRVToOCL20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ bool SPIRVToOCL20Legacy::runOnModule(Module &Module) {
bool SPIRVToOCL20Base::runSPIRVToOCL(Module &Module) {
M = &Module;
Ctx = &M->getContext();
auto Src = getSPIRVSource(&Module);
SrcLang = std::get<0>(Src);

// Lower builtin variables to builtin calls first.
lowerBuiltinVariablesToCalls(M);
Expand Down
4 changes: 2 additions & 2 deletions lib/SPIRV/SPIRVTypeScavenger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,9 @@ bool SPIRVTypeScavenger::typeIntrinsicCall(
};

StringRef DemangledName;
if (oclIsBuiltin(TargetFn->getName(), DemangledName) ||
if (oclIsBuiltin(TargetFn->getName(), DemangledName, isCpp(SrcLang)) ||
isDecoratedSPIRVFunc(TargetFn, DemangledName)) {
Op OC = getSPIRVFuncOC(DemangledName);
Op OC = getSPIRVFuncOC(DemangledName, nullptr, isCpp(SrcLang));
switch (OC) {
case OpAtomicLoad:
case OpAtomicExchange:
Expand Down
7 changes: 7 additions & 0 deletions lib/SPIRV/SPIRVTypeScavenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueMap.h"

#include "SPIRVInternal.h"

using namespace llvm;

/// This class allows for the recovery of typed pointer types from LLVM opaque
Expand Down Expand Up @@ -208,8 +210,13 @@ class SPIRVTypeScavenger {
/// currently being investigated, to avoid the possibility of infinite cycles.
std::vector<Value *> VisitStack;

/// Source language
unsigned SrcLang;

public:
explicit SPIRVTypeScavenger(Module &M) : UnifiedTypeVars(1024) {
auto Src = getSPIRVSource(&M);
SrcLang = std::get<0>(Src);
typeModule(M);
}

Expand Down
Loading
Loading