Skip to content

Commit df87130

Browse files
iliya-diyachkovzuban32michalpaszkowskiandreytr4intelktrifunovic
committed
[SPIRV] support capabilities and extensions
This patch supports SPIR-V capabilities and extensions. In addition, it inserts decorations related to MIFlags and improves support of switches. Five tests are included to demonstrate the improvement. Differential Revision: https://reviews.llvm.org/D131221 Co-authored-by: Aleksandr Bezzubikov <zuban32s@gmail.com> Co-authored-by: Michal Paszkowski <michal.paszkowski@outlook.com> Co-authored-by: Andrey Tretyakov <andrey1.tretyakov@intel.com> Co-authored-by: Konrad Trifunovic <konrad.trifunovic@intel.com>
1 parent d6f2e32 commit df87130

13 files changed

+1077
-17
lines changed

llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class SPIRVAsmPrinter : public AsmPrinter {
5757
void outputMCInst(MCInst &Inst);
5858
void outputInstruction(const MachineInstr *MI);
5959
void outputModuleSection(SPIRV::ModuleSectionType MSType);
60+
void outputGlobalRequirements();
6061
void outputEntryPoints();
6162
void outputDebugSourceAndStrings(const Module &M);
6263
void outputOpExtInstImports(const Module &M);
@@ -318,6 +319,30 @@ void SPIRVAsmPrinter::outputEntryPoints() {
318319
}
319320
}
320321

322+
// Create global OpCapability instructions for the required capabilities.
323+
void SPIRVAsmPrinter::outputGlobalRequirements() {
324+
// Abort here if not all requirements can be satisfied.
325+
MAI->Reqs.checkSatisfiable(*ST);
326+
327+
for (const auto &Cap : MAI->Reqs.getMinimalCapabilities()) {
328+
MCInst Inst;
329+
Inst.setOpcode(SPIRV::OpCapability);
330+
Inst.addOperand(MCOperand::createImm(Cap));
331+
outputMCInst(Inst);
332+
}
333+
334+
// Generate the final OpExtensions with strings instead of enums.
335+
for (const auto &Ext : MAI->Reqs.getExtensions()) {
336+
MCInst Inst;
337+
Inst.setOpcode(SPIRV::OpExtension);
338+
addStringImm(getSymbolicOperandMnemonic(
339+
SPIRV::OperandCategory::ExtensionOperand, Ext),
340+
Inst);
341+
outputMCInst(Inst);
342+
}
343+
// TODO add a pseudo instr for version number.
344+
}
345+
321346
void SPIRVAsmPrinter::outputExtFuncDecls() {
322347
// Insert OpFunctionEnd after each declaration.
323348
SmallVectorImpl<MachineInstr *>::iterator
@@ -467,8 +492,8 @@ void SPIRVAsmPrinter::outputModuleSections() {
467492
MAI = &SPIRVModuleAnalysis::MAI;
468493
assert(ST && TII && MAI && M && "Module analysis is required");
469494
// Output instructions according to the Logical Layout of a Module:
470-
// TODO: 1,2. All OpCapability instructions, then optional OpExtension
471-
// instructions.
495+
// 1,2. All OpCapability instructions, then optional OpExtension instructions.
496+
outputGlobalRequirements();
472497
// 3. Optional OpExtInstImport instructions.
473498
outputOpExtInstImports(*M);
474499
// 4. The single required OpMemoryModel instruction.

llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,56 @@ bool SPIRVInstrInfo::isHeaderInstr(const MachineInstr &MI) const {
9191
}
9292
}
9393

94+
bool SPIRVInstrInfo::canUseFastMathFlags(const MachineInstr &MI) const {
95+
switch (MI.getOpcode()) {
96+
case SPIRV::OpFAddS:
97+
case SPIRV::OpFSubS:
98+
case SPIRV::OpFMulS:
99+
case SPIRV::OpFDivS:
100+
case SPIRV::OpFRemS:
101+
case SPIRV::OpFAddV:
102+
case SPIRV::OpFSubV:
103+
case SPIRV::OpFMulV:
104+
case SPIRV::OpFDivV:
105+
case SPIRV::OpFRemV:
106+
case SPIRV::OpFMod:
107+
return true;
108+
default:
109+
return false;
110+
}
111+
}
112+
113+
bool SPIRVInstrInfo::canUseNSW(const MachineInstr &MI) const {
114+
switch (MI.getOpcode()) {
115+
case SPIRV::OpIAddS:
116+
case SPIRV::OpIAddV:
117+
case SPIRV::OpISubS:
118+
case SPIRV::OpISubV:
119+
case SPIRV::OpIMulS:
120+
case SPIRV::OpIMulV:
121+
case SPIRV::OpShiftLeftLogicalS:
122+
case SPIRV::OpShiftLeftLogicalV:
123+
case SPIRV::OpSNegate:
124+
return true;
125+
default:
126+
return false;
127+
}
128+
}
129+
130+
bool SPIRVInstrInfo::canUseNUW(const MachineInstr &MI) const {
131+
switch (MI.getOpcode()) {
132+
case SPIRV::OpIAddS:
133+
case SPIRV::OpIAddV:
134+
case SPIRV::OpISubS:
135+
case SPIRV::OpISubV:
136+
case SPIRV::OpIMulS:
137+
case SPIRV::OpIMulV:
138+
return true;
139+
default:
140+
return false;
141+
}
142+
}
143+
94144
// Analyze the branching code at the end of MBB, returning
95145
// true if it cannot be understood (e.g. it's a switch dispatch or isn't
96146
// implemented for a target). Upon success, this returns false and returns

llvm/lib/Target/SPIRV/SPIRVInstrInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class SPIRVInstrInfo : public SPIRVGenInstrInfo {
3232
bool isConstantInstr(const MachineInstr &MI) const;
3333
bool isTypeDeclInstr(const MachineInstr &MI) const;
3434
bool isDecorationInstr(const MachineInstr &MI) const;
35+
bool canUseFastMathFlags(const MachineInstr &MI) const;
36+
bool canUseNSW(const MachineInstr &MI) const;
37+
bool canUseNUW(const MachineInstr &MI) const;
3538

3639
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
3740
MachineBasicBlock *&FBB,

0 commit comments

Comments
 (0)