@@ -549,6 +549,16 @@ static void addSPIRVBuiltinDecoration(llvm::GlobalVariable *GV,
549549 GV->addMetadata (" spirv.Decorations" , *Decoration);
550550}
551551
552+ static void addLocationDecoration (llvm::GlobalVariable *GV, unsigned Location) {
553+ LLVMContext &Ctx = GV->getContext ();
554+ IRBuilder<> B (GV->getContext ());
555+ MDNode *Operands =
556+ MDNode::get (Ctx, {ConstantAsMetadata::get (B.getInt32 (/* Location */ 30 )),
557+ ConstantAsMetadata::get (B.getInt32 (Location))});
558+ MDNode *Decoration = MDNode::get (Ctx, {Operands});
559+ GV->addMetadata (" spirv.Decorations" , *Decoration);
560+ }
561+
552562static llvm::Value *createSPIRVBuiltinLoad (IRBuilder<> &B, llvm::Module &M,
553563 llvm::Type *Ty, const Twine &Name,
554564 unsigned BuiltInID) {
@@ -562,6 +572,69 @@ static llvm::Value *createSPIRVBuiltinLoad(IRBuilder<> &B, llvm::Module &M,
562572 return B.CreateLoad (Ty, GV);
563573}
564574
575+ static llvm::Value *createSPIRVLocationLoad (IRBuilder<> &B, llvm::Module &M,
576+ llvm::Type *Ty, unsigned Location,
577+ StringRef Name) {
578+ auto *GV = new llvm::GlobalVariable (
579+ M, Ty, /* isConstant= */ true , llvm::GlobalValue::ExternalLinkage,
580+ /* Initializer= */ nullptr , /* Name= */ Name, /* insertBefore= */ nullptr ,
581+ llvm::GlobalVariable::GeneralDynamicTLSModel,
582+ /* AddressSpace */ 7 , /* isExternallyInitialized= */ true );
583+ GV->setVisibility (llvm::GlobalValue::HiddenVisibility);
584+ addLocationDecoration (GV, Location);
585+ return B.CreateLoad (Ty, GV);
586+ }
587+
588+ llvm::Value *
589+ CGHLSLRuntime::emitSPIRVUserSemanticLoad (llvm::IRBuilder<> &B, llvm::Type *Type,
590+ HLSLSemanticAttr *Semantic,
591+ std::optional<unsigned > Index) {
592+ Twine BaseName = Twine (Semantic->getAttrName ()->getName ());
593+ Twine VariableName = BaseName.concat (Twine (Index.value_or (0 )));
594+
595+ unsigned Location = SPIRVLastAssignedInputSemanticLocation;
596+
597+ // DXC completely ignores the semantic/index pair. Location are assigned from
598+ // the first semantic to the last.
599+ llvm::ArrayType *AT = dyn_cast<llvm::ArrayType>(Type);
600+ unsigned ElementCount = AT ? AT->getNumElements () : 1 ;
601+ SPIRVLastAssignedInputSemanticLocation += ElementCount;
602+ return createSPIRVLocationLoad (B, CGM.getModule (), Type, Location,
603+ VariableName.str ());
604+ }
605+
606+ llvm::Value *
607+ CGHLSLRuntime::emitDXILUserSemanticLoad (llvm::IRBuilder<> &B, llvm::Type *Type,
608+ HLSLSemanticAttr *Semantic,
609+ std::optional<unsigned > Index) {
610+ Twine BaseName = Twine (Semantic->getAttrName ()->getName ());
611+ Twine VariableName = BaseName.concat (Twine (Index.value_or (0 )));
612+
613+ // DXIL packing rules etc shall be handled here.
614+ // FIXME: generate proper sigpoint, index, col, row values.
615+ // FIXME: also DXIL loads vectors element by element.
616+ SmallVector<Value *> Args{B.getInt32 (4 ), B.getInt32 (0 ), B.getInt32 (0 ),
617+ B.getInt8 (0 ),
618+ llvm::PoisonValue::get (B.getInt32Ty ())};
619+
620+ llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::dx_load_input;
621+ llvm::Value *Value = B.CreateIntrinsic (/* ReturnType=*/ Type, IntrinsicID, Args,
622+ nullptr , VariableName);
623+ return Value;
624+ }
625+
626+ llvm::Value *CGHLSLRuntime::emitUserSemanticLoad (
627+ IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl,
628+ HLSLSemanticAttr *Semantic, std::optional<unsigned > Index) {
629+ if (CGM.getTarget ().getTriple ().isSPIRV ())
630+ return emitSPIRVUserSemanticLoad (B, Type, Semantic, Index);
631+
632+ if (CGM.getTarget ().getTriple ().isDXIL ())
633+ return emitDXILUserSemanticLoad (B, Type, Semantic, Index);
634+
635+ llvm_unreachable (" Unsupported target for user-semantic load." );
636+ }
637+
565638llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad (
566639 IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl,
567640 Attr *Semantic, std::optional<unsigned > Index) {
@@ -626,6 +699,9 @@ CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD,
626699 std::optional<unsigned > Index = std::nullopt ;
627700 if (Semantic->isSemanticIndexExplicit ())
628701 Index = Semantic->getSemanticIndex ();
702+
703+ if (isa<HLSLUserSemanticAttr>(Semantic))
704+ return emitUserSemanticLoad (B, Type, Decl, Semantic, Index);
629705 return emitSystemSemanticLoad (B, Type, Decl, Semantic, Index);
630706}
631707
0 commit comments