Skip to content

Commit 900f333

Browse files
committed
[SPIR-V] Add OpConstantCompositeContinuedINTEL instruction
Specification: https://github.khronos.org/SPIRV-Registry/extensions/INTEL/SPV_INTEL_long_composites.html
1 parent c19a303 commit 900f333

File tree

6 files changed

+102
-21
lines changed

6 files changed

+102
-21
lines changed

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,24 +2911,30 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
29112911
case Intrinsic::spv_const_composite: {
29122912
// If no values are attached, the composite is null constant.
29132913
bool IsNull = I.getNumExplicitDefs() + 1 == I.getNumExplicitOperands();
2914-
// Select a proper instruction.
2915-
unsigned Opcode = SPIRV::OpConstantNull;
29162914
SmallVector<Register> CompositeArgs;
2917-
if (!IsNull) {
2918-
Opcode = SPIRV::OpConstantComposite;
2919-
if (!wrapIntoSpecConstantOp(I, CompositeArgs))
2920-
return false;
2921-
}
29222915
MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
2923-
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
2924-
.addDef(ResVReg)
2925-
.addUse(GR.getSPIRVTypeID(ResType));
2916+
29262917
// skip type MD node we already used when generated assign.type for this
29272918
if (!IsNull) {
2928-
for (Register OpReg : CompositeArgs)
2929-
MIB.addUse(OpReg);
2919+
if (!wrapIntoSpecConstantOp(I, CompositeArgs))
2920+
return false;
2921+
MachineIRBuilder MIR(I);
2922+
SmallVector<MachineInstr *, 4> Instructions = createContinuedInstructions(
2923+
MIR, SPIRV::OpConstantComposite, 3,
2924+
SPIRV::OpConstantCompositeContinuedINTEL, CompositeArgs, ResVReg,
2925+
GR.getSPIRVTypeID(ResType));
2926+
for (auto *Instr : Instructions) {
2927+
Instr->setDebugLoc(I.getDebugLoc());
2928+
if (!constrainSelectedInstRegOperands(*Instr, TII, TRI, RBI))
2929+
return false;
2930+
}
2931+
return true;
2932+
} else {
2933+
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
2934+
.addDef(ResVReg)
2935+
.addUse(GR.getSPIRVTypeID(ResType));
2936+
return MIB.constrainAllUses(TII, TRI, RBI);
29302937
}
2931-
return MIB.constrainAllUses(TII, TRI, RBI);
29322938
}
29332939
case Intrinsic::spv_assign_name: {
29342940
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpName));

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,21 @@ void SPIRVModuleAnalysis::visitDecl(
372372
MAI.setSkipEmission(NextInstr);
373373
NextInstr = NextInstr->getNextNode();
374374
}
375+
} else if (Opcode == SPIRV::OpCompositeConstruct) {
376+
GReg = handleTypeDeclOrConstant(MI, SignatureToGReg);
377+
const MachineInstr *NextInstr = MI.getNextNode();
378+
while (NextInstr && NextInstr->getOpcode() ==
379+
SPIRV::OpCompositeConstructContinuedINTEL) {
380+
Register Tmp = handleTypeDeclOrConstant(*NextInstr, SignatureToGReg);
381+
// For the case with the global variable,
382+
// OpConstantCompositeContinuedINTEL does not go directly after
383+
// OpConstantComposite, but they are "split" by the OpVariable
384+
// instruction. My guess is that the order can be fixed somewhere here,
385+
// but not sure. MAI.setRegisterAlias(MF,
386+
// NextInstr->getOperand(0).getReg(), Tmp);
387+
// MAI.setSkipEmission(NextInstr);
388+
NextInstr = NextInstr->getNextNode();
389+
}
375390
} else if (TII->isTypeDeclInstr(MI) || TII->isConstantInstr(MI) ||
376391
TII->isInlineAsmDefInstr(MI)) {
377392
GReg = handleTypeDeclOrConstant(MI, SignatureToGReg);

llvm/lib/Target/SPIRV/SPIRVUtils.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -802,10 +802,13 @@ bool isSpvIntrinsic(const Value *Arg) {
802802

803803
// Function to create continued instructions for SPV_INTEL_long_composites
804804
// extension
805-
void createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
806-
unsigned MinWC, unsigned ContinuedOpcode,
807-
ArrayRef<Register> Args,
808-
Register ReturnRegister, Register TypeID) {
805+
SmallVector<MachineInstr *, 4>
806+
createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
807+
unsigned MinWC, unsigned ContinuedOpcode,
808+
ArrayRef<Register> Args, Register ReturnRegister,
809+
Register TypeID) {
810+
811+
SmallVector<MachineInstr *, 4> Instructions;
809812
constexpr unsigned MaxWordCount = UINT16_MAX;
810813
const size_t NumElements = Args.size();
811814
size_t MaxNumElements = MaxWordCount - MinWC;
@@ -824,12 +827,16 @@ void createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
824827
for (size_t I = 0; I < SPIRVStructNumElements; ++I)
825828
MIB.addUse(Args[I]);
826829

830+
Instructions.push_back(MIB.getInstr());
831+
827832
for (size_t I = SPIRVStructNumElements; I < NumElements;
828833
I += MaxNumElements) {
829834
auto MIB = MIRBuilder.buildInstr(ContinuedOpcode);
830835
for (size_t J = I; J < std::min(I + MaxNumElements, NumElements); ++J)
831836
MIB.addUse(Args[J]);
837+
Instructions.push_back(MIB.getInstr());
832838
}
839+
return Instructions;
833840
}
834841

835842
} // namespace llvm

llvm/lib/Target/SPIRV/SPIRVUtils.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,10 +444,11 @@ inline FPDecorationId demangledPostfixToDecorationId(const std::string &S) {
444444
return It == Mapping.end() ? FPDecorationId::NONE : It->second;
445445
}
446446

447-
void createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
448-
unsigned MinWC, unsigned ContinuedOpcode,
449-
ArrayRef<Register> Args,
450-
Register ReturnRegister, Register TypeID);
447+
SmallVector<MachineInstr *, 4>
448+
createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
449+
unsigned MinWC, unsigned ContinuedOpcode,
450+
ArrayRef<Register> Args, Register ReturnRegister,
451+
Register TypeID);
451452

452453
} // namespace llvm
453454
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H

llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_long_composites/long-constant-array.ll

Lines changed: 25 additions & 0 deletions
Large diffs are not rendered by default.

llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_long_composites/long-constant-composite.ll

Lines changed: 27 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)