Expected behavior
Block access-region analysis should handle valid uint32/uint64 conditions without crashing. If an unsigned predicate cannot be solved, conservatively including both branches is sufficient.
Actual behavior
Analyzing if_then_else(mask != 0, data[0], data[3]) with an unsigned mask raises:
tvm.error.InternalError: cannot make uint from negative value -1
There is no negative constant in the input program, and all buffer accesses are in bounds. Both uint32 and uint64 reproduce; the int32 control passes. An explicit mask == 0 condition also reproduces.
The failure occurs when analyzing the implicit else condition, mask == 0. ConditionalBoundsContext::TrySolveCondition accepts unsigned variables and passes the condition to SolveInequalitiesToRange / SolveLinearInequalities. The solver constructs signed mathematical coefficients using the program variable's unsigned type, for example:
PrimExpr c_pos = MakeConst(v_ty, neg.first / first_gcd);
This attempts to represent an internally generated -1 as an unsigned constant. The issue is a mismatch between conditional-analysis eligibility and the inequality solver's supported arithmetic domain, not an invalid user literal.
Environment
- Apache TVM
main, commit cc0f9f07c17c8118a781fdca55f7fe45f7de916a (0.26.dev0).
- Windows, Python 3.12.13, locally built TVM compiler/runtime DLLs.
- Reproduced directly in Apache TVM, without TileLang. No GPU execution or LLVM code generation is required.
Steps to reproduce
Run this script against the above revision:
from tvm import s_tir, tirx
mask_buffer = tirx.decl_buffer((1,), "uint32", name="mask_buffer")
data = tirx.decl_buffer((4,), "int32", name="data")
output = tirx.decl_buffer((1,), "int32", name="output")
mask = tirx.Var("mask", "uint32")
body = tirx.SeqStmt([
tirx.Bind(mask, mask_buffer[0]),
tirx.BufferStore(
output, tirx.if_then_else(mask != 0, data[0], data[3]), [0]
),
])
block = tirx.SBlock([], [], [], "conditional_read", body)
buffers = {buf: buf for buf in (mask_buffer, data, output)}
print(s_tir.analysis.get_sblock_access_region(block, buffers))
Replace both uint32 occurrences with uint64 to reproduce the same error, or with int32 for the passing control. The expected conservative read region for data is [0:4].
Triage
Expected behavior
Block access-region analysis should handle valid
uint32/uint64conditions without crashing. If an unsigned predicate cannot be solved, conservatively including both branches is sufficient.Actual behavior
Analyzing
if_then_else(mask != 0, data[0], data[3])with an unsignedmaskraises:There is no negative constant in the input program, and all buffer accesses are in bounds. Both
uint32anduint64reproduce; theint32control passes. An explicitmask == 0condition also reproduces.The failure occurs when analyzing the implicit else condition,
mask == 0.ConditionalBoundsContext::TrySolveConditionaccepts unsigned variables and passes the condition toSolveInequalitiesToRange/SolveLinearInequalities. The solver constructs signed mathematical coefficients using the program variable's unsigned type, for example:This attempts to represent an internally generated
-1as an unsigned constant. The issue is a mismatch between conditional-analysis eligibility and the inequality solver's supported arithmetic domain, not an invalid user literal.Environment
main, commitcc0f9f07c17c8118a781fdca55f7fe45f7de916a(0.26.dev0).Steps to reproduce
Run this script against the above revision:
Replace both
uint32occurrences withuint64to reproduce the same error, or withint32for the passing control. The expected conservative read region fordatais[0:4].Triage