summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp')
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp235
1 files changed, 138 insertions, 97 deletions
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 3547ac66430a..289d5f316648 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -61,6 +61,7 @@ class SPIRVInstructionSelector : public InstructionSelector {
/// We need to keep track of the number we give to anonymous global values to
/// generate the same name every time when this is needed.
mutable DenseMap<const GlobalValue *, unsigned> UnnamedGlobalIDs;
+ SmallPtrSet<MachineInstr *, 8> DeadMIs;
public:
SPIRVInstructionSelector(const SPIRVTargetMachine &TM,
@@ -262,9 +263,6 @@ private:
bool selectSaturate(Register ResVReg, const SPIRVType *ResType,
MachineInstr &I) const;
- bool selectSpvThreadId(Register ResVReg, const SPIRVType *ResType,
- MachineInstr &I) const;
-
bool selectWaveOpInst(Register ResVReg, const SPIRVType *ResType,
MachineInstr &I, unsigned Opcode) const;
@@ -309,6 +307,10 @@ private:
SPIRVType *widenTypeToVec4(const SPIRVType *Type, MachineInstr &I) const;
void extractSubvector(Register &ResVReg, const SPIRVType *ResType,
Register &ReadReg, MachineInstr &InsertionPoint) const;
+ bool BuildCOPY(Register DestReg, Register SrcReg, MachineInstr &I) const;
+ bool loadVec3BuiltinInputID(SPIRV::BuiltIn::BuiltIn BuiltInValue,
+ Register ResVReg, const SPIRVType *ResType,
+ MachineInstr &I) const;
};
} // end anonymous namespace
@@ -381,6 +383,24 @@ static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI);
// Defined in SPIRVLegalizerInfo.cpp.
extern bool isTypeFoldingSupported(unsigned Opcode);
+bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI) {
+ for (const auto &MO : MI.all_defs()) {
+ Register Reg = MO.getReg();
+ if (Reg.isPhysical() || !MRI.use_nodbg_empty(Reg))
+ return false;
+ }
+ if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE || MI.isFakeUse() ||
+ MI.isLifetimeMarker())
+ return false;
+ if (MI.isPHI())
+ return true;
+ if (MI.mayStore() || MI.isCall() ||
+ (MI.mayLoad() && MI.hasOrderedMemoryRef()) || MI.isPosition() ||
+ MI.isDebugInstr() || MI.isTerminator() || MI.isJumpTableDebugInfo())
+ return false;
+ return true;
+}
+
bool SPIRVInstructionSelector::select(MachineInstr &I) {
resetVRegsType(*I.getParent()->getParent());
@@ -403,11 +423,15 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
}
});
assert(Res || Def->getOpcode() == TargetOpcode::G_CONSTANT);
- if (Res)
+ if (Res) {
+ if (!isTriviallyDead(*Def, *MRI) && isDead(*Def, *MRI))
+ DeadMIs.insert(Def);
return Res;
+ }
}
MRI->setRegClass(SrcReg, MRI->getRegClass(DstReg));
MRI->replaceRegWith(SrcReg, DstReg);
+ GR.invalidateMachineInstr(&I);
I.removeFromParent();
return true;
} else if (I.getNumDefs() == 1) {
@@ -417,6 +441,16 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
+ if (DeadMIs.contains(&I)) {
+ // if the instruction has been already made dead by folding it away
+ // erase it
+ LLVM_DEBUG(dbgs() << "Instruction is folded and dead.\n");
+ salvageDebugInfo(*MRI, I);
+ GR.invalidateMachineInstr(&I);
+ I.eraseFromParent();
+ return true;
+ }
+
if (I.getNumOperands() != I.getNumExplicitOperands()) {
LLVM_DEBUG(errs() << "Generic instr has unexpected implicit operands\n");
return false;
@@ -432,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;
}
@@ -449,6 +484,19 @@ static bool mayApplyGenericSelection(unsigned Opcode) {
return isTypeFoldingSupported(Opcode);
}
+bool SPIRVInstructionSelector::BuildCOPY(Register DestReg, Register SrcReg,
+ MachineInstr &I) const {
+ const TargetRegisterClass *DstRC = MRI->getRegClassOrNull(DestReg);
+ const TargetRegisterClass *SrcRC = MRI->getRegClassOrNull(SrcReg);
+ if (DstRC != SrcRC && SrcRC)
+ MRI->setRegClass(DestReg, SrcRC);
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(TargetOpcode::COPY))
+ .addDef(DestReg)
+ .addUse(SrcReg)
+ .constrainAllUses(TII, TRI, RBI);
+}
+
bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
@@ -543,9 +591,13 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
case TargetOpcode::G_UCMP:
return selectSUCmp(ResVReg, ResType, I, false);
+ case TargetOpcode::G_STRICT_FMA:
case TargetOpcode::G_FMA:
return selectExtInst(ResVReg, ResType, I, CL::fma, GL::Fma);
+ case TargetOpcode::G_STRICT_FLDEXP:
+ return selectExtInst(ResVReg, ResType, I, CL::ldexp);
+
case TargetOpcode::G_FPOW:
return selectExtInst(ResVReg, ResType, I, CL::pow, GL::Pow);
case TargetOpcode::G_FPOWI:
@@ -604,6 +656,7 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
case TargetOpcode::G_FTANH:
return selectExtInst(ResVReg, ResType, I, CL::tanh, GL::Tanh);
+ case TargetOpcode::G_STRICT_FSQRT:
case TargetOpcode::G_FSQRT:
return selectExtInst(ResVReg, ResType, I, CL::sqrt, GL::Sqrt);
@@ -1074,10 +1127,7 @@ bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
addMemoryOperands(*I.memoperands_begin(), MIB);
Result &= MIB.constrainAllUses(TII, TRI, RBI);
if (ResVReg.isValid() && ResVReg != MIB->getOperand(0).getReg())
- Result &=
- BuildMI(BB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), ResVReg)
- .addUse(MIB->getOperand(0).getReg())
- .constrainAllUses(TII, TRI, RBI);
+ Result &= BuildCOPY(ResVReg, MIB->getOperand(0).getReg(), I);
return Result;
}
@@ -1414,10 +1464,7 @@ bool SPIRVInstructionSelector::selectAddrSpaceCast(Register ResVReg,
// don't generate a cast for a null that may be represented by OpTypeInt
if (SrcPtrTy->getOpcode() != SPIRV::OpTypePointer ||
ResType->getOpcode() != SPIRV::OpTypePointer)
- return BuildMI(BB, I, DL, TII.get(TargetOpcode::COPY))
- .addDef(ResVReg)
- .addUse(SrcPtr)
- .constrainAllUses(TII, TRI, RBI);
+ return BuildCOPY(ResVReg, SrcPtr, I);
SPIRV::StorageClass::StorageClass SrcSC = GR.getPointerStorageClass(SrcPtrTy);
SPIRV::StorageClass::StorageClass DstSC = GR.getPointerStorageClass(ResType);
@@ -1455,20 +1502,13 @@ bool SPIRVInstructionSelector::selectAddrSpaceCast(Register ResVReg,
// don't generate a cast between identical storage classes
if (SrcSC == DstSC)
- return BuildMI(BB, I, DL, TII.get(TargetOpcode::COPY))
- .addDef(ResVReg)
- .addUse(SrcPtr)
- .constrainAllUses(TII, TRI, RBI);
+ return BuildCOPY(ResVReg, SrcPtr, I);
if ((SrcSC == SPIRV::StorageClass::Function &&
DstSC == SPIRV::StorageClass::Private) ||
(DstSC == SPIRV::StorageClass::Function &&
- SrcSC == SPIRV::StorageClass::Private)) {
- return BuildMI(BB, I, DL, TII.get(TargetOpcode::COPY))
- .addDef(ResVReg)
- .addUse(SrcPtr)
- .constrainAllUses(TII, TRI, RBI);
- }
+ SrcSC == SPIRV::StorageClass::Private))
+ return BuildCOPY(ResVReg, SrcPtr, I);
// Casting from an eligible pointer to Generic.
if (DstSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(SrcSC))
@@ -1643,11 +1683,7 @@ bool SPIRVInstructionSelector::selectAnyOrAll(Register ResVReg,
bool IsVectorTy = InputType->getOpcode() == SPIRV::OpTypeVector;
if (IsBoolTy && !IsVectorTy) {
assert(ResVReg == I.getOperand(0).getReg());
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(TargetOpcode::COPY))
- .addDef(ResVReg)
- .addUse(InputRegister)
- .constrainAllUses(TII, TRI, RBI);
+ return BuildCOPY(ResVReg, InputRegister, I);
}
bool IsFloatTy = GR.isScalarOrVectorOfType(InputRegister, SPIRV::OpTypeFloat);
@@ -2162,6 +2198,7 @@ bool SPIRVInstructionSelector::selectBuildVector(Register ResVReg,
report_fatal_error(
"There must be at least two constituent operands in a vector");
+ MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
TII.get(IsConst ? SPIRV::OpConstantComposite
: SPIRV::OpCompositeConstruct))
@@ -2195,6 +2232,7 @@ bool SPIRVInstructionSelector::selectSplatVector(Register ResVReg,
report_fatal_error(
"There must be at least two constituent operands in a vector");
+ MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
TII.get(IsConst ? SPIRV::OpConstantComposite
: SPIRV::OpCompositeConstruct))
@@ -2218,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();
@@ -2364,7 +2404,7 @@ bool SPIRVInstructionSelector::selectSelect(Register ResVReg,
bool IsScalarBool =
GR.isScalarOfType(I.getOperand(1).getReg(), SPIRV::OpTypeBool);
unsigned Opcode =
- IsScalarBool ? SPIRV::OpSelectSISCond : SPIRV::OpSelectSIVCond;
+ IsScalarBool ? SPIRV::OpSelectSISCond : SPIRV::OpSelectVIVCond;
return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
@@ -2402,17 +2442,8 @@ bool SPIRVInstructionSelector::selectExt(Register ResVReg,
return selectSelect(ResVReg, ResType, I, IsSigned);
SPIRVType *SrcType = GR.getSPIRVTypeForVReg(SrcReg);
- if (SrcType == ResType) {
- const TargetRegisterClass *DstRC = MRI->getRegClassOrNull(ResVReg);
- const TargetRegisterClass *SrcRC = MRI->getRegClassOrNull(SrcReg);
- if (DstRC != SrcRC && SrcRC)
- MRI->setRegClass(ResVReg, SrcRC);
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(TargetOpcode::COPY))
- .addDef(ResVReg)
- .addUse(SrcReg)
- .constrainAllUses(TII, TRI, RBI);
- }
+ if (SrcType == ResType)
+ return BuildCOPY(ResVReg, SrcReg, I);
unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
return selectUnOp(ResVReg, ResType, I, Opcode);
@@ -2512,17 +2543,8 @@ bool SPIRVInstructionSelector::selectTrunc(Register ResVReg,
const SPIRVType *ArgType = GR.getSPIRVTypeForVReg(IntReg);
if (GR.isScalarOrVectorOfType(ResVReg, SPIRV::OpTypeBool))
return selectIntToBool(IntReg, ResVReg, I, ArgType, ResType);
- if (ArgType == ResType) {
- const TargetRegisterClass *DstRC = MRI->getRegClassOrNull(ResVReg);
- const TargetRegisterClass *SrcRC = MRI->getRegClassOrNull(IntReg);
- if (DstRC != SrcRC && SrcRC)
- MRI->setRegClass(ResVReg, SrcRC);
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(TargetOpcode::COPY))
- .addDef(ResVReg)
- .addUse(IntReg)
- .constrainAllUses(TII, TRI, RBI);
- }
+ if (ArgType == ResType)
+ return BuildCOPY(ResVReg, IntReg, I);
bool IsSigned = GR.isScalarOrVectorSigned(ResType);
unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
return selectUnOp(ResVReg, ResType, I, Opcode);
@@ -2544,12 +2566,7 @@ bool SPIRVInstructionSelector::selectConst(Register ResVReg,
if (TyOpcode == SPIRV::OpTypeInt) {
assert(Imm.getBitWidth() <= 64 && "Unsupported integer width!");
Register Reg = GR.getOrCreateConstInt(Imm.getZExtValue(), I, ResType, TII);
- if (Reg == ResVReg)
- return true;
- return BuildMI(BB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY))
- .addDef(ResVReg)
- .addUse(Reg)
- .constrainAllUses(TII, TRI, RBI);
+ return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
}
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
.addDef(ResVReg)
@@ -2701,7 +2718,7 @@ bool SPIRVInstructionSelector::wrapIntoSpecConstantOp(
continue;
}
// Create a new register for the wrapper
- WrapReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
+ WrapReg = MRI->createVirtualRegister(GR.getRegClass(OpType));
GR.add(OpDefine, MF, WrapReg);
CompositeArgs.push_back(WrapReg);
// Decorate the wrapper register and generate a new instruction
@@ -2766,6 +2783,7 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
if (!wrapIntoSpecConstantOp(I, CompositeArgs))
return false;
}
+ MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType));
@@ -2845,13 +2863,24 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
.addUse(I.getOperand(2).getReg())
.constrainAllUses(TII, TRI, RBI);
else
- return BuildMI(BB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
- ResVReg)
- .addUse(I.getOperand(2).getReg())
- .constrainAllUses(TII, TRI, RBI);
+ return BuildCOPY(ResVReg, I.getOperand(2).getReg(), I);
break;
case Intrinsic::spv_thread_id:
- return selectSpvThreadId(ResVReg, ResType, I);
+ // The HLSL SV_DispatchThreadID semantic is lowered to llvm.spv.thread.id
+ // intrinsic in LLVM IR for SPIR-V backend.
+ //
+ // In SPIR-V backend, llvm.spv.thread.id is now correctly translated to a
+ // `GlobalInvocationId` builtin variable
+ return loadVec3BuiltinInputID(SPIRV::BuiltIn::GlobalInvocationId, ResVReg,
+ ResType, I);
+ case Intrinsic::spv_thread_id_in_group:
+ // The HLSL SV_GroupThreadId semantic is lowered to
+ // llvm.spv.thread.id.in.group intrinsic in LLVM IR for SPIR-V backend.
+ //
+ // In SPIR-V backend, llvm.spv.thread.id.in.group is now correctly
+ // translated to a `LocalInvocationId` builtin variable
+ return loadVec3BuiltinInputID(SPIRV::BuiltIn::LocalInvocationId, ResVReg,
+ ResType, I);
case Intrinsic::spv_fdot:
return selectFloatDot(ResVReg, ResType, I);
case Intrinsic::spv_udot:
@@ -2935,6 +2964,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
return selectExtInst(ResVReg, ResType, I, CL::s_clamp, GL::SClamp);
case Intrinsic::spv_wave_active_countbits:
return selectWaveActiveCountBits(ResVReg, ResType, I);
+ case Intrinsic::spv_wave_all:
+ return selectWaveOpInst(ResVReg, ResType, I, SPIRV::OpGroupNonUniformAll);
case Intrinsic::spv_wave_any:
return selectWaveOpInst(ResVReg, ResType, I, SPIRV::OpGroupNonUniformAny);
case Intrinsic::spv_wave_is_first_lane:
@@ -2956,14 +2987,14 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
// Discard internal intrinsics.
case Intrinsic::spv_value_md:
break;
- case Intrinsic::spv_handle_fromBinding: {
+ case Intrinsic::spv_resource_handlefrombinding: {
return selectHandleFromBinding(ResVReg, ResType, I);
}
- case Intrinsic::spv_typedBufferStore: {
+ case Intrinsic::spv_resource_store_typedbuffer: {
selectImageWriteIntrinsic(I);
return true;
}
- case Intrinsic::spv_typedBufferLoad: {
+ case Intrinsic::spv_resource_load_typedbuffer: {
selectReadImageIntrinsic(ResVReg, ResType, I);
return true;
}
@@ -3298,12 +3329,17 @@ bool SPIRVInstructionSelector::selectAllocaArray(Register ResVReg,
// there was an allocation size parameter to the allocation instruction
// that is not 1
MachineBasicBlock &BB = *I.getParent();
- return BuildMI(BB, I, I.getDebugLoc(),
- TII.get(SPIRV::OpVariableLengthArrayINTEL))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(2).getReg())
- .constrainAllUses(TII, TRI, RBI);
+ bool Res = BuildMI(BB, I, I.getDebugLoc(),
+ TII.get(SPIRV::OpVariableLengthArrayINTEL))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(2).getReg())
+ .constrainAllUses(TII, TRI, RBI);
+ if (!STI.isVulkanEnv()) {
+ unsigned Alignment = I.getOperand(3).getImm();
+ buildOpDecorate(ResVReg, I, TII, SPIRV::Decoration::Alignment, {Alignment});
+ }
+ return Res;
}
bool SPIRVInstructionSelector::selectFrameIndex(Register ResVReg,
@@ -3312,12 +3348,18 @@ bool SPIRVInstructionSelector::selectFrameIndex(Register ResVReg,
// Change order of instructions if needed: all OpVariable instructions in a
// function must be the first instructions in the first block
auto It = getOpVariableMBBIt(I);
- return BuildMI(*It->getParent(), It, It->getDebugLoc(),
- TII.get(SPIRV::OpVariable))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function))
- .constrainAllUses(TII, TRI, RBI);
+ bool Res = BuildMI(*It->getParent(), It, It->getDebugLoc(),
+ TII.get(SPIRV::OpVariable))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function))
+ .constrainAllUses(TII, TRI, RBI);
+ if (!STI.isVulkanEnv()) {
+ unsigned Alignment = I.getOperand(2).getImm();
+ buildOpDecorate(ResVReg, *It, TII, SPIRV::Decoration::Alignment,
+ {Alignment});
+ }
+ return Res;
}
bool SPIRVInstructionSelector::selectBranch(MachineInstr &I) const {
@@ -3377,7 +3419,10 @@ bool SPIRVInstructionSelector::selectPhi(Register ResVReg,
MIB.addUse(I.getOperand(i + 0).getReg());
MIB.addMBB(I.getOperand(i + 1).getMBB());
}
- return MIB.constrainAllUses(TII, TRI, RBI);
+ bool Res = MIB.constrainAllUses(TII, TRI, RBI);
+ MIB->setDesc(TII.get(TargetOpcode::PHI));
+ MIB->removeOperand(1);
+ return Res;
}
bool SPIRVInstructionSelector::selectGlobalValue(
@@ -3456,10 +3501,7 @@ bool SPIRVInstructionSelector::selectGlobalValue(
.constrainAllUses(TII, TRI, RBI);
}
assert(NewReg != ResVReg);
- return BuildMI(BB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY))
- .addDef(ResVReg)
- .addUse(NewReg)
- .constrainAllUses(TII, TRI, RBI);
+ return BuildCOPY(ResVReg, NewReg, I);
}
auto GlobalVar = cast<GlobalVariable>(GV);
assert(GlobalVar->getName() != "llvm.global.annotations");
@@ -3540,13 +3582,12 @@ bool SPIRVInstructionSelector::selectLog10(Register ResVReg,
.constrainAllUses(TII, TRI, RBI);
}
-bool SPIRVInstructionSelector::selectSpvThreadId(Register ResVReg,
- const SPIRVType *ResType,
- MachineInstr &I) const {
- // DX intrinsic: @llvm.dx.thread.id(i32)
- // ID Name Description
- // 93 ThreadId reads the thread ID
-
+// Generate the instructions to load 3-element vector builtin input
+// IDs/Indices.
+// Like: GlobalInvocationId, LocalInvocationId, etc....
+bool SPIRVInstructionSelector::loadVec3BuiltinInputID(
+ SPIRV::BuiltIn::BuiltIn BuiltInValue, Register ResVReg,
+ const SPIRVType *ResType, MachineInstr &I) const {
MachineIRBuilder MIRBuilder(I);
const SPIRVType *U32Type = GR.getOrCreateSPIRVIntegerType(32, MIRBuilder);
const SPIRVType *Vec3Ty =
@@ -3554,16 +3595,16 @@ bool SPIRVInstructionSelector::selectSpvThreadId(Register ResVReg,
const SPIRVType *PtrType = GR.getOrCreateSPIRVPointerType(
Vec3Ty, MIRBuilder, SPIRV::StorageClass::Input);
- // Create new register for GlobalInvocationID builtin variable.
+ // Create new register for the input ID builtin variable.
Register NewRegister =
MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
MIRBuilder.getMRI()->setType(NewRegister, LLT::pointer(0, 64));
GR.assignSPIRVTypeToVReg(PtrType, NewRegister, MIRBuilder.getMF());
- // Build GlobalInvocationID global variable with the necessary decorations.
+ // Build global variable with the necessary decorations for the input ID
+ // builtin variable.
Register Variable = GR.buildGlobalVariable(
- NewRegister, PtrType,
- getLinkStringForBuiltIn(SPIRV::BuiltIn::GlobalInvocationId), nullptr,
+ NewRegister, PtrType, getLinkStringForBuiltIn(BuiltInValue), nullptr,
SPIRV::StorageClass::Input, nullptr, true, true,
SPIRV::LinkageType::Import, MIRBuilder, false);
@@ -3580,12 +3621,12 @@ bool SPIRVInstructionSelector::selectSpvThreadId(Register ResVReg,
.addUse(GR.getSPIRVTypeID(Vec3Ty))
.addUse(Variable);
- // Get Thread ID index. Expecting operand is a constant immediate value,
+ // Get the input ID index. Expecting operand is a constant immediate value,
// wrapped in a type assignment.
assert(I.getOperand(2).isReg());
const uint32_t ThreadId = foldImm(I.getOperand(2), MRI);
- // Extract the thread ID from the loaded vector value.
+ // Extract the input ID from the loaded vector value.
MachineBasicBlock &BB = *I.getParent();
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract))
.addDef(ResVReg)