Skip to content

[SPIR-V] Fix issue #120078 and simplifies parsing of floating point decoration tips in demangled function name #120128

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

Merged
merged 3 commits into from
Dec 18, 2024
Merged
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
16 changes: 10 additions & 6 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ using namespace InstructionSet;
namespace SPIRV {
/// Parses the name part of the demangled builtin call.
std::string lookupBuiltinNameHelper(StringRef DemangledCall,
std::string *Postfix) {
FPDecorationId *DecorationId) {
const static std::string PassPrefix = "(anonymous namespace)::";
std::string BuiltinName;
// Itanium Demangler result may have "(anonymous namespace)::" prefix
Expand Down Expand Up @@ -232,12 +232,16 @@ std::string lookupBuiltinNameHelper(StringRef DemangledCall,
"ReadClockKHR|SubgroupBlockReadINTEL|SubgroupImageBlockReadINTEL|"
"SubgroupImageMediaBlockReadINTEL|SubgroupImageMediaBlockWriteINTEL|"
"Convert|"
"UConvert|SConvert|FConvert|SatConvert).*)_R(.*)");
"UConvert|SConvert|FConvert|SatConvert).*)_R[^_]*_?(\\w+)?.*");
std::smatch Match;
if (std::regex_match(BuiltinName, Match, SpvWithR) && Match.size() > 3) {
BuiltinName = Match[1].str();
if (Postfix)
*Postfix = Match[3].str();
if (std::regex_match(BuiltinName, Match, SpvWithR) && Match.size() > 1) {
std::ssub_match SubMatch;
if (DecorationId && Match.size() > 3) {
SubMatch = Match[3];
*DecorationId = demangledPostfixToDecorationId(SubMatch.str());
}
SubMatch = Match[1];
BuiltinName = SubMatch.str();
}

return BuiltinName;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SPIRV/SPIRVBuiltins.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace llvm {
namespace SPIRV {
/// Parses the name part of the demangled builtin call.
std::string lookupBuiltinNameHelper(StringRef DemangledCall,
std::string *Postfix = nullptr);
FPDecorationId *DecorationId = nullptr);
/// Lowers a builtin function call using the provided \p DemangledCall skeleton
/// and external instruction \p Set.
///
Expand Down
52 changes: 26 additions & 26 deletions llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1876,18 +1876,6 @@ bool SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I,
return true;
}

static unsigned roundingModeMDToDecorationConst(StringRef S) {
if (S == "rte")
return SPIRV::FPRoundingMode::FPRoundingMode::RTE;
if (S == "rtz")
return SPIRV::FPRoundingMode::FPRoundingMode::RTZ;
if (S == "rtp")
return SPIRV::FPRoundingMode::FPRoundingMode::RTP;
if (S == "rtn")
return SPIRV::FPRoundingMode::FPRoundingMode::RTN;
return std::numeric_limits<unsigned>::max();
}

void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
IRBuilder<> &B) {
// TODO: extend the list of functions with known result types
Expand All @@ -1905,9 +1893,10 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
Function *CalledF = CI->getCalledFunction();
std::string DemangledName =
getOclOrSpirvBuiltinDemangledName(CalledF->getName());
std::string Postfix;
FPDecorationId DecorationId = FPDecorationId::NONE;
if (DemangledName.length() > 0)
DemangledName = SPIRV::lookupBuiltinNameHelper(DemangledName, &Postfix);
DemangledName =
SPIRV::lookupBuiltinNameHelper(DemangledName, &DecorationId);
auto ResIt = ResTypeWellKnown.find(DemangledName);
if (ResIt != ResTypeWellKnown.end()) {
IsKnown = true;
Expand All @@ -1919,18 +1908,29 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
break;
}
}
// check if a floating rounding mode info is present
StringRef S = Postfix;
SmallVector<StringRef, 8> Parts;
S.split(Parts, "_", -1, false);
if (Parts.size() > 1) {
// Convert the info about rounding mode into a decoration record.
unsigned RoundingModeDeco = roundingModeMDToDecorationConst(Parts[1]);
if (RoundingModeDeco != std::numeric_limits<unsigned>::max())
createRoundingModeDecoration(CI, RoundingModeDeco, B);
// Check if the SaturatedConversion info is present.
if (Parts[1] == "sat")
createSaturatedConversionDecoration(CI, B);
// check if a floating rounding mode or saturation info is present
switch (DecorationId) {
default:
break;
case FPDecorationId::SAT:
createSaturatedConversionDecoration(CI, B);
break;
case FPDecorationId::RTE:
createRoundingModeDecoration(
CI, SPIRV::FPRoundingMode::FPRoundingMode::RTE, B);
break;
case FPDecorationId::RTZ:
createRoundingModeDecoration(
CI, SPIRV::FPRoundingMode::FPRoundingMode::RTZ, B);
break;
case FPDecorationId::RTP:
createRoundingModeDecoration(
CI, SPIRV::FPRoundingMode::FPRoundingMode::RTP, B);
break;
case FPDecorationId::RTN:
createRoundingModeDecoration(
CI, SPIRV::FPRoundingMode::FPRoundingMode::RTN, B);
break;
}
}
}
Expand Down
36 changes: 30 additions & 6 deletions llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,28 +157,52 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeVoid(MachineIRBuilder &MIRBuilder) {
});
}

