@@ -341,6 +341,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
341341 bool loadVec3BuiltinInputID (SPIRV::BuiltIn::BuiltIn BuiltInValue,
342342 Register ResVReg, const SPIRVType *ResType,
343343 MachineInstr &I) const ;
344+ bool loadBuiltinInputID (SPIRV::BuiltIn::BuiltIn BuiltInValue,
345+ Register ResVReg, const SPIRVType *ResType,
346+ MachineInstr &I) const ;
344347 bool loadHandleBeforePosition (Register &HandleReg, const SPIRVType *ResType,
345348 GIntrinsic &HandleDef, MachineInstr &Pos) const ;
346349};
@@ -3065,6 +3068,15 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
30653068 // builtin variable
30663069 return loadVec3BuiltinInputID (SPIRV::BuiltIn::WorkgroupId, ResVReg, ResType,
30673070 I);
3071+ case Intrinsic::spv_flattened_thread_id_in_group:
3072+ // The HLSL SV_GroupIndex semantic is lowered to
3073+ // llvm.spv.flattened.thread.id.in.group() intrinsic in LLVM IR for SPIR-V
3074+ // backend.
3075+ //
3076+ // In SPIR-V backend, llvm.spv.flattened.thread.id.in.group is translated to
3077+ // a `LocalInvocationIndex` builtin variable
3078+ return loadBuiltinInputID (SPIRV::BuiltIn::LocalInvocationIndex, ResVReg,
3079+ ResType, I);
30683080 case Intrinsic::spv_fdot:
30693081 return selectFloatDot (ResVReg, ResType, I);
30703082 case Intrinsic::spv_udot:
@@ -4011,6 +4023,40 @@ bool SPIRVInstructionSelector::loadVec3BuiltinInputID(
40114023 return Result && MIB.constrainAllUses (TII, TRI, RBI);
40124024}
40134025
4026+ // Generate the instructions to load 32-bit integer builtin input IDs/Indices.
4027+ // Like LocalInvocationIndex
4028+ bool SPIRVInstructionSelector::loadBuiltinInputID (
4029+ SPIRV::BuiltIn::BuiltIn BuiltInValue, Register ResVReg,
4030+ const SPIRVType *ResType, MachineInstr &I) const {
4031+ MachineIRBuilder MIRBuilder (I);
4032+ const SPIRVType *PtrType = GR.getOrCreateSPIRVPointerType (
4033+ ResType, MIRBuilder, SPIRV::StorageClass::Input);
4034+
4035+ // Create new register for the input ID builtin variable.
4036+ Register NewRegister =
4037+ MIRBuilder.getMRI ()->createVirtualRegister (GR.getRegClass (PtrType));
4038+ MIRBuilder.getMRI ()->setType (
4039+ NewRegister,
4040+ LLT::pointer (storageClassToAddressSpace (SPIRV::StorageClass::Input),
4041+ GR.getPointerSize ()));
4042+ GR.assignSPIRVTypeToVReg (PtrType, NewRegister, MIRBuilder.getMF ());
4043+
4044+ // Build global variable with the necessary decorations for the input ID
4045+ // builtin variable.
4046+ Register Variable = GR.buildGlobalVariable (
4047+ NewRegister, PtrType, getLinkStringForBuiltIn (BuiltInValue), nullptr ,
4048+ SPIRV::StorageClass::Input, nullptr , true , true ,
4049+ SPIRV::LinkageType::Import, MIRBuilder, false );
4050+
4051+ // Load uint value from the global variable.
4052+ auto MIB = BuildMI (*I.getParent (), I, I.getDebugLoc (), TII.get (SPIRV::OpLoad))
4053+ .addDef (ResVReg)
4054+ .addUse (GR.getSPIRVTypeID (ResType))
4055+ .addUse (Variable);
4056+
4057+ return MIB.constrainAllUses (TII, TRI, RBI);
4058+ }
4059+
40144060SPIRVType *SPIRVInstructionSelector::widenTypeToVec4 (const SPIRVType *Type,
40154061 MachineInstr &I) const {
40164062 MachineIRBuilder MIRBuilder (I);
0 commit comments