Skip to content

Commit 4724809

Browse files
authored
Ensure generated getters of optional operands don't crash (#10019)
Some IR instructions have optional operands. The getters generated by Fiddle for those instructions did not consider the optionality, and attempt to fetch them regardless, triggering an assertion if called. This PR makes the generated getters behave like most of the hand-written getters with optional operands, by checking that the operand exists first. If it doesn't, `nullptr` is returned, which the caller is expected to handle. I don't think this can break existing code, as the previous behavior when fetching a non-existent optional operand was to simply crash. This is in preparation for a PR to implement shader-slang/spec#39, but is a separate issue, which is why I'm submitting this change in a separate PR. It's of particular importance there, as a new optional data layout operand is added, which is often queried with the Fiddle-generated getter in `IRPtrType`. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Changes to the Slang Shader Compiler This PR fixes a crash in the IR (Intermediate Representation) layer by making Fiddle-generated instruction accessor getters handle optional operands safely. ### Compiler Stages Affected - IR Stage (Primary): Changes are in the IR code generation and generated IR accessor implementations: - source/slang/slang-ir.h.lua — Fiddle code-generator: now propagates an `optional` flag into per-operand metadata and adjusts generation logic (including handling single-operand forms and simplifying the expression used when emitting getters). - source/slang/slang-ir-insts.h — generated IR instruction accessor getters: getter bodies now check whether an optional operand is present (index < operand count) and return nullptr when missing instead of asserting/crashing. No changes to lexer, parser, semantic analysis, or code generation stages. ### Backend Impact - No backend-specific source files were modified, but the IR accessors are used by all backends. This makes queries for optional operands safe across targets that inspect IR (SPIRV, HLSL, GLSL, Metal, CUDA, WGSL, etc.). The change prevents assertion failures when backends or other passes query absent optional operands and is preparatory for adding a frequently-queried optional data layout operand in a follow-up PR. ### Public API Impact - No public API headers were modified (include/slang.h, slang-com-helper.h were not changed). Function signatures of the generated getters were not changed; only their bodies/behavior were adjusted. ### Commits / Notable Implementation Details - Commit message: "Fix single-operand insts + more compact expression" — addresses single-operand instruction handling and simplifies the emitted getter expression. - The generator now marks operands with optional = true when appropriate and emits getter bodies that check operand existence (returning nullptr when missing), matching typical hand-written getters. ### Summary Fiddle's IR getter generation now respects optional operands, avoiding crashes when code queries absent optional operands and aligning generated getters with established hand-written behavior. This is a non-breaking internal change to IR accessor implementations. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 2942719 commit 4724809

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

source/slang/slang-ir-insts.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,10 +2960,18 @@ struct IR$(inst.struct_name) : IR$(inst.parent_struct)
29602960
}
29612961
% end
29622962
% for _, operand in ipairs(inst.operands) do
2963-
% if operand.has_type then
2964-
$(operand.type)* $(operand.getter_name)() { return ($(operand.type)*)getOperand($(operand.index)); }
2963+
% if operand.optional then
2964+
% if operand.has_type then
2965+
$(operand.type)* $(operand.getter_name)() { return getOperandCount() > $(operand.index) ? ($(operand.type)*)getOperand($(operand.index)) : nullptr; }
2966+
% else
2967+
IRInst* $(operand.getter_name)() { return getOperandCount() > $(operand.index) ? getOperand($(operand.index)) : nullptr; }
2968+
% end
29652969
% else
2970+
% if operand.has_type then
2971+
$(operand.type)* $(operand.getter_name)() { return ($(operand.type)*)getOperand($(operand.index)); }
2972+
% else
29662973
IRInst* $(operand.getter_name)() { return getOperand($(operand.index)); }
2974+
% end
29672975
% end
29682976
% end
29692977
};

source/slang/slang-ir.h.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ local function getAllOtherInstStructsData()
177177
getter_name = "get" .. operandName:sub(1, 1):upper() .. operandName:sub(2),
178178
index = i - 1,
179179
has_type = operandType ~= nil,
180+
optional = operand.optional == true,
180181
})
181182
end
182183
elseif type(value.operands[1]) == "string" then
@@ -190,6 +191,7 @@ local function getAllOtherInstStructsData()
190191
index = 0,
191192
has_type = operandType ~= nil,
192193
variadic = value.operands.variadic,
194+
optional = value.operands.optional == true,
193195
})
194196
end
195197
end

0 commit comments

Comments
 (0)