Skip to content

[Fix][Arith] Translate boolean bitwise operations to logic in the Z3 prover - #88

Open
stealth-rklopper wants to merge 1 commit into
tile-ai:tilelang_mainfrom
thesm-os:fix/z3-boolean-bitwise
Open

stealth-rklopper wants to merge 1 commit into
tile-ai:tilelang_mainfrom
thesm-os:fix/z3-boolean-bitwise

Conversation

@stealth-rklopper

Copy link
Copy Markdown

Summary

Z3Prover translates bitwise_and, bitwise_or, bitwise_xor and bitwise_not through bit-vectors, also when the operands are booleans. TileLang writes a condition with &, such as (bx % 10 < 2) & (tk > 0), as a bitwise_and of two booleans. As a constraint, its bit-vector terms use up the rlimit budget of the solver, and an easy proof under it returns unknown.

ThreadSync of TileLang aborts the compile with LOG(FATAL) in two such cases:

With T.And in place of &, the proofs hold. This PR translates a bitwise operation of booleans to its logical operation, so both forms give the same proofs.

Reproduction and cause

import tvm
from tvm import tirx

tx1, tx2, pages = (tirx.Var(name, "int32") for name in ("tx1", "tx2", "pages"))
bindings = []
for name in ("1", "2"):
    slot = tirx.Var("slot" + name, "int32")
    inside = tirx.Var("inside" + name, "bool")
    bindings.append(inside == tirx.bitwise_and(slot >= 0, slot < pages))
condition = tirx.all(tx1 != tx2, 0 <= tx1, tx1 < 128, 0 <= tx2, tx2 < 128, *bindings)
ana = tvm.arith.Analyzer()
with ana.constraint_scope(condition):
    print(ana.can_prove(tx1 // 32 * 256 + tx1 % 32 != tx2 // 32 * 256 + tx2 % 32 + 32))
# Before this change: False. With tirx.And in place of tirx.bitwise_and: True.

The binding of each thread instance is the form in which ThreadSync passes the constraints of a statement to the solver. VisitBitwiseOp converts each operand with int2bv and the result with bv2int(..., true), so each boolean becomes a 1-bit vector. The claim itself has no bitwise operation, but the solver gives up on it within its budget of 10,000 steps. The prover sets that budget with SetRLimit(1e4), so a longer timeout gives the same result.

Changes

  • VisitExpr_(const CallNode *) translates bitwise_and, bitwise_or, bitwise_xor and bitwise_not with a scalar boolean result to &&, ||, != and ! of the boolean operands.
  • Integer bitwise operations keep their bit-vector translation.
  • test_z3_proves_under_bitwise_and_of_booleans in tests/python/arith/test_arith_simplify.py checks the proof above. It fails before this change and passes after it.

Validation

A TileLang PR follows with the bump of 3rdparty/tvm and regression tests for both cases of ThreadSync.

…prover

Z3Prover translated bitwise_and, bitwise_or, bitwise_xor and
bitwise_not through bit-vectors, also for boolean operands. TileLang
writes a condition with `&`, such as `(bx % 10 < 2) & (tk > 0)`, as a
bitwise_and of two booleans. As a constraint, its bit-vector terms used
up the rlimit budget of the solver, so an easy proof under it returned
unknown, and ThreadSync of TileLang aborted the compile.

A bitwise operation with a scalar boolean result now becomes the
logical operation of its boolean operands. Integer bitwise operations
keep their bit-vector translation.

test_z3_proves_under_bitwise_and_of_booleans checks a proof of
ThreadSync under such a binding. It fails before this change.
stealth-rklopper added a commit to thesm-os/tilelang that referenced this pull request Oct 26, 2026
Point 3rdparty/tvm at 815a438 of thesm-os/tvm, the fix of
tile-ai/tvm#88. The Z3 prover then reads & and | of two conditions as
logic, so ThreadSync proves a partial barrier under such a condition
warp-uniform, as tile-ai#3653 reports.
stealth-rklopper added a commit to thesm-os/tilelang that referenced this pull request Oct 26, 2026
Point 3rdparty/tvm at the Z3 fix of tile-ai/tvm#88 on top of 4211874e9,
the commit that upstream pins. The previous base, 5959716 of
tilelang_main, has the HIP device query of tile-ai/tvm#79. The HIP stub
of TileLang throws in hipGetDeviceCount without libamdhip64.so, so a
ROCm target fails on a machine without ROCm. tile-ai#3425
changes the stub and moves 3rdparty/tvm past tile-ai#79.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant