Skip to content

[FSM] Eliminate mutually exclusive transition guards (#3577)#10754

Open
arefinaa wants to merge 1 commit into
llvm:mainfrom
arefinaa:fix-issue-3577
Open

[FSM] Eliminate mutually exclusive transition guards (#3577)#10754
arefinaa wants to merge 1 commit into
llvm:mainfrom
arefinaa:fix-issue-3577

Conversation

@arefinaa

@arefinaa arefinaa commented Jul 1, 2026

Copy link
Copy Markdown

What does this PR do?

Adds a canonicalization to fsm.state that detects when a state has exactly
two outgoing transitions whose guards are logical complements of one another
(e.g. cond and !cond) and strips the second transition's guard, turning it
into an unconditional default transition. Since the second transition is only
reached when the first guard has already failed, the second guard necessarily
holds and is redundant. The complement is recognized in both the comb
(comb.xor %cond, %true) and arith (arith.xori %cond, %true) spellings.

Why was this PR needed?

The Calyx → FSM lowering emits these mutually exclusive guard pairs verbatim,
and the redundant logic propagates all the way into the emitted SystemVerilog.
The pattern is conservatively scoped to states with exactly two transitions to
avoid the non-determinism that affected earlier unreachable-state work on this
issue.

What are the relevant issue numbers?

Fixes #3577

Testing

  • Lit tests added in test/Dialect/FSM/canonicalize.mlir: positive cases
    for both comb and arith complement spellings, and negative cases
    (non-complementary guards, three-transition state)
  • No breaking changes — pure canonicalization addition

Assisted-by: Claude Code:claude-opus-4-8

When a state has exactly two outgoing transitions whose guards are
logical complements of one another (e.g. `cond` and `!cond`), the second
transition is only reached when the first guard has already failed, which
implies the second guard necessarily holds. The second guard is therefore
redundant.

This adds a canonicalization to `StateOp::canonicalize` that detects this
case and strips the second transition's guard, turning it into an
unconditional default transition. The complement is recognized in both
the comb (`comb.xor %cond, %true`) and arith (`arith.xori %cond, %true`)
spellings; the now-dead complement op is removed by dead-code elimination.

This removes redundant logic that the Calyx -> FSM lowering emits verbatim
and that would otherwise propagate all the way to emitted SystemVerilog.

The pattern is conservatively scoped to states with exactly two
transitions to avoid the non-determinism that affected earlier
unreachable-state work.

Adds lit tests covering the comb and arith positive cases and negative
cases (non-complementary guards, and a three-transition state).

Assisted-by: Claude Code:claude-opus-4-8
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@arefinaa arefinaa requested a review from mortbopet as a code owner July 1, 2026 23:17
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.

[FSM] Tracking issue for canonicalization and optimization patterns

1 participant