diff --git a/docs/DXIL.rst b/docs/DXIL.rst
index 8871d3d8c9..68fe0882bc 100644
--- a/docs/DXIL.rst
+++ b/docs/DXIL.rst
@@ -2342,18 +2342,6 @@ ID Name Description
223 TextureGatherRaw Gather raw elements from 4 texels with no type conversions (SRV type is constrained)
224 SampleCmpLevel samples a texture and compares a single component against the specified comparison value
225 TextureStoreSample stores texel data at specified sample index
-226 Reserved0 reserved
-227 Reserved1 reserved
-228 Reserved2 reserved
-229 Reserved3 reserved
-230 Reserved4 reserved
-231 Reserved5 reserved
-232 Reserved6 reserved
-233 Reserved7 reserved
-234 Reserved8 reserved
-235 Reserved9 reserved
-236 Reserved10 reserved
-237 Reserved11 reserved
238 AllocateNodeOutputRecords returns a handle for the output records
239 GetNodeRecordPtr retrieve node input/output record pointer in address space 6
240 IncrementOutputCount Select the next logical output count for an EmptyNodeOutput for the whole group or per thread.
@@ -2375,9 +2363,6 @@ ID Name Description
256 StartVertexLocation returns the BaseVertexLocation from DrawIndexedInstanced or StartVertexLocation from DrawInstanced
257 StartInstanceLocation returns the StartInstanceLocation from Draw*Instanced
258 AllocateRayQuery2 allocates space for RayQuery and return handle
-259 ReservedA0 reserved
-260 ReservedA1 reserved
-261 ReservedA2 reserved
262 HitObject_TraceRay Analogous to TraceRay but without invoking CH/MS and returns the intermediate state as a HitObject
263 HitObject_FromRayQuery Creates a new HitObject representing a committed hit from a RayQuery
264 HitObject_FromRayQueryWithAttrs Creates a new HitObject representing a committed hit from a RayQuery and committed attributes
@@ -2406,19 +2391,6 @@ ID Name Description
287 HitObject_SetShaderTableIndex Returns a HitObject with updated shader table index
288 HitObject_LoadLocalRootTableConstant Returns the root table constant for this HitObject and offset
289 HitObject_Attributes Returns the attributes set for this HitObject
-290 ReservedB28 reserved
-291 ReservedB29 reserved
-292 ReservedB30 reserved
-293 ReservedC0 reserved
-294 ReservedC1 reserved
-295 ReservedC2 reserved
-296 ReservedC3 reserved
-297 ReservedC4 reserved
-298 ReservedC5 reserved
-299 ReservedC6 reserved
-300 ReservedC7 reserved
-301 ReservedC8 reserved
-302 ReservedC9 reserved
303 RawBufferVectorLoad reads from a raw buffer and structured buffer
304 RawBufferVectorStore writes to a RWByteAddressBuffer or RWStructuredBuffer
305 MatVecMul Multiplies a MxK dimension matrix and a K sized input vector
@@ -3095,9 +3067,6 @@ ID Name Description
2147483675 MatrixAccumulateToDescriptor accumulates a matrix to a RWByteAddressBuffer
2147483676 MatrixAccumulateToMemory accumulates a matrix to groupshared memory
2147483677 MatrixOuterProduct Outer products an M sized vector and a K sized vector producing an MxK matrix
-2147483678 LinAlgMatrixReserved0 reserved
-2147483679 LinAlgMatrixReserved1 reserved
-2147483680 LinAlgMatrixReserved2 reserved
2147483681 DebugBreak triggers a breakpoint if a debugger is attached
2147483682 IsDebuggerPresent returns true if a debugger is attached
========== ======================================== ===================================================================================================================
diff --git a/include/dxc/DXIL/DxilConstants.h b/include/dxc/DXIL/DxilConstants.h
index eb5f6ac1dd..d9c678b0d1 100644
--- a/include/dxc/DXIL/DxilConstants.h
+++ b/include/dxc/DXIL/DxilConstants.h
@@ -511,11 +511,6 @@ namespace ExperimentalOps {
static const OpCodeTableID TableID = OpCodeTableID::ExperimentalOps;
// Enumeration for ExperimentalOps DXIL operations
enum class OpCode : unsigned {
- //
- LinAlgMatrixReserved0 = 30, // reserved
- LinAlgMatrixReserved1 = 31, // reserved
- LinAlgMatrixReserved2 = 32, // reserved
-
// Debugging
DebugBreak = 33, // triggers a breakpoint if a debugger is attached
IsDebuggerPresent = 34, // returns true if a debugger is attached
@@ -584,6 +579,9 @@ enum class OpCode : unsigned {
HitObject_TriangleObjectPosition =
10, // returns triangle vertices in object space as <9 x float>
+ // Reserved values:
+ // 30, 31, 32
+
NumOpCodes = 35, // exclusive last value of enumeration
};
} // namespace ExperimentalOps
@@ -599,36 +597,6 @@ static const unsigned NumOpCodeTables = 2;
// OPCODE-ENUM:BEGIN
// Enumeration for CoreOps DXIL operations
enum class OpCode : unsigned {
- //
- Reserved0 = 226, // reserved
- Reserved1 = 227, // reserved
- Reserved10 = 236, // reserved
- Reserved11 = 237, // reserved
- Reserved2 = 228, // reserved
- Reserved3 = 229, // reserved
- Reserved4 = 230, // reserved
- Reserved5 = 231, // reserved
- Reserved6 = 232, // reserved
- Reserved7 = 233, // reserved
- Reserved8 = 234, // reserved
- Reserved9 = 235, // reserved
- ReservedA0 = 259, // reserved
- ReservedA1 = 260, // reserved
- ReservedA2 = 261, // reserved
- ReservedB28 = 290, // reserved
- ReservedB29 = 291, // reserved
- ReservedB30 = 292, // reserved
- ReservedC0 = 293, // reserved
- ReservedC1 = 294, // reserved
- ReservedC2 = 295, // reserved
- ReservedC3 = 296, // reserved
- ReservedC4 = 297, // reserved
- ReservedC5 = 298, // reserved
- ReservedC6 = 299, // reserved
- ReservedC7 = 300, // reserved
- ReservedC8 = 301, // reserved
- ReservedC9 = 302, // reserved
-
// Amplification shader instructions
DispatchMesh = 173, // Amplification shader intrinsic DispatchMesh
@@ -1182,6 +1150,10 @@ enum class OpCode : unsigned {
OutputComplete =
241, // indicates all outputs for a given records are complete
+ // Reserved values:
+ // 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 259, 260, 261,
+ // 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302
+
NumOpCodes_Dxil_1_0 = 137,
NumOpCodes_Dxil_1_1 = 139,
NumOpCodes_Dxil_1_2 = 141,
@@ -1322,12 +1294,6 @@ enum class OpCode : unsigned {
EXP_OPCODE(ExperimentalOps,
MatrixOuterProduct), // Outer products an M sized vector and a K
// sized vector producing an MxK matrix
- // LinAlgMatrixReserved0 = 0x8000001E, 2147483678U, -2147483618
- EXP_OPCODE(ExperimentalOps, LinAlgMatrixReserved0), // reserved
- // LinAlgMatrixReserved1 = 0x8000001F, 2147483679U, -2147483617
- EXP_OPCODE(ExperimentalOps, LinAlgMatrixReserved1), // reserved
- // LinAlgMatrixReserved2 = 0x80000020, 2147483680U, -2147483616
- EXP_OPCODE(ExperimentalOps, LinAlgMatrixReserved2), // reserved
// DebugBreak = 0x80000021, 2147483681U, -2147483615
EXP_OPCODE(ExperimentalOps,
DebugBreak), // triggers a breakpoint if a debugger is attached
diff --git a/include/dxc/DXIL/DxilOperations.h b/include/dxc/DXIL/DxilOperations.h
index fabf07ee14..453315bb06 100644
--- a/include/dxc/DXIL/DxilOperations.h
+++ b/include/dxc/DXIL/DxilOperations.h
@@ -275,6 +275,7 @@ class OP {
unsigned *OptTableIndex = nullptr);
static bool IsValidOpCode(unsigned EncodedOpCode);
static bool IsValidOpCode(OpCode EncodedOpCode);
+ static bool IsReservedOpCode(unsigned EncodedOpCode);
private:
// Static properties.
diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp
index eb5b2a2ceb..1026da8d21 100644
--- a/lib/DXIL/DxilOperations.cpp
+++ b/lib/DXIL/DxilOperations.cpp
@@ -34,6 +34,10 @@ using OCC = OP::OpCodeClass;
//
// OP class const-static data and related static methods.
//
+static const OP::OpCodeProperty ReservedOpCodeProps = {
+ OC::Invalid, "Reserved", OCC::Reserved, "reserved", Attribute::None, 0,
+ {}, {}};
+
/*
import hctdb_instrhelp
*/
@@ -1994,104 +1998,19 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = {
Attribute::None,
1,
{{0x63}},
- {{0x0}}}, // Overloads: hfwi
-
- {OC::Reserved0,
- "Reserved0",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved1,
- "Reserved1",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved2,
- "Reserved2",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved3,
- "Reserved3",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved4,
- "Reserved4",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved5,
- "Reserved5",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved6,
- "Reserved6",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved7,
- "Reserved7",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved8,
- "Reserved8",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved9,
- "Reserved9",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved10,
- "Reserved10",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::Reserved11,
- "Reserved11",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
+ {{0x0}}}, // Overloads: hfwi
+ ReservedOpCodeProps, // Reserved: 0x000000E2
+ ReservedOpCodeProps, // Reserved: 0x000000E3
+ ReservedOpCodeProps, // Reserved: 0x000000E4
+ ReservedOpCodeProps, // Reserved: 0x000000E5
+ ReservedOpCodeProps, // Reserved: 0x000000E6
+ ReservedOpCodeProps, // Reserved: 0x000000E7
+ ReservedOpCodeProps, // Reserved: 0x000000E8
+ ReservedOpCodeProps, // Reserved: 0x000000E9
+ ReservedOpCodeProps, // Reserved: 0x000000EA
+ ReservedOpCodeProps, // Reserved: 0x000000EB
+ ReservedOpCodeProps, // Reserved: 0x000000EC
+ ReservedOpCodeProps, // Reserved: 0x000000ED
// Create/Annotate Node Handles
{OC::AllocateNodeOutputRecords,
@@ -2277,32 +2196,10 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = {
Attribute::None,
0,
{},
- {}}, // Overloads: v
-
- {OC::ReservedA0,
- "ReservedA0",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedA1,
- "ReservedA1",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedA2,
- "ReservedA2",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
+ {}}, // Overloads: v
+ ReservedOpCodeProps, // Reserved: 0x00000103
+ ReservedOpCodeProps, // Reserved: 0x00000104
+ ReservedOpCodeProps, // Reserved: 0x00000105
// Shader Execution Reordering
{OC::HitObject_TraceRay,
@@ -2528,112 +2425,20 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = {
Attribute::ArgMemOnly,
1,
{{0x100}},
- {{0x0}}}, // Overloads: u
-
- {OC::ReservedB28,
- "ReservedB28",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedB29,
- "ReservedB29",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedB30,
- "ReservedB30",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC0,
- "ReservedC0",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC1,
- "ReservedC1",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC2,
- "ReservedC2",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC3,
- "ReservedC3",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC4,
- "ReservedC4",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC5,
- "ReservedC5",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC6,
- "ReservedC6",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC7,
- "ReservedC7",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC8,
- "ReservedC8",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
- {OC::ReservedC9,
- "ReservedC9",
- OCC::Reserved,
- "reserved",
- Attribute::None,
- 0,
- {},
- {}}, // Overloads: v
+ {{0x0}}}, // Overloads: u
+ ReservedOpCodeProps, // Reserved: 0x00000122
+ ReservedOpCodeProps, // Reserved: 0x00000123
+ ReservedOpCodeProps, // Reserved: 0x00000124
+ ReservedOpCodeProps, // Reserved: 0x00000125
+ ReservedOpCodeProps, // Reserved: 0x00000126
+ ReservedOpCodeProps, // Reserved: 0x00000127
+ ReservedOpCodeProps, // Reserved: 0x00000128
+ ReservedOpCodeProps, // Reserved: 0x00000129
+ ReservedOpCodeProps, // Reserved: 0x0000012A
+ ReservedOpCodeProps, // Reserved: 0x0000012B
+ ReservedOpCodeProps, // Reserved: 0x0000012C
+ ReservedOpCodeProps, // Reserved: 0x0000012D
+ ReservedOpCodeProps, // Reserved: 0x0000012E
// Resources
{OC::RawBufferVectorLoad,
@@ -2975,32 +2780,10 @@ static const OP::OpCodeProperty ExperimentalOps_OpCodeProps[] = {
Attribute::None,
2,
{{0x400}, {0x400}},
- {{0x63}, {0x63}}}, // Overloads: = DXIL::NumOpCodeTables)
return false;
+ OP::OpCodeTable &Table = OP::g_OpCodeTables[TableIndex];
unsigned Op = (EncodedOpCode & 0xFFFF);
- if (Op >= OP::g_OpCodeTables[TableIndex].Count)
+ if (Op >= Table.Count)
return false;
TableID = (OP::OpCodeTableID)TID;
OpIndex = Op;
if (OptTableIndex)
*OptTableIndex = TableIndex;
- return true;
+ return Table.Table[Op].opCode != OP::OpCode::Invalid;
}
bool OP::DecodeOpCode(OpCode EncodedOpCode, OP::OpCodeTableID &TableID,
unsigned &OpIndex, unsigned *OptTableIndex) {
@@ -3092,6 +2876,19 @@ bool OP::IsValidOpCode(unsigned EncodedOpCode) {
bool OP::IsValidOpCode(OP::OpCode EncodedOpCode) {
return IsValidOpCode((unsigned)EncodedOpCode);
}
+bool OP::IsReservedOpCode(unsigned EncodedOpCode) {
+ if (EncodedOpCode == (unsigned)OP::OpCode::Invalid)
+ return false;
+ OP::OpCodeTableID TID = (OP::OpCodeTableID)(EncodedOpCode >> 16);
+ unsigned TableIndex = GetOpCodeTableIndex(TID);
+ if (TableIndex >= DXIL::NumOpCodeTables)
+ return false;
+ OP::OpCodeTable &Table = OP::g_OpCodeTables[TableIndex];
+ unsigned Op = (EncodedOpCode & 0xFFFF);
+ if (Op >= Table.Count)
+ return false;
+ return Table.Table[Op].opCodeClass == OP::OpCodeClass::Reserved;
+}
const OP::OpCodeProperty &OP::GetOpCodeProps(unsigned OriginalOpCode) {
OP::OpCodeTableID TID = OP::OpCodeTableID::CoreOps;
unsigned Op = 0;
@@ -3282,6 +3079,9 @@ bool OP::CheckOpCodeTable() {
const OP::OpCodeTable &Table = OP::g_OpCodeTables[TableIndex];
for (unsigned OpIndex = 0; OpIndex < Table.Count; OpIndex++) {
const OP::OpCodeProperty &Prop = Table.Table[OpIndex];
+ // Skip reserved opcodes, which must never be used.
+ if ((unsigned)Prop.opCode == (unsigned)OP::OpCode::Invalid)
+ continue;
OP::OpCodeTableID DecodedTID;
unsigned DecodedOpIndex;
unsigned DecodedTableIndex;
@@ -5936,56 +5736,6 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
A(pI32);
break;
- //
- case OpCode::Reserved0:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved1:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved2:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved3:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved4:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved5:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved6:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved7:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved8:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved9:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved10:
- A(pV);
- A(pI32);
- break;
- case OpCode::Reserved11:
- A(pV);
- A(pI32);
- break;
-
// Create/Annotate Node Handles
case OpCode::AllocateNodeOutputRecords:
A(pNodeRecordHandle);
@@ -6145,20 +5895,6 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
A(pI32);
break;
- //
- case OpCode::ReservedA0:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedA1:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedA2:
- A(pV);
- A(pI32);
- break;
-
// Shader Execution Reordering
case OpCode::HitObject_TraceRay:
A(pHit);
@@ -6339,60 +6075,6 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
A(udt);
break;
- //
- case OpCode::ReservedB28:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedB29:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedB30:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC0:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC1:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC2:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC3:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC4:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC5:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC6:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC7:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC8:
- A(pV);
- A(pI32);
- break;
- case OpCode::ReservedC9:
- A(pV);
- A(pI32);
- break;
-
// Resources
case OpCode::RawBufferVectorLoad:
RRT(pETy);
@@ -6690,20 +6372,6 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
EXT(1);
break;
- //
- case OpCode::LinAlgMatrixReserved0:
- A(pV);
- A(pI32);
- break;
- case OpCode::LinAlgMatrixReserved1:
- A(pV);
- A(pI32);
- break;
- case OpCode::LinAlgMatrixReserved2:
- A(pV);
- A(pI32);
- break;
-
// Debugging
case OpCode::DebugBreak:
A(pV);
@@ -6958,18 +6626,6 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
case OpCode::AnnotateHandle:
case OpCode::CreateHandleFromBinding:
case OpCode::CreateHandleFromHeap:
- case OpCode::Reserved0:
- case OpCode::Reserved1:
- case OpCode::Reserved2:
- case OpCode::Reserved3:
- case OpCode::Reserved4:
- case OpCode::Reserved5:
- case OpCode::Reserved6:
- case OpCode::Reserved7:
- case OpCode::Reserved8:
- case OpCode::Reserved9:
- case OpCode::Reserved10:
- case OpCode::Reserved11:
case OpCode::AllocateNodeOutputRecords:
case OpCode::IncrementOutputCount:
case OpCode::OutputComplete:
@@ -6986,28 +6642,12 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
case OpCode::NodeOutputIsValid:
case OpCode::GetRemainingRecursionLevels:
case OpCode::AllocateRayQuery2:
- case OpCode::ReservedA0:
- case OpCode::ReservedA1:
- case OpCode::ReservedA2:
case OpCode::HitObject_FromRayQuery:
case OpCode::HitObject_MakeMiss:
case OpCode::HitObject_MakeNop:
case OpCode::MaybeReorderThread:
case OpCode::HitObject_SetShaderTableIndex:
case OpCode::HitObject_LoadLocalRootTableConstant:
- case OpCode::ReservedB28:
- case OpCode::ReservedB29:
- case OpCode::ReservedB30:
- case OpCode::ReservedC0:
- case OpCode::ReservedC1:
- case OpCode::ReservedC2:
- case OpCode::ReservedC3:
- case OpCode::ReservedC4:
- case OpCode::ReservedC5:
- case OpCode::ReservedC6:
- case OpCode::ReservedC7:
- case OpCode::ReservedC8:
- case OpCode::ReservedC9:
case OpCode::ExperimentalNop:
case OpCode::GetGroupWaveIndex:
case OpCode::GetGroupWaveCount:
@@ -7025,9 +6665,6 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
case OpCode::MatrixAccumulate:
case OpCode::MatrixAccumulateToDescriptor:
case OpCode::MatrixAccumulateToMemory:
- case OpCode::LinAlgMatrixReserved0:
- case OpCode::LinAlgMatrixReserved1:
- case OpCode::LinAlgMatrixReserved2:
case OpCode::DebugBreak:
case OpCode::IsDebuggerPresent:
return Type::getVoidTy(Ctx);
diff --git a/lib/DxilValidation/DxilValidation.cpp b/lib/DxilValidation/DxilValidation.cpp
index 624d0b8dc6..7739c105d9 100644
--- a/lib/DxilValidation/DxilValidation.cpp
+++ b/lib/DxilValidation/DxilValidation.cpp
@@ -3293,10 +3293,13 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
OP::OpCodeTableID TableID;
unsigned OpIndex;
if (!OP::DecodeOpCode(Opcode, TableID, OpIndex)) {
+ std::string OpCodeStr = std::to_string(Opcode);
+ if (OP::IsReservedOpCode(Opcode))
+ OpCodeStr += " (reserved opcode)";
ValCtx.EmitInstrFormatError(
&I, ValidationRule::InstrIllegalDXILOpCode,
{std::to_string((unsigned)DXIL::OpCode::NumOpCodes),
- std::to_string(Opcode)});
+ OpCodeStr});
continue;
}
if (TableID != OP::OpCodeTableID::CoreOps &&
diff --git a/tools/clang/test/LitDXILValidation/reservedDXILOp.ll b/tools/clang/test/LitDXILValidation/reservedDXILOp.ll
new file mode 100644
index 0000000000..2c4b569f59
--- /dev/null
+++ b/tools/clang/test/LitDXILValidation/reservedDXILOp.ll
@@ -0,0 +1,39 @@
+; REQUIRES: dxil-1-10
+; RUN: not %dxv %s 2>&1 | FileCheck %s
+
+; Make sure that using a reserved DXIL opcode produces an appropriate error.
+
+; 302 is currently reserved. If it is ever assigned to a valid DXIL op,
+; this test should be updated to use a different reserved opcode.
+; See "Reserved values:" comment in main DXIL::OpCode definition in
+; DxilConstants.h for reserved opcodes.
+
+; CHECK: error: DXILOpCode must be [0..{{[0-9]+}}] or a supported experimental opcode. 302 (reserved opcode) specified.
+; CHECK: note: at 'call void @dx.op.reserved(i32 302)' in block '#0' of function 'main'.
+
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-ms-dx"
+
+define void @main() {
+ call void @dx.op.reserved(i32 302)
+ ret void
+}
+
+; Function Attrs: nounwind
+declare void @dx.op.reserved(i32) #0
+
+attributes #0 = { nounwind}
+
+!llvm.ident = !{!0}
+!dx.version = !{!1}
+!dx.valver = !{!1}
+!dx.shaderModel = !{!2}
+!dx.resources = !{!3}
+!dx.entryPoints = !{!4}
+
+!0 = !{!"hand-crafted"}
+!1 = !{i32 1, i32 10}
+!2 = !{!"vs", i32 6, i32 10}
+!3 = !{null, null, null, null}
+!4 = !{void ()* @main, !"main", !5, !3, null}
+!5 = !{null, null, null}
diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py
index dd03d00450..1a56396c78 100644
--- a/utils/hct/hctdb.py
+++ b/utils/hct/hctdb.py
@@ -70,6 +70,8 @@ def __init__(self, value, name, doc):
self.name = name # Name (identifier)
self.doc = doc # Documentation string
self.category = None
+ # reserved: whether value reserved and excluded from enum definition
+ self.reserved = False
class db_dxil_enum(object):
@@ -418,6 +420,15 @@ def __getitem__(self, idx):
def __iter__(self):
return iter(self.ops)
+ def get_dxil_ops(self, include_reserved=False):
+ "Get all DXIL operations; optionally include_reserved."
+ if include_reserved:
+ return iter(self.ops)
+ for i in self.ops:
+ if i.is_reserved:
+ continue
+ yield i
+
def set_op_count_for_version(self, major, minor):
op_count = len(self.ops)
self.op_enum.dxil_version_info[(major, minor)] = op_count
@@ -432,6 +443,7 @@ def add(self, i):
def add_dxil_op(
self, name, code_class, doc, oload_types, fn_attr, op_params, **props
):
+ "Add a new DXIL operation to this table; returns the new op."
# The return value is parameter 0, insert the opcode as 1.
op_params.insert(1, self.opcode_param)
i = db_dxil_inst(
@@ -450,14 +462,15 @@ def add_dxil_op(
i.props = props
return self.add(i)
- def add_dxil_op_reserved(self, name):
+ def add_dxil_op_reserved(self):
+ "Reserve a DXIL opcode for future use; returns the reserved op."
# The return value is parameter 0, insert the opcode as 1.
op_params = [db_dxil_param(0, "v", "", "reserved"), self.opcode_param]
i = db_dxil_inst(
- name,
+ "Reserved",
llvm_id=self.call_instr.llvm_id,
llvm_name=self.call_instr.llvm_name,
- dxil_op=name,
+ dxil_op="Reserved",
dxil_opid=self._next_id(),
dxil_table=self.name,
doc="reserved",
@@ -468,14 +481,9 @@ def add_dxil_op_reserved(self, name):
)
return self.add(i)
- def reserve_dxil_op_range(self, group_name, count, start_reserved_id=0):
- "Reserve a range of dxil opcodes for future use; returns next id"
- return [
- self.add_dxil_op_reserved(
- "{0}{1}".format(group_name, start_reserved_id + i)
- )
- for i in range(0, count)
- ]
+ def reserve_dxil_ops(self, count=1):
+ "Reserve dxil opcodes for future use; returns list of reserved ops."
+ return [self.add_dxil_op_reserved() for i in range(0, count)]
class db_dxil(object):
@@ -524,18 +532,22 @@ def get_llvm_insts(self):
for i in self._llvm_insts:
yield i
- def get_dxil_ops(self):
- "Get all DXIL operations."
+ def get_dxil_ops(self, include_reserved=False):
+ "Get all DXIL operations; optionally include_reserved."
for table in self.op_tables:
for i in table:
+ if not include_reserved and i.is_reserved:
+ continue
yield i
- def get_all_insts(self):
- "Get all instructions, including LLVM and DXIL operations."
+ def get_all_insts(self, include_reserved=False):
+ "Get all LLVM instructions and DXIL operations; optionally include_reserved."
for i in self._llvm_insts:
yield i
for table in self.op_tables:
for i in table:
+ if not include_reserved and i.is_reserved:
+ continue
yield i
def get_insts_by_names(self, *names):
@@ -596,8 +608,9 @@ def build_opcode_enum(self):
for i in table:
v = table.op_enum.add_value(i.dxil_op_index(), i.dxil_op, i.doc)
v.category = i.category
+ v.reserved = i.is_reserved
class_dict[i.dxil_class] = i.category
- if table != self.core_table:
+ if table != self.core_table and not i.is_reserved:
# // = 0x, U,
# Signed id is useful for comparing with IR opcodes, which
# are printed as signed i32 values.
@@ -1721,7 +1734,7 @@ def populate_CoreOps(self):
self.core_table = self.add_dxil_op_table(0, "CoreOps", "Core DXIL operations")
op_table = self.core_table
add_dxil_op = op_table.add_dxil_op
- reserve_dxil_op_range = op_table.reserve_dxil_op_range
+ reserve_dxil_ops = op_table.reserve_dxil_ops
set_op_count_for_version = op_table.set_op_count_for_version
# $o in a parameter type means the overload type
@@ -5136,8 +5149,7 @@ def UFI(name, **mappings):
% op_count
)
- # Reserved ops
- reserve_dxil_op_range("Reserved", 12)
+ reserve_dxil_ops(12)
# Work Graph
add_dxil_op(
@@ -5540,8 +5552,7 @@ def UFI(name, **mappings):
],
)
- # Reserved block A
- reserve_dxil_op_range("ReservedA", 3)
+ reserve_dxil_ops(3)
# Shader Execution Reordering
add_dxil_op(
@@ -5998,10 +6009,7 @@ def UFI(name, **mappings):
],
)
- reserve_dxil_op_range("ReservedB", 3, 28)
-
- # Reserved block C
- reserve_dxil_op_range("ReservedC", 10)
+ reserve_dxil_ops(13)
# Long Vectors
add_dxil_op(
@@ -6218,6 +6226,7 @@ def populate_ExperimentalOps(self):
0x8000, "ExperimentalOps", "Experimental DXIL operations"
)
add_dxil_op = op_table.add_dxil_op
+ reserve_dxil_ops = op_table.reserve_dxil_ops
retvoid_param = db_dxil_param(0, "v", "", "no return value")
@@ -6706,7 +6715,7 @@ def populate_ExperimentalOps(self):
],
)
- op_table.reserve_dxil_op_range("LinAlgMatrixReserved", 3)
+ reserve_dxil_ops(3)
# Debugging intrinsics
add_dxil_op(
@@ -9394,6 +9403,8 @@ def add_valrule_msg(self, name, desc, err_msg):
)
def add_inst(self, i):
+ if i.is_reserved:
+ return i
if i.name != "UDiv":
# These should not overlap, but UDiv is a known collision.
assert i.name not in self.name_idx, f"Duplicate instruction name: {i.name}"
diff --git a/utils/hct/hctdb_instrhelp.py b/utils/hct/hctdb_instrhelp.py
index 7e2f8b89d7..f238574562 100644
--- a/utils/hct/hctdb_instrhelp.py
+++ b/utils/hct/hctdb_instrhelp.py
@@ -426,10 +426,10 @@ def print_enum(self, e, **kwargs):
print("// %s" % e.doc)
print("enum class %s : unsigned {" % e.name)
hide_val = kwargs.get("hide_val", False)
- sorted_values = e.values
+ sorted_values = filter(lambda v: not v.reserved, e.values)
if kwargs.get("sort_val", True):
sorted_values = sorted(
- e.values,
+ sorted_values,
key=lambda v: ("" if v.category == None else v.category) + "." + v.name,
)
last_category = None
@@ -447,6 +447,12 @@ def print_enum(self, e, **kwargs):
if v.doc:
line_format += " // {doc}"
print(line_format.format(name=v.name, value=v.value, doc=v.doc))
+ # Print unnamed reserved values separately.
+ reserved_values = list(filter(lambda v: v.reserved, e.values))
+ if len(reserved_values) > 0:
+ print("")
+ print(" // Reserved values:")
+ print(" // " + ", ".join([str(v.value) for v in reserved_values]))
if e.last_value_name:
lastName = e.last_value_name
versioned = [
@@ -462,7 +468,7 @@ def print_enum(self, e, **kwargs):
" "
+ lastName
+ " = "
- + str(len(sorted_values))
+ + str(len(e.values))
+ ", // exclusive last value of enumeration"
)
if e.postfix_lines:
@@ -551,11 +557,13 @@ def print_opfunc_props_for_table(self, table):
"{" + ",".join(["{0x%x}" % m for m in oloads]) + "}"
)
for i in table:
+ if i.is_reserved:
+ print(f"ReservedOpCodeProps, // Reserved: 0x{i.dxil_opid:08X}")
+ continue
if last_category != i.category:
if last_category != None:
print("")
- if not i.is_reserved:
- print(f" // {i.category}")
+ print(f" // {i.category}")
last_category = i.category
scalar_masks = []
vector_masks = []
@@ -1415,7 +1423,7 @@ def get_opcodes_rst():
def get_opcodes_rst_for_table(table):
"Create an rst table of opcodes for given opcode table"
- instrs = [i for i in table]
+ instrs = [i for i in table.get_dxil_ops()]
rows = []
rows.append(["ID", "Name", "Description"])
for i in instrs: