Skip to content

fix(mir-lower): fall back to live operand type in arithmetic signedness check - #141

Merged
nihalpasham merged 7 commits into
NVIDIA:mainfrom
haixuanTao:fix/arith-live-type-fallback
Jun 12, 2026
Merged

nihalpasham merged 7 commits into
NVIDIA:mainfrom
haixuanTao:fix/arith-live-type-fallback

Conversation

@haixuanTao

Copy link
Copy Markdown
Contributor

is_signed_int_op errored ("expected IntegerType or MirPtrType operand") when the pre-conversion MIR type was not tracked for an operand — which happens for booleans and values produced inside short-circuit ||/&&, or already-converted operands.

Fall back to the live operand type: a (signless, post-conversion) integer or a pointer is treated as unsigned, instead of failing the whole lowering.

…ss check

`is_signed_int_op` errored ("expected IntegerType or MirPtrType operand") when the
pre-conversion MIR type was not tracked for an operand — which happens for booleans
and values produced inside short-circuit `||`/`&&`, or already-converted operands.

Fall back to the live operand type: a (signless, post-conversion) integer or a
pointer is treated as unsigned, instead of failing the whole lowering.
@nihalpasham nihalpasham added bug Something isn't working IR-lowering Lowering between dialects (dialect-mir to LLVM dialect) codegen Device code-generation pipeline (Rust MIR to IR to PTX) labels Jun 10, 2026
The fallback added for untracked operands treated any live integer as
unsigned. That is correct today because the only values without
conversion history are signless i1 bools (signless is not Signed), but
a blanket "unsigned" would silently miscompile if a future pass ever
produced an untracked Signed-typed operand. Consult the live type's
signedness instead, and correct the comment: replace_operation records
history for already-converted operands, so the untracked case is
exactly values whose type was never convertible.
Builds the short-circuit shape (let p = a || b; p == q; p < q) directly
in dialect-mir: a merge-block i1 argument has no conversion history
because signless i1 is rejected by can_convert_type, so the comparison
must go through the live-type fallback in is_signed_int_op. Asserts the
lowered body contains exactly icmp eq i1 and icmp ult i1. Reverting the
fallback reproduces the original failure (expected IntegerType or
MirPtrType operand in arithmetic op).
End-to-end cover for PR NVIDIA#141 through the full device pipeline: a bool
phi produced by short-circuit || feeds both == and < comparisons, and
the lanes cover all four (p, q) truth combinations. Before the fallback
in is_signed_int_op this kernel failed device codegen with "expected
IntegerType or MirPtrType operand in arithmetic op"; the emitted IR now
contains icmp eq i1 and icmp ult i1 over the phi.
# Conflicts:
#	crates/mir-lower/tests/lowering_test.rs
…i_cmp

clippy::bool_comparison wants p < q rewritten as !p & q, but the
comparison shape is the regression under test: it must reach mir-lower
as an order comparison on an untracked i1 phi and lower to icmp ult i1.
@nihalpasham

Copy link
Copy Markdown
Collaborator

This LGTM 👍🏾

Added three commits layered on top:

  • 4f06905: the untracked-operand fallback now consults the live IntegerType's signedness instead of blanket "unsigned". Identical behavior today (the only untracked values are signless i1 bools), but an untracked Signed operand from a future pass lowers correctly instead of silently going unsigned.
  • 81a3160: lowering test locking icmp eq i1 / icmp ult i1 for a bool-phi comparison; reverting the fallback reproduces the original "expected IntegerType or MirPtrType operand" failure.
  • 3583fce: bool_phi_cmp example (short-circuit || phi feeding == and <, all four truth combinations), picked up by examples-compile CI.

One correction folded into the first commit: "already-converted operands" in the comment was not quite right, since replace_operation records history for those. The untracked case is values whose type was never convertible, which today is only signless i1 bools.

@nihalpasham
nihalpasham merged commit bccce85 into NVIDIA:main Jun 12, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working codegen Device code-generation pipeline (Rust MIR to IR to PTX) IR-lowering Lowering between dialects (dialect-mir to LLVM dialect)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants