64 bits integer simplification in TIR

I encountered a bug when I try to simplify a 64 bits integer TIR expression: floordiv(uint32(floordiv((int64(floordiv(iii, (uint32)1))*(int64)536870912), (int64)4294967296)), (uint32)1) Using arith::Analyzer to “Simplify” this expression will result in floormod 0 error. The cause is that the definition of floormod is PrimExpr(PrimExpr, int) which truncates int64_t to int at here:

Adding int64_t overloading version will solve the problem, but a potential issue is that any existing invocation of this function with uint64_t type will raise complaining of “call of overloadded … is ambiguous”.

ideally we should create IntImm explicitly with specific dtype. where did your expression come from? is it possible to fix such usage by creating IntImm?

@vinx13, that should fix this bug too. In my case, the direct caller to here is

I assume that there are many places doing the same way, i.e., passing int64_t or uint64_t directly to this function.

In this case, it should use c1.Eval() / c2.Eval() instead, which is the same way as other rewriting rules and it respects the original dtypes. Actually, it’s not safe to directly create IntImm with i64, or adding i64 overload here because that will always promote the whole expression to i64.

I think the intention of the original code in op.h is to prioritize the type of PrimExpr operand if some of the operands are not “TIR typed”. So even if 64bit overload is added, the eventual expression type is determined by the PrimExpr operand. So if the expression is finally a 64bit computation, it should result from the type of the PrimExpr operand, and I think that should also be the intention of the caller. On the other hand, if PrimExpr is 32 bit, it won’t escalate the compute precision to 64 bits.

1 Like

That makes sense. So either solution should work