Skip to content

Emit range assume after IntToInt cast in MatchBranchSimplification#155206

Closed
blackms wants to merge 1 commit intorust-lang:mainfrom
blackms:fix-bounds-check-149480
Closed

Emit range assume after IntToInt cast in MatchBranchSimplification#155206
blackms wants to merge 1 commit intorust-lang:mainfrom
blackms:fix-bounds-check-149480

Conversation

@blackms
Copy link
Copy Markdown

@blackms blackms commented Apr 12, 2026

Fixes #149480

PR #127324 introduced unify_by_int_to_int in MatchBranchSimplification, which replaces individual constant assignments with a single IntToInt cast. This is a valid optimization, but it loses range information that LLVM previously inferred from phi node constants — causing unnecessary bounds checks to remain.

The fix emits assume(result <= max_value) after the IntToInt cast, where max_value is the maximum of the original constant values being replaced. This allows LLVM to prove the index is in-bounds and eliminate the bounds check.

Before (with bounds check):

cmp     rax, 4
ja      .LBB0_2          ; panic_bounds_check

After (bounds check eliminated):

add     rdx, rax
mov     rax, rdx
ret

r? mir-opt

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 12, 2026

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 12, 2026
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Foo::B(B::B0) => 3,
Foo::B(B::B1) => 4,
};
// CHECK-NOT: panic_bounds_check
Copy link
Copy Markdown
Member

@saethlin saethlin Apr 12, 2026

Choose a reason for hiding this comment

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

View changes since the review

It's good to have a negative check but without a positive test as well in here (checking for the IR sequence that should appear) this test could incorrectly pass if the function is renamed or if it's optimized to some other kind of panicking.

You should be able to draw inspiration from other codegen tests. Not having a positive check is a common flaw in the existing test suite, but it's not universal :)

@saethlin saethlin added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 13, 2026
When MatchBranchSimplification replaces multiple constant assignments
with a single IntToInt cast, the range information that LLVM could
previously infer from the phi node constants is lost. This causes
unnecessary bounds checks to remain in the generated code.

Fix this by emitting an assume(result <= max_value) after the cast,
where max_value is the maximum of the original constant values. This
allows LLVM to eliminate bounds checks that depend on the cast result.
@blackms blackms force-pushed the fix-bounds-check-149480 branch from 0c81f4a to bcbe68f Compare April 14, 2026 13:27
@blackms
Copy link
Copy Markdown
Author

blackms commented Apr 14, 2026

Thanks for the review @saethlin! Addressed in the latest push (force-pushed to drop the Fixes #... line from the commit message as rustbot requested):

  • Positive check added. The test for bar now also asserts the expected IR shape (load i8, ptr + ret i8), so it can't silently pass if the function is renamed or the panicking path changes.
  • Sanity check added. A second test_check function with a non-elidable arr[i] ensures panic_bounds_check is still the symbol LLVM actually emits, guarding the CHECK-NOT in @bar against becoming vacuously true.
  • tidy failure fixed. Applied the rustfmt changes the tidy bot suggested on match_branches.rs and on the test.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 14, 2026
@saethlin
Copy link
Copy Markdown
Member

r? compiler

@rustbot rustbot assigned TaKO8Ki and unassigned saethlin Apr 15, 2026
@jieyouxu
Copy link
Copy Markdown
Member

See #155296 (comment)

@jieyouxu jieyouxu closed this Apr 15, 2026
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 15, 2026
@rust-lang rust-lang locked and limited conversation to collaborators Apr 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Array indexed by exhaustive match still generates bounds checks

6 participants