diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -64,6 +64,7 @@ case OverloadKind::VOID: case OverloadKind::ObjectType: case OverloadKind::UserDefineType: + default: llvm_unreachable("invalid overload type for name"); return "void"; } @@ -233,9 +234,11 @@ static bool lowerIntrinsics(Module &M) { bool Updated = false; - static SmallDenseMap LowerMap = { - {Intrinsic::sin, DXIL::OpCode::Sin}, - {Intrinsic::umax, DXIL::OpCode::UMax}}; + +#define DXIL_OP_INTRINSIC_MAP +#include "DXILOperation.inc" +#undef DXIL_OP_INTRINSIC_MAP + for (Function &F : make_early_inc_range(M.functions())) { if (!F.isDeclaration()) continue; diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp --- a/llvm/utils/TableGen/DXILEmitter.cpp +++ b/llvm/utils/TableGen/DXILEmitter.cpp @@ -59,8 +59,10 @@ SmallVector Params; // the operands that this instruction takes StringRef OverloadTypes; // overload types if applicable StringRef FnAttr; // attribute shorthands: rn=does not access - // memory,ro=only reads from memory, - bool IsDeriv; // whether this is some kind of derivative + // memory,ro=only reads from memory + StringRef Intrinsic; // The llvm intrinsic map to DXILOp. Default is "" which + // means no map exist + bool IsDeriv; // whether this is some kind of derivative bool IsGradient; // whether this requires a gradient calculation bool IsFeedback; // whether this is a sampler feedback op bool IsWave; // whether this requires in-wave, cross-lane functionality @@ -79,7 +81,15 @@ DXILClass = R->getValueAsDef("op_class")->getValueAsString("name"); Category = R->getValueAsDef("category")->getValueAsString("name"); + if (R->getValue("llvm_intrinsic")) { + auto *IntrinsicDef = R->getValueAsDef("llvm_intrinsic"); + auto DefName = IntrinsicDef->getName(); + // Remove the int_ from intrinsic name. + Intrinsic = DefName.substr(4); + } + Doc = R->getValueAsString("doc"); + ListInit *ParamList = R->getValueAsListInit("ops"); for (unsigned i = 0; i < ParamList->size(); ++i) { Record *Param = ParamList->getElementAsRecord(i); @@ -179,6 +189,23 @@ OS << "\n};\n\n"; } +// Emit map from llvm intrinsic to DXIL operation. +static void EmitDXILIntrinsicMap(std::vector &DXILOps, + raw_ostream &OS) { + OS << "\n"; + OS << "static const SmallDenseMap LowerMap = " + "{\n"; + for (auto &DXILOp : DXILOps) { + if (DXILOp.Intrinsic.empty()) + continue; + // {Intrinsic::sin, DXIL::OpCode::Sin}, + OS << " { Intrinsic::" << DXILOp.Intrinsic + << ", DXIL::OpCode::" << DXILOp.DXILOp << "},\n"; + } + OS << "};\n"; + OS << "\n"; +} + namespace llvm { void EmitDXILOperation(RecordKeeper &Records, raw_ostream &OS) { @@ -196,6 +223,11 @@ emitDXILEnums(DXILOps, OS); OS << "#endif\n\n"; + OS << "#ifdef DXIL_OP_INTRINSIC_MAP\n"; + EmitDXILIntrinsicMap(DXILOps, OS); + OS << "#endif\n\n"; + + OS << "\n"; }