)]}'
{
  "commit": "556c7ca95c6a309278c6cee98129d573827a05b4",
  "tree": "9316130adfb048792ae73176eea8b1574d048d1d",
  "parents": [
    "42956b77fea93fb1e1824d20169f174419e9845d"
  ],
  "author": {
    "name": "Diego Novillo",
    "email": "dnovillo@nvidia.com",
    "time": "Tue Mar 24 17:57:43 2026 -0400"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Tue Mar 24 17:57:43 2026 -0400"
  },
  "message": "spirv-dis: Add --handle-unknown-opcodes flag (#6604)\n\nThis addresses a frequent issue we have when working with new\nextensions/instructions in SPIR-V. Often, the assembler/disassembler\nwill not understand the new opcodes, so running `spirv-dis` on such a\nmodule just errors out.\n\nIn #6024 Cassie added support for `OpUnknown` to the assembler, so if\n`spirv-dis` were to emit `OpUnknown` when it finds an instruction it\ndoesn\u0027t know, we would be able to get a textual representation that can\nbe re-assembled even when there are unknown instructions. The main use\nI\u0027m thinking of here is testing. When calling `spirv-dis\n--handle-unknown-opcodes`:\n\n- Unknown opcodes: the instruction words are consumed raw and the\ninstruction is passed to the callback.\n- Unknown extended instruction numbers in semantic sets: parsing\ncontinues by treating the remaining operands as\n`SPV_OPERAND_TYPE_VARIABLE_ID`.\n- Known opcodes with unknown enum operands (`StorageClass`,\n`Capability`, `FunctionControl`, `MemoryAccess`, etc.): re-emits the\ninstruction as raw data.\n\nIn all three cases the disassembler emits:\n\n```\n  OpUnknown(\u003copcode\u003e, \u003cword_count\u003e) \u003cword[1]\u003e ... \u003cword[n]\u003e\n```\n\nAdded several tests to validate that it is possible to round-trip a\nSPIR-V module containing new instructions that the assembler still does\nnot understand.\n\nThere is one limitation that is possible to fix, but it is not a big\ndeal in the use case I\u0027m considering. When the disassembler emits\n`OpUnknown` operand words as bare decimal integers, the assembler does\nnot track those integers as ID definitions. If an unknown instruction\ndefines a result ID that is larger than every ID in the rest of the\nmodule, the reassembled module\u0027s ID bound will be too low.\n\nThis is not a concern for round-trips that do not involve validation.\nThe instruction words in the reassembled binary are byte-for-byte\nidentical to the original and only the module header ID bound field may\nbe wrong. Tools that do not validate the header are unaffected.\n\nOne way to fix this would be for the disassembler to emit all\n`OpUnknown` operands as ID references instead of bare decimal integers.\nThe issue is that words which are plain integer immediates (not IDs)\nwould also be treated as ID references, causing the reassembled module\u0027s\nID bound to be larger than necessary. This would be harmless, I think.\n\nThe real problem is with string operands.\n`SPV_OPERAND_TYPE_OPTIONAL_CIV` also accepts string literals, and a\nmulti-word string packed into `uint32_t` words must be emitted as a\nquoted string token, not as `%N`. Without grammar, the disassembler\ncannot tell which words start a string. String operands are not common,\nso this may not be a big issue.",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "9ee86ea7b963d2a149fdacc2e9ce4788ef52259d",
      "old_mode": 33188,
      "old_path": "include/spirv-tools/libspirv.h",
      "new_id": "28fd916534a8a64bcbb2d0e146de15743c741223",
      "new_mode": 33188,
      "new_path": "include/spirv-tools/libspirv.h"
    },
    {
      "type": "modify",
      "old_id": "0cad8b522087f2de940f4415b7480d4816d1df2f",
      "old_mode": 33188,
      "old_path": "source/binary.cpp",
      "new_id": "01ab65cf560ec56725d0d5d1f47db88d882ac49b",
      "new_mode": 33188,
      "new_path": "source/binary.cpp"
    },
    {
      "type": "modify",
      "old_id": "eb3beacac34bad16bcb88d39d02389cbe210eb9c",
      "old_mode": 33188,
      "old_path": "source/binary.h",
      "new_id": "7dbb9a8229a7412ee47c1e6def3be1de59ec3d0c",
      "new_mode": 33188,
      "new_path": "source/binary.h"
    },
    {
      "type": "modify",
      "old_id": "43db1daa2916d004676ceacaa5549820ad44b46a",
      "old_mode": 33188,
      "old_path": "source/disassemble.cpp",
      "new_id": "b85958ee94ec7cd0f5bcb9d7459099b4e7a28bd9",
      "new_mode": 33188,
      "new_path": "source/disassemble.cpp"
    },
    {
      "type": "modify",
      "old_id": "08c37381f35417f553f7318945f1d804b18f5bee",
      "old_mode": 33188,
      "old_path": "source/disassemble.h",
      "new_id": "7165a04818b7ff369a8a1175995caa0b4641928a",
      "new_mode": 33188,
      "new_path": "source/disassemble.h"
    },
    {
      "type": "modify",
      "old_id": "5f869c4116a72fdbc93f4aee668e74fe6e72cb40",
      "old_mode": 33188,
      "old_path": "source/name_mapper.cpp",
      "new_id": "798c609b7757b590ae871a2376dc3e1c3339ef6d",
      "new_mode": 33188,
      "new_path": "source/name_mapper.cpp"
    },
    {
      "type": "modify",
      "old_id": "6902141b1987560ba77bb97c1246394c473eadee",
      "old_mode": 33188,
      "old_path": "source/name_mapper.h",
      "new_id": "106a0127bbce836804f63710e6c2f78169f411b4",
      "new_mode": 33188,
      "new_path": "source/name_mapper.h"
    },
    {
      "type": "modify",
      "old_id": "d7f60b50e1cba2b1be4d8db8659af2c05340ffa3",
      "old_mode": 33188,
      "old_path": "test/CMakeLists.txt",
      "new_id": "2627f9a76a7b55f9ca61ae9ad0bab94c3cb395f6",
      "new_mode": 33188,
      "new_path": "test/CMakeLists.txt"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "eaf00ff26c9d883662b350f0267dc515c2070dfe",
      "new_mode": 33188,
      "new_path": "test/handle_unknown_opcodes_test.cpp"
    },
    {
      "type": "modify",
      "old_id": "c294d039ce3636ed6d2e4a45478da54e95fb7632",
      "old_mode": 33188,
      "old_path": "tools/dis/dis.cpp",
      "new_id": "74cd03c8f504ec7c72683df8143c8166cec15db1",
      "new_mode": 33188,
      "new_path": "tools/dis/dis.cpp"
    }
  ]
}