void SPIRVGlobalRegistry::invalidateMachineInstr(MachineInstr *MI) {
// TODO:
// - take into account duplicate tracker case which is a known issue,
// - review other data structure wrt. possible issues related to removal
// of a machine instruction during instruction selection.
const MachineFunction *MF = MI->getParent()->getParent();
auto It = LastInsertedTypeMap.find(MF);
if (It == LastInsertedTypeMap.end())
return;
if (It->second == MI)
LastInsertedTypeMap.erase(MF);
}

SPIRVType *SPIRVGlobalRegistry::createOpType(
MachineIRBuilder &MIRBuilder,
std::function<MachineInstr *(MachineIRBuilder &)> Op) {
auto oldInsertPoint = MIRBuilder.getInsertPt();
MachineBasicBlock *OldMBB = &MIRBuilder.getMBB();
MachineBasicBlock *NewMBB = &*MIRBuilder.getMF().begin();

auto LastInsertedType = LastInsertedTypeMap.find(CurMF);
if (LastInsertedType != LastInsertedTypeMap.end()) {
auto It = LastInsertedType->second->getIterator();
auto NewMBB = MIRBuilder.getMF().begin();
MIRBuilder.setInsertPt(*NewMBB, It->getNextNode()
? It->getNextNode()->getIterator()
: NewMBB->end());
// It might happen that this instruction was removed from the first MBB,
// hence the Parent's check.
MachineBasicBlock::iterator InsertAt;
if (It->getParent() != NewMBB)
InsertAt = oldInsertPoint->getParent() == NewMBB
? oldInsertPoint
: getInsertPtValidEnd(NewMBB);
else if (It->getNextNode())
InsertAt = It->getNextNode()->getIterator();
else
InsertAt = getInsertPtValidEnd(NewMBB);
MIRBuilder.setInsertPt(*NewMBB, InsertAt);
} else {
MIRBuilder.setInsertPt(*MIRBuilder.getMF().begin(),
MIRBuilder.getMF().begin()->begin());
MIRBuilder.setInsertPt(*NewMBB, NewMBB->begin());
auto Result = LastInsertedTypeMap.try_emplace(CurMF, nullptr);
assert(Result.second);
LastInsertedType = Result.first;
}

MachineInstr *Type = Op(MIRBuilder);
// We expect all users of this function to insert definitions at the insertion
// point set above that is always the first MBB.
assert(Type->getParent() == NewMBB);
LastInsertedType->second = Type;

MIRBuilder.setInsertPt(*OldMBB, oldInsertPoint);
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ class SPIRVGlobalRegistry {
bool isBitcastCompatible(const SPIRVType *Type1,
const SPIRVType *Type2) const;

// Informs about removal of the machine instruction and invalidates data
// structures referring this instruction.
void invalidateMachineInstr(MachineInstr *MI);

private:
SPIRVType *getOpTypeBool(MachineIRBuilder &MIRBuilder);

Expand Down
9 changes: 7 additions & 2 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
}
MRI->setRegClass(SrcReg, MRI->getRegClass(DstReg));
MRI->replaceRegWith(SrcReg, DstReg);
GR.invalidateMachineInstr(&I);
I.removeFromParent();
return true;
} else if (I.getNumDefs() == 1) {
Expand All @@ -445,6 +446,7 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
// erase it
LLVM_DEBUG(dbgs() << "Instruction is folded and dead.\n");
salvageDebugInfo(*MRI, I);
GR.invalidateMachineInstr(&I);
I.eraseFromParent();
return true;
}
Expand All @@ -464,6 +466,7 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
if (HasDefs) // Make all vregs 64 bits (for SPIR-V IDs).
for (unsigned i = 0; i < I.getNumDefs(); ++i)
MRI->setType(I.getOperand(i).getReg(), LLT::scalar(64));
GR.invalidateMachineInstr(&I);
I.removeFromParent();
return true;
}
Expand Down Expand Up @@ -2253,8 +2256,10 @@ bool SPIRVInstructionSelector::selectDiscard(Register ResVReg,
} else {
Opcode = SPIRV::OpKill;
// OpKill must be the last operation of any basic block.
MachineInstr *NextI = I.getNextNode();
NextI->removeFromParent();
if (MachineInstr *NextI = I.getNextNode()) {
GR.invalidateMachineInstr(NextI);
NextI->removeFromParent();
}
}

MachineBasicBlock &BB = *I.getParent();
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,8 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
// tighten these requirements. Many of these math functions are only legal on
// specific bitwidths, so they are not selectable for
// allFloatScalarsAndVectors.
getActionDefinitionsBuilder({G_FPOW,
getActionDefinitionsBuilder({G_STRICT_FSQRT,
G_FPOW,
G_FEXP,
G_FEXP2,
G_FLOG,
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,19 @@ MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I) {
return It;
}

MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB) {
MachineBasicBlock::iterator I = MBB->end();
if (I == MBB->begin())
return I;
--I;
while (I->isTerminator() || I->isDebugValue()) {
if (I == MBB->begin())
break;
--I;
}
return I;
}

SPIRV::StorageClass::StorageClass
addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI) {
switch (AddrSpace) {
Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder,
// i.e., at the beginning of the first block of the function.
MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I);

// Return a valid position for the instruction at the end of the block before
// terminators and debug instructions.
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB);

// Convert a SPIR-V storage class to the corresponding LLVM IR address space.
// TODO: maybe the following two functions should be handled in the subtarget
// to allow for different OpenCL vs Vulkan handling.
Expand Down Expand Up @@ -396,5 +400,18 @@ Register createVirtualRegister(const Type *Ty, SPIRVGlobalRegistry *GR,
// Return true if there is an opaque pointer type nested in the argument.
bool isNestedPointer(const Type *Ty);

enum FPDecorationId { NONE, RTE, RTZ, RTP, RTN, SAT };

inline FPDecorationId demangledPostfixToDecorationId(const std::string &S) {
static std::unordered_map<std::string, FPDecorationId> Mapping = {
{"rte", FPDecorationId::RTE},
{"rtz", FPDecorationId::RTZ},
{"rtp", FPDecorationId::RTP},
{"rtn", FPDecorationId::RTN},
{"sat", FPDecorationId::SAT}};
auto It = Mapping.find(S);
return It == Mapping.end() ? FPDecorationId::NONE : It->second;
}

} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
Loading