[llvm] [DXIL] Add constraint specification and backend implementation of DXIL Ops (PR #97593)

Xiang Li via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 11 08:11:52 PDT 2024


================
@@ -249,17 +228,102 @@ static FunctionType *getDXILOpFunctionType(const OpCodeProperty *Prop,
       ArgTys[0], ArrayRef<Type *>(&ArgTys[1], ArgTys.size() - 1), false);
 }
 
+static int getValidConstraintIndex(const OpCodeProperty *Prop,
+                                   const VersionTuple SMVer) {
+  // std::vector Prop->Constraints is in ascending order of SM Version
+  // Overloads of highest SM version that is not greater than SMVer
+  // are the ones that are valid for SMVer.
+  auto Size = Prop->Constraints.size();
+  for (int I = Size - 1; I >= 0; I--) {
+    auto OL = Prop->Constraints[I];
+    if (VersionTuple(OL.ShaderModelVer.Major, OL.ShaderModelVer.Minor) <=
+        SMVer) {
+      return I;
+    }
+  }
+  report_fatal_error(
+      StringRef(SMVer.getAsString().append(": Unknown Shader Model Version")),
+      /*gen_crash_diag*/ false);
+
+  return -1;
+}
+
 namespace llvm {
 namespace dxil {
 
 CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode, Type *ReturnTy,
                                           Type *OverloadTy,
                                           SmallVector<Value *> Args) {
+
+  std::string TTStr = M.getTargetTriple();
+  // No extra checks need be performed to verify that the Triple is
+  // well-formed or 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.
+  auto Major = Triple(TTStr).getOSVersion().getMajor();
+  auto MinorOrErr = Triple(TTStr).getOSVersion().getMinor();
+  uint32_t Minor = MinorOrErr.has_value() ? *MinorOrErr : 0;
+  VersionTuple SMVer(Major, Minor);
+  // Get Shader Stage Kind
+  Triple::EnvironmentType ShaderEnv = Triple(TTStr).getEnvironment();
+  auto ShaderEnvStr = Triple(TTStr).getEnvironmentName();
+
   const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
+  int Index = getValidConstraintIndex(Prop, SMVer);
+  uint16_t ValidTyMask = Prop->Constraints[Index].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(
+        StringRef(std::string("Invalid Overload Type for DXIL operation - ")
+                      .append(getOpCodeName((OpCode)))),
+        /* gen_crash_diag=*/false);
+  }
+
+  // Ensure Environment type is known
+  if (ShaderEnv == Triple::UnknownEnvironment) {
+    report_fatal_error(
+        StringRef(SMVer.getAsString().append(
----------------
python3kgae wrote:

This error could simply check the target triple once instead of checking it every time when building DXIL operations.

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


More information about the llvm-commits mailing list