Skip to content

Commit 22bcfb1

Browse files
committed
Fix unbound symbol errors from failed term generation
When instruction_to_term() returns None (e.g. Phi with different incoming values), the id was left in known_instruction_ids but never added to id_to_term. Later instructions referencing it via get_or_create_term() emitted a bare variable reference that was never bound, causing egglog "Unbound symbol" errors. Fix: remove the id from known_instruction_ids on failure so get_or_create_term() falls back to a Sym constructor.
1 parent 118a7e2 commit 22bcfb1

1 file changed

Lines changed: 28 additions & 21 deletions

File tree

rust/spirv-tools-opt/src/direct/context.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,32 +79,39 @@ impl EgglogContext {
7979
) {
8080
self.root_ids.push(result_id);
8181
}
82+
} else {
83+
// Term generation failed (e.g. Phi with different incoming values).
84+
// Remove from known_instruction_ids so get_or_create_term() falls
85+
// back to a Sym constructor instead of emitting a bare variable
86+
// reference that would be unbound in the egraph.
87+
self.known_instruction_ids.remove(&result_id);
88+
return;
89+
}
8290

83-
// Seed ResultWidth for integer constants and conversions
84-
if let Some(result_type) = inst.result_type {
85-
let tc = self.type_class_of_type(result_type);
86-
if tc == TypeClass::Int {
87-
let width = self.type_widths.get(&result_type).copied().unwrap_or(32);
88-
match inst.class.opcode {
89-
Op::Constant | Op::SConvert | Op::UConvert => {
90-
self.additional_facts
91-
.push(format!("(set (ResultWidth id{}) {})", result_id, width));
92-
}
93-
_ => {}
91+
// Seed ResultWidth for integer constants and conversions
92+
if let Some(result_type) = inst.result_type {
93+
let tc = self.type_class_of_type(result_type);
94+
if tc == TypeClass::Int {
95+
let width = self.type_widths.get(&result_type).copied().unwrap_or(32);
96+
match inst.class.opcode {
97+
Op::Constant | Op::SConvert | Op::UConvert => {
98+
self.additional_facts
99+
.push(format!("(set (ResultWidth id{}) {})", result_id, width));
94100
}
101+
_ => {}
95102
}
96103
}
104+
}
97105

98-
// Detect same-type bitcast for redundant bitcast elimination
99-
if inst.class.opcode == Op::Bitcast {
100-
if let Some(result_type) = inst.result_type {
101-
let src_id = inst.operands.iter().find_map(|op| op.id_ref_any());
102-
if let Some(src_id) = src_id {
103-
if let Some(src_type) = self.id_to_type.get(&src_id) {
104-
if *src_type == result_type {
105-
self.additional_facts
106-
.push(format!("(SameTypeBitcast id{})", result_id));
107-
}
106+
// Detect same-type bitcast for redundant bitcast elimination
107+
if inst.class.opcode == Op::Bitcast {
108+
if let Some(result_type) = inst.result_type {
109+
let src_id = inst.operands.iter().find_map(|op| op.id_ref_any());
110+
if let Some(src_id) = src_id {
111+
if let Some(src_type) = self.id_to_type.get(&src_id) {
112+
if *src_type == result_type {
113+
self.additional_facts
114+
.push(format!("(SameTypeBitcast id{})", result_id));
108115
}
109116
}
110117
}

0 commit comments

Comments
 (0)