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