@@ -217,15 +217,15 @@ impl EgglogContext {
217217 Op :: ConstantTrue => "(BoolConst 1)" . to_string ( ) ,
218218 Op :: ConstantFalse => "(BoolConst 0)" . to_string ( ) ,
219219
220- Op :: IAdd => self . binary_op ( "Add" , inst) ?,
221- Op :: ISub => self . binary_op ( "Sub" , inst) ?,
222- Op :: IMul => self . binary_op ( "Mul" , inst) ?,
223- Op :: SDiv => self . binary_op ( "SDiv" , inst) ?,
224- Op :: UDiv => self . binary_op ( "UDiv" , inst) ?,
225- Op :: SRem => self . binary_op ( "SRem" , inst) ?,
226- Op :: SMod => self . binary_op ( "SMod" , inst) ?,
227- Op :: UMod => self . binary_op ( "UMod" , inst) ?,
228- Op :: SNegate => self . unary_op ( "Neg" , inst) ?,
220+ Op :: IAdd => self . typed_binary_op ( "Add" , "VecAdd ", inst) ?,
221+ Op :: ISub => self . typed_binary_op ( "Sub" , "VecSub ", inst) ?,
222+ Op :: IMul => self . typed_binary_op ( "Mul" , "VecMul ", inst) ?,
223+ Op :: SDiv => self . typed_binary_op ( "SDiv" , "VecSDiv ", inst) ?,
224+ Op :: UDiv => self . typed_binary_op ( "UDiv" , "VecUDiv ", inst) ?,
225+ Op :: SRem => self . typed_binary_op ( "SRem" , "VecSRem ", inst) ?,
226+ Op :: SMod => self . typed_binary_op ( "SMod" , "VecSMod ", inst) ?,
227+ Op :: UMod => self . typed_binary_op ( "UMod" , "VecUMod ", inst) ?,
228+ Op :: SNegate => self . typed_unary_op ( "Neg" , "VecNeg ", inst) ?,
229229 Op :: ShiftLeftLogical => self . binary_op ( "Shl" , inst) ?,
230230 Op :: ShiftRightLogical => self . binary_op ( "ShrU" , inst) ?,
231231 Op :: ShiftRightArithmetic => self . binary_op ( "ShrS" , inst) ?,
@@ -249,14 +249,14 @@ impl EgglogContext {
249249 Op :: LogicalOr => self . binary_op ( "LogOr" , inst) ?,
250250 Op :: LogicalEqual => self . binary_op ( "LogEq" , inst) ?,
251251 Op :: LogicalNotEqual => self . binary_op ( "LogNe" , inst) ?,
252- // Floating-point operations
253- Op :: FAdd => self . binary_op ( "FAdd" , inst) ?,
254- Op :: FSub => self . binary_op ( "FSub" , inst) ?,
255- Op :: FMul => self . binary_op ( "FMul" , inst) ?,
256- Op :: FDiv => self . binary_op ( "FDiv" , inst) ?,
257- Op :: FRem => self . binary_op ( "FRem" , inst) ?,
258- Op :: FMod => self . binary_op ( "FMod" , inst) ?,
259- Op :: FNegate => self . unary_op ( "FNeg" , inst) ?,
252+ // Floating-point operations (scalar or vector)
253+ Op :: FAdd => self . typed_binary_op ( "FAdd" , "VecFAdd ", inst) ?,
254+ Op :: FSub => self . typed_binary_op ( "FSub" , "VecFSub ", inst) ?,
255+ Op :: FMul => self . typed_binary_op ( "FMul" , "VecFMul ", inst) ?,
256+ Op :: FDiv => self . typed_binary_op ( "FDiv" , "VecFDiv ", inst) ?,
257+ Op :: FRem => self . typed_binary_op ( "FRem" , "VecFRem ", inst) ?,
258+ Op :: FMod => self . typed_binary_op ( "FMod" , "VecFMod ", inst) ?,
259+ Op :: FNegate => self . typed_unary_op ( "FNeg" , "VecFNeg ", inst) ?,
260260 // Floating-point comparisons (ordered)
261261 Op :: FOrdEqual => self . binary_op ( "FOrdEq" , inst) ?,
262262 Op :: FOrdNotEqual => self . binary_op ( "FOrdNe" , inst) ?,
@@ -930,6 +930,46 @@ impl EgglogContext {
930930 Some ( format ! ( "({} {})" , op, operand) )
931931 }
932932
933+ /// Type-dispatched binary op: uses `scalar_op` (typed sort) when the result
934+ /// type is a scalar, and `vec_op` (Expr sort) when it is a vector/other type.
935+ /// This prevents sort mismatches when SPIR-V opcodes like OpFAdd/OpIAdd
936+ /// operate on vectors whose operands are in the generic Expr sort.
937+ fn typed_binary_op (
938+ & mut self ,
939+ scalar_op : & str ,
940+ vec_op : & str ,
941+ inst : & Instruction ,
942+ ) -> Option < String > {
943+ let is_scalar = inst
944+ . result_type
945+ . map ( |ty| self . type_class_of_type ( ty) != TypeClass :: Other )
946+ . unwrap_or ( false ) ;
947+ if is_scalar {
948+ self . binary_op ( scalar_op, inst)
949+ } else {
950+ self . binary_op ( vec_op, inst)
951+ }
952+ }
953+
954+ /// Type-dispatched unary op: uses `scalar_op` (typed sort) when the result
955+ /// type is a scalar, and `vec_op` (Expr sort) when it is a vector/other type.
956+ fn typed_unary_op (
957+ & mut self ,
958+ scalar_op : & str ,
959+ vec_op : & str ,
960+ inst : & Instruction ,
961+ ) -> Option < String > {
962+ let is_scalar = inst
963+ . result_type
964+ . map ( |ty| self . type_class_of_type ( ty) != TypeClass :: Other )
965+ . unwrap_or ( false ) ;
966+ if is_scalar {
967+ self . unary_op ( scalar_op, inst)
968+ } else {
969+ self . unary_op ( vec_op, inst)
970+ }
971+ }
972+
933973 /// Convert GLSL.std.450 extended instruction to egglog term.
934974 fn extended_instruction_to_term ( & mut self , inst : & Instruction ) -> Option < String > {
935975 // ExtInst operands: %set %instruction operands...
0 commit comments