[llvm] [DXIL] Add DXIL version-specific TableGen specification and implementation of DXIL Ops (PR #97593)

Chris B via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 26 14:30:10 PDT 2024


================
@@ -249,17 +309,95 @@ static FunctionType *getDXILOpFunctionType(const OpCodeProperty *Prop,
       ArgTys[0], ArrayRef<Type *>(&ArgTys[1], ArgTys.size() - 1), false);
 }
 
+/// Get index of the property from PropList valid for the most recent
+/// DXIL version not greater than DXILVer.
+/// PropList is expected to be sorted in ascending order of DXIL version.
+template <typename T>
+static int getPropIndex(const std::vector<T> PropList,
+                        const VersionTuple DXILVer) {
+  auto Size = PropList.size();
+  for (int I = Size - 1; I >= 0; I--) {
+    auto OL = PropList[I];
+    if (VersionTuple(OL.DXILVersion.Major, OL.DXILVersion.Minor) <= DXILVer) {
+      return I;
+    }
+  }
+  report_fatal_error(Twine(DXILVer.getAsString()) + ": Unknown DXIL Version",
+                     /*gen_crash_diag*/ false);
+
+  return -1;
+}
+
 namespace llvm {
 namespace dxil {
 
+// No extra checks on TargetTripleStr need be performed to verify that the
+// Triple is well-formed or that the target is supported since these checks
+// would have been done at the time the module M is constructed in the earlier
+// stages of compilation.
+DXILOpBuilder::DXILOpBuilder(Module &M, IRBuilderBase &B)
+    : M(M), B(B), TargetTripleStr(M.getTargetTriple()) {}
+
 CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode, Type *ReturnTy,
                                           Type *OverloadTy,
                                           SmallVector<Value *> Args) {
+
+  auto Major = Triple(TargetTripleStr).getDXILVersion().getMajor();
+  auto MinorOrErr = Triple(TargetTripleStr).getDXILVersion().getMinor();
+  uint32_t Minor = MinorOrErr.has_value() ? *MinorOrErr : 0;
+  VersionTuple DXILVer(Major, Minor);
+  // Get Shader Stage Kind
+  Triple::EnvironmentType ShaderEnv = Triple(TargetTripleStr).getEnvironment();
+
   const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
+  int OlIndex = getPropIndex(Prop->Overloads, DXILVer);
+  uint16_t ValidTyMask = Prop->Overloads[OlIndex].ValidTys;
 
   OverloadKind Kind = getOverloadKind(OverloadTy);
-  if ((Prop->OverloadTys & (uint16_t)Kind) == 0) {
-    report_fatal_error("Invalid Overload Type", /* gen_crash_diag=*/false);
+
+  // Check if the operation supports overload types and OverloadTy is valid
+  // per the specified types for the operation
+  if ((ValidTyMask != OverloadKind::UNDEFINED) &&
+      (ValidTyMask & (uint16_t)Kind) == 0) {
+    report_fatal_error(Twine("Invalid Overload Type for DXIL operation - ") +
+                           getOpCodeName(OpCode),
+                       /* gen_crash_diag=*/false);
+  }
+
+  // Ensure Environment type is known
+  if (ShaderEnv == Triple::UnknownEnvironment) {
+    report_fatal_error(
+        Twine(DXILVer.getAsString()) +
+            ": Unknown Compilation Target Shader Stage specified ",
+        /*gen_crash_diag*/ false);
+  }
+
+  // Perform necessary checks to ensure Opcode is valid in the targeted shader
+  // kind
+  int StIndex = getPropIndex(Prop->Stages, DXILVer);
+  uint16_t ValidShaderKindMask = Prop->Stages[StIndex].ValidStages;
+  enum ShaderKind ModuleStagekind = getShaderKindEnum(ShaderEnv);
----------------
llvm-beanz wrote:

```suggestion
  ShaderKind ModuleStagekind = getShaderKindEnum(ShaderEnv);
```

https://github.com/llvm/llvm-project/pull/97593


More information about the llvm-commits mailing list