Skip to content

IR support for switch instructions#7536

Draft
vaivaswatha wants to merge 37 commits intomasterfrom
vaivaswatha/ir_switch
Draft

IR support for switch instructions#7536
vaivaswatha wants to merge 37 commits intomasterfrom
vaivaswatha/ir_switch

Conversation

@vaivaswatha
Copy link
Contributor

@vaivaswatha vaivaswatha commented Jan 21, 2026

Description

This PR adds a new IR instruction switch, that supports both exhaustive (for exhaustive matchs, verified by the front-end) and non-exhaustive switches.

Since matchs in the frontend still translate to an if-else ladder, a switch is never generated yet. So for testing, the PR adds support in the test harness to compile and execute (in the VM) sway-ir files directly.

To be able to snapshot-test the generated ASM output, we will add compile-ir to forc as well. This will be done in a follow up PR in which we will also add snapshot tests for should_pass/language/ir_switch tests added in this PR

This is the first step on the backend in implementing #7503.

@vaivaswatha vaivaswatha self-assigned this Jan 21, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Jan 21, 2026

Merging this PR will not alter performance

✅ 25 untouched benchmarks


Comparing vaivaswatha/ir_switch (62f3856) with master (f9de545)

Open in CodSpeed

@vaivaswatha vaivaswatha marked this pull request as ready for review January 22, 2026 10:30
@vaivaswatha vaivaswatha requested review from a team as code owners January 22, 2026 10:30
@cursor
Copy link

cursor bot commented Jan 22, 2026

PR Summary

Medium Risk
Adds a new IR terminator and threads it through parsing, verification, CFG/optimizer utilities, and Fuel ASM generation, which could affect compilation correctness and control-flow handling. EVM codegen stubs switch as todo!(), so any accidental use on that backend would panic.

Overview
Adds a new Sway-IR switch terminator (optional default; None means exhaustive) with parser/printer support, verifier rules (u64 discriminant, no duplicates, exhaustive-range enforcement), and updated CFG utilities/optimizations to understand switch successors and branch arguments.

Implements Fuel backend lowering for switch by introducing an organizational Switch op that expands into a jump-table in the data section (Datum::WordArray) and a computed jump sequence; constant propagation and other ASM passes are updated for the new control-flow op. EVM backend plumbing is added but compile_switch remains todo!().

Adds IR compilation + test coverage by exposing forc_pkg::compile_ir (requires new sway-ir dep) and extending the e2e harness with a new ir_run category that compiles main.ir and executes it in the VM, along with new IR switch test programs and simplify-cfg tests.

Written by Cursor Bugbot for commit 62f3856. This will update automatically on new commits. Configure here.

xunilrj
xunilrj previously approved these changes Jan 23, 2026
sorted_cases
.iter_mut()
.for_each(|(val, _)| *val -= min_case_value);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In-place SUBI corrupts discriminant register for successor blocks

High Severity

The SUBI writes the adjusted discriminant back into discrim_reg, the same virtual register returned by value_to_register(discriminant). This register is shared by all uses of that IR value. If any successor block references the discriminant directly (not via phi/block arguments), value_to_register returns the same register, and the successor sees the subtracted value instead of the original. A fresh temporary register from self.reg_seqr.next() is needed for the adjusted value.

Fix in Cursor Fix in Web

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! This is indeed a bug!

xunilrj
xunilrj previously approved these changes Feb 20, 2026
@ironcev ironcev temporarily deployed to fuel-sway-bot March 2, 2026 10:53 — with GitHub Actions Inactive
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@ironcev ironcev temporarily deployed to fuel-sway-bot March 2, 2026 14:01 — with GitHub Actions Inactive
@ironcev ironcev temporarily deployed to fuel-sway-bot March 3, 2026 07:06 — with GitHub Actions Inactive
@ironcev ironcev temporarily deployed to fuel-sway-bot March 3, 2026 11:50 — with GitHub Actions Inactive
@ironcev ironcev temporarily deployed to fuel-sway-bot March 3, 2026 13:13 — with GitHub Actions Inactive
@ironcev
Copy link
Member

ironcev commented Mar 3, 2026

Putting to draft until https://github.com/FuelLabs/sway/pull/7536/changes#r2821795856 is fixed and tested.

@ironcev ironcev marked this pull request as draft March 3, 2026 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla:signed compiler: codegen Everything to do with IR->ASM, register allocation, etc. compiler: ir IRgen and sway-ir including optimization passes compiler General compiler. Should eventually become more specific as the issue is triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants