@@ -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};
@@ -3059,6 +3062,15 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
30593062 // builtin variable
30603063 return loadVec3BuiltinInputID (SPIRV::BuiltIn::WorkgroupId, ResVReg, ResType,
30613064 I);
3065+ case Intrinsic::spv_flattened_thread_id_in_group:
3066+ // The HLSL SV_GroupIndex semantic is lowered to
3067+ // llvm.spv.flattened.thread.id.in.group() intrinsic in LLVM IR for SPIR-V
3068+ // backend.
3069+ //
3070+ // In SPIR-V backend, llvm.spv.flattened.thread.id.in.group is translated to
3071+ // a `LocalInvocationIndex` builtin variable
3072+ return loadBuiltinInputID (SPIRV::BuiltIn::LocalInvocationIndex, ResVReg,
3073+ ResType, I);
30623074 case Intrinsic::spv_fdot:
30633075 return selectFloatDot (ResVReg, ResType, I);
30643076 case Intrinsic::spv_udot:
@@ -4005,6 +4017,38 @@ bool SPIRVInstructionSelector::loadVec3BuiltinInputID(
40054017 return Result && MIB.constrainAllUses (TII, TRI, RBI);
40064018}
40074019
4020+ // Generate the instructions to load 32-bit integer builtin input IDs/Indices.
4021+ // Like LocalInvocationIndex
4022+ bool SPIRVInstructionSelector::loadBuiltinInputID (
4023+ SPIRV::BuiltIn::BuiltIn BuiltInValue, Register ResVReg,
4024+ const SPIRVType *ResType, MachineInstr &I) const {
4025+ MachineIRBuilder MIRBuilder (I);
4026+ const SPIRVType *U32Type = GR.getOrCreateSPIRVIntegerType (32 , MIRBuilder);
4027+ const SPIRVType *PtrType = GR.getOrCreateSPIRVPointerType (
4028+ U32Type, MIRBuilder, SPIRV::StorageClass::Input);
4029+
4030+ // Create new register for the input ID builtin variable.
4031+ Register NewRegister =
4032+ MIRBuilder.getMRI ()->createVirtualRegister (&SPIRV::iIDRegClass);
4033+ MIRBuilder.getMRI ()->setType (NewRegister, LLT::pointer (0 , 64 ));
4034+ GR.assignSPIRVTypeToVReg (PtrType, NewRegister, MIRBuilder.getMF ());
4035+
4036+ // Build global variable with the necessary decorations for the input ID
4037+ // builtin variable.
4038+ Register Variable = GR.buildGlobalVariable (
4039+ NewRegister, PtrType, getLinkStringForBuiltIn (BuiltInValue), nullptr ,
4040+ SPIRV::StorageClass::Input, nullptr , true , true ,
4041+ SPIRV::LinkageType::Import, MIRBuilder, false );
4042+
4043+ // Load uint value from the global variable.
4044+ auto MIB = BuildMI (*I.getParent (), I, I.getDebugLoc (), TII.get (SPIRV::OpLoad))
4045+ .addDef (ResVReg)
4046+ .addUse (GR.getSPIRVTypeID (U32Type))
4047+ .addUse (Variable);
4048+
4049+ return MIB.constrainAllUses (TII, TRI, RBI);
4050+ }
4051+
40084052SPIRVType *SPIRVInstructionSelector::widenTypeToVec4 (const SPIRVType *Type,
40094053 MachineInstr &I) const {
40104054 MachineIRBuilder MIRBuilder (I);
0 commit comments