[Fix][Relax][ONNX] Preserve integer Div truncation during import#19975
[Fix][Relax][ONNX] Preserve integer Div truncation during import#19975viiccwen wants to merge 2 commits into
Conversation
ONNX integer Div uses truncating division, rounding toward zero. The Relax ONNX frontend already special-cased integer Div to detect zero divisors, but its PrimExpr folding path could still use NumPy floating-point division and produce floating-point TIR values for integer shape computations. This can make shape-derived expressions such as Shape -> Gather -> Div -> Slice fail during import, because strided_slice expects integer PrimExpr bounds. Handle scalar integer Div inputs that contain a PrimExpr using TIR truncdiv, while keeping existing generic BinaryBase handling for tensor constants and runtime expressions. Add regression tests for integer constant Div semantics and a shape-derived PrimExpr Div used as a Slice bound. Signed-off-by: viiccwen <vicwen@apache.org>
Signed-off-by: viiccwen <vicwen@apache.org>
There was a problem hiding this comment.
Code Review
This pull request adds support for folding integer division operations involving symbolic PrimExpr inputs in the ONNX frontend, truncating toward zero. It introduces helper methods to identify zero divisors and extract scalar expressions, and adds corresponding unit tests. The review feedback points out that shape-derived values in Relax are often wrapped in relax.PrimValue rather than raw tvm.ir.PrimExprs. To avoid bypassing the symbolic division path and causing potential runtime errors, it is recommended to explicitly check for and unwrap relax.PrimValue in both _as_scalar_prim_expr and the has_prim_expr condition.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
cc @guan404ming, @tlopex. 🙌 |

ONNX integer Div uses truncating division, rounding toward zero. The Relax ONNX frontend already special-cased integer Div to detect zero divisors, but its PrimExpr folding path could still use NumPy floating-point division when one of the inputs was a shape-derived PrimExpr.
That behavior can produce floating-point TIR values for integer shape/index computations. For example, a
Shape -> Gather -> Div -> Slicesubgraph can produceT.float64(128.666...)as a Slice bound, which Relax rejects because strided_slice expects integer PrimExpr bounds.This patch handles scalar integer Div inputs that contain a PrimExpr using TIR
truncdiv, preserving ONNX semantics while keeping shape computations in TIR instead of routing them through NumPy. Constant tensor Div continues to use the existing generic binary constant-folding path.The regression tests cover:
Verification:
python -m pytest tests/python/relax/test_frontend_onnx.py::test_div_integer_constant_zero_divisor_raises_valueerror tests/python/relax/test_frontend_onnx.py::test_div_integer_constant_folding_truncates_toward_zero tests/python/relax/test_frontend_onnx.py::test_div_integer_primexpr_folding_truncates_toward_zero -qFixes #19974