@@ -33,6 +33,11 @@ using namespace llvm::dxil;
3333
3434namespace {
3535
36+ struct DXILIntrinsicSelect {
37+ StringRef Intrinsic;
38+ SmallVector<StringRef, 4 > ExtraArgs;
39+ };
40+
3641struct DXILOperationDesc {
3742 std::string OpName; // name of DXIL operation
3843 int OpCode; // ID of DXIL operation
@@ -43,8 +48,7 @@ struct DXILOperationDesc {
4348 SmallVector<const Record *> OverloadRecs;
4449 SmallVector<const Record *> StageRecs;
4550 SmallVector<const Record *> AttrRecs;
46- StringRef Intrinsic; // The llvm intrinsic map to OpName. Default is "" which
47- // means no map exists
51+ SmallVector<DXILIntrinsicSelect> IntrinsicSelects;
4852 SmallVector<StringRef, 4 >
4953 ShaderStages; // shader stages to which this applies, empty for all.
5054 int OverloadParamIndex; // Index of parameter with overload type.
@@ -158,14 +162,43 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
158162 OpName);
159163 }
160164
161- const RecordVal *RV = R->getValue (" LLVMIntrinsic" );
162- if (RV && RV->getValue ()) {
163- if (DefInit *DI = dyn_cast<DefInit>(RV->getValue ())) {
164- auto *IntrinsicDef = DI->getDef ();
165- auto DefName = IntrinsicDef->getName ();
166- assert (DefName.starts_with (" int_" ) && " invalid intrinsic name" );
167- // Remove the int_ from intrinsic name.
168- Intrinsic = DefName.substr (4 );
165+ auto GetIntrinsicName = [](const RecordVal *RV) -> StringRef {
166+ if (RV && RV->getValue ()) {
167+ if (DefInit *DI = dyn_cast<DefInit>(RV->getValue ())) {
168+ auto *IntrinsicDef = DI->getDef ();
169+ auto DefName = IntrinsicDef->getName ();
170+ assert (DefName.starts_with (" int_" ) && " invalid intrinsic name" );
171+ // Remove the int_ from intrinsic name.
172+ return DefName.substr (4 );
173+ }
174+ }
175+ return " " ;
176+ };
177+
178+ {
179+ DXILIntrinsicSelect IntrSelect;
180+ IntrSelect.Intrinsic = GetIntrinsicName (R->getValue (" LLVMIntrinsic" ));
181+ if (IntrSelect.Intrinsic .size ())
182+ IntrinsicSelects.emplace_back (std::move (IntrSelect));
183+ }
184+
185+ Recs = R->getValueAsListOfDefs (" intrinsic_selects" );
186+ if (Recs.size ()) {
187+ if (IntrinsicSelects.size ()) {
188+ PrintFatalError (R,
189+ Twine (" LLVMIntrinsic and intrinsic_match cannot be both "
190+ " defined for DXIL operation - " ) +
191+ OpName);
192+ } else {
193+ for (const Record *R : Recs) {
194+ DXILIntrinsicSelect IntrSelect;
195+ IntrSelect.Intrinsic = GetIntrinsicName (R->getValue (" Intr" ));
196+ auto ExtraArgs = R->getValueAsListOfStrings (" ExtraArgs" );
197+ for (StringRef Arg : ExtraArgs) {
198+ IntrSelect.ExtraArgs .push_back (Arg);
199+ }
200+ IntrinsicSelects.emplace_back (std::move (IntrSelect));
201+ }
169202 }
170203 }
171204}
@@ -378,10 +411,17 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
378411 OS << " #ifdef DXIL_OP_INTRINSIC\n " ;
379412 OS << " \n " ;
380413 for (const auto &Op : Ops) {
381- if (Op.Intrinsic .empty ())
414+ if (Op.IntrinsicSelects .empty ()) {
382415 continue ;
383- OS << " DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
384- << " , Intrinsic::" << Op.Intrinsic << " )\n " ;
416+ }
417+ for (const DXILIntrinsicSelect &MappedIntr : Op.IntrinsicSelects ) {
418+ OS << " DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
419+ << " , Intrinsic::" << MappedIntr.Intrinsic << " , (ArrayRef<Value *> {" ;
420+ for (const StringRef &Arg : MappedIntr.ExtraArgs ) {
421+ OS << Arg << " , " ;
422+ }
423+ OS << " }))\n " ;
424+ }
385425 }
386426 OS << " \n " ;
387427 OS << " #undef DXIL_OP_INTRINSIC\n " ;
0 commit comments