[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