Skip to content

codegen: tell LLVM that the discriminant is a power of two - #162741

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
dianqk:codegen-discriminants-cast
Oct 8, 2026
Merged

rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
dianqk:codegen-discriminants-cast

Conversation

@dianqk

@dianqk dianqk commented Sep 14, 2026 •

Copy link
Copy Markdown
Member

Fixes #162513.

We should not disable the pattern in MatchBranchSimplification. The two forms exhaustive match and cast are equivalent, but the cast is better represented in MIR: no branches, only one statement.

AFAIK, LLVM does not handle multiple disjoint intervals well. As an workaround, the patch emits assume(ctpop(val) == 1) to tell LLVM that the discriminant is a power of two.

LLM disclosure: search the codebase and fix grammer.

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 14, 2026
@rust-log-analyzer

This comment has been minimized.

@dianqk
dianqk force-pushed the codegen-discriminants-cast branch from 00815d3 to 78443a5 Compare September 14, 2026 10:36
@rust-log-analyzer

This comment has been minimized.

@dianqk
dianqk force-pushed the codegen-discriminants-cast branch from 78443a5 to 277091e Compare September 14, 2026 11:20
@rust-log-analyzer

This comment has been minimized.

@dianqk

dianqk commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 14, 2026
rust-bors Bot pushed a commit that referenced this pull request Sep 14, 2026
codegen: tell LLVM that the discriminant is a power of two
@rust-bors

rust-bors Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: fb82f6b (fb82f6bd3bc4448e1f07ef7b824296245782bc7c)
Base parent: ed77b7b (ed77b7b8699e342c2dc842c83cb5fe4025252ee8)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (fb82f6b): comparison URL.

Overall result: ❌ regressions - no action needed

Benchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up.

@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.2% [0.2%, 0.2%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Max RSS (memory usage)

This perf run didn't have relevant results for this metric.

Cycles

Results (secondary -5.3%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.3% [2.3%, 2.3%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-9.1% [-9.1%, -9.0%] 2
All ❌✅ (primary) - - 0

Binary size

Results (secondary -0.1%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.1% [-0.1%, -0.1%] 1
All ❌✅ (primary) - - 0

Bootstrap: 495.332s -> 496.261s (0.19%)
Artifact size: 406.96 MiB -> 406.98 MiB (0.01%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 14, 2026
@dianqk
dianqk force-pushed the codegen-discriminants-cast branch from 277091e to 150cc4d Compare September 14, 2026 22:23
@rust-log-analyzer

This comment has been minimized.

@dianqk
dianqk force-pushed the codegen-discriminants-cast branch from 150cc4d to 52c6615 Compare September 15, 2026 00:37
@rust-log-analyzer

This comment has been minimized.

@dianqk
dianqk force-pushed the codegen-discriminants-cast branch from 52c6615 to 9ca373c Compare September 15, 2026 10:16
@dianqk
dianqk marked this pull request as ready for review September 15, 2026 10:17
@rustbot

rustbot commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

rustc_codegen_gcc is developed in its own repository. If possible, consider making this change to rust-lang/rustc_codegen_gcc instead.

cc @antoyo, @GuillaumeGomez

@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 Sep 15, 2026
@rustbot

rustbot commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

r? @adwinwhite

rustbot has assigned @adwinwhite.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 76 candidates
  • Random selection from 19 candidates

@adwinwhite

Copy link
Copy Markdown
Contributor

@rustbot reroll

@saethlin

saethlin commented Oct 5, 2026

Copy link
Copy Markdown
Member

r? saethlin
r=me but you might want to take my suggestion. I think it compiles.

@rustbot rustbot assigned saethlin and unassigned jackh726 Oct 5, 2026
We should not disable the pattern in MatchBranchSimplification.
The two forms exhaustive match and cast are equivalent, but the cast is better represented in MIR: no branches, only one statement.

AFAIK, LLVM does not handle multiple disjoint intervals well.
As an workaround, the patch emits `assume(ctpop(val) == 1)` to tell LLVM that
the discriminant is a power of two.
@dianqk
dianqk force-pushed the codegen-discriminants-cast branch from 9ca373c to 23fa0f4 Compare October 7, 2026 14:45
@dianqk

dianqk commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

@bors r=saethlin

@rust-bors

rust-bors Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 23fa0f4 has been approved by saethlin

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 7, 2026
jhpratt added a commit to jhpratt/rust that referenced this pull request Oct 8, 2026
… r=saethlin

codegen: tell LLVM that the discriminant is a power of two

Fixes rust-lang#162513.

We should not disable the pattern in MatchBranchSimplification. The two forms exhaustive match and cast are equivalent, but the cast is better represented in MIR: no branches, only one statement.

AFAIK, LLVM does not handle multiple disjoint intervals well. As an workaround, the patch emits `assume(ctpop(val) == 1)` to tell LLVM that the discriminant is a power of two.

LLM disclosure: search the codebase and fix grammer.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Oct 8, 2026
… r=saethlin

codegen: tell LLVM that the discriminant is a power of two

Fixes rust-lang#162513.

We should not disable the pattern in MatchBranchSimplification. The two forms exhaustive match and cast are equivalent, but the cast is better represented in MIR: no branches, only one statement.

AFAIK, LLVM does not handle multiple disjoint intervals well. As an workaround, the patch emits `assume(ctpop(val) == 1)` to tell LLVM that the discriminant is a power of two.

LLM disclosure: search the codebase and fix grammer.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Oct 8, 2026
… r=saethlin

codegen: tell LLVM that the discriminant is a power of two

Fixes rust-lang#162513.

We should not disable the pattern in MatchBranchSimplification. The two forms exhaustive match and cast are equivalent, but the cast is better represented in MIR: no branches, only one statement.

AFAIK, LLVM does not handle multiple disjoint intervals well. As an workaround, the patch emits `assume(ctpop(val) == 1)` to tell LLVM that the discriminant is a power of two.

LLM disclosure: search the codebase and fix grammer.
rust-bors Bot pushed a commit that referenced this pull request Oct 8, 2026
…uwer

Rollup of 10 pull requests

Successful merges:

 - #162741 (codegen: tell LLVM that the discriminant is a power of two)
 - #162758 (Split PassMode::IndirectUnsized out of PassMode::Indirect)
 - #163931 (Move `loop_hint_attrs` from `Terminator` into `TerminatorKind::Goto`)
 - #163028 (autodiff: fix sysroot candidates in libEnzyme not found error)
 - #163538 (Add `rustc::missing_generic_type_visitable` lint)
 - #163841 ([rustdoc] Fix more `incoherent_impl` linking)
 - #163908 (Update Enzyme submodule)
 - #163935 (Use BasicBlock::start_location and Location::START)
 - #163949 (disable next-solver with higher-ranked-assumptions)
 - #163951 (relax_elf_relocations is x86-only)
rust-bors Bot pushed a commit that referenced this pull request Oct 8, 2026
…uwer

Rollup of 11 pull requests

Successful merges:

 - #162741 (codegen: tell LLVM that the discriminant is a power of two)
 - #162758 (Split PassMode::IndirectUnsized out of PassMode::Indirect)
 - #163931 (Move `loop_hint_attrs` from `Terminator` into `TerminatorKind::Goto`)
 - #163028 (autodiff: fix sysroot candidates in libEnzyme not found error)
 - #163257 (abby DSL: sanity checks on forall where clauses)
 - #163841 ([rustdoc] Fix more `incoherent_impl` linking)
 - #163908 (Update Enzyme submodule)
 - #163935 (Use BasicBlock::start_location and Location::START)
 - #163949 (disable next-solver with higher-ranked-assumptions)
 - #163951 (relax_elf_relocations is x86-only)
 - #163968 (Remove needs-triage label from relnotes issues)
@rust-bors
rust-bors Bot merged commit dfca88b into rust-lang:main Oct 8, 2026
14 checks passed
rust-bors Bot pushed a commit that referenced this pull request Oct 8, 2026
Rollup merge of #162741 - dianqk:codegen-discriminants-cast, r=saethlin

codegen: tell LLVM that the discriminant is a power of two

Fixes #162513.

We should not disable the pattern in MatchBranchSimplification. The two forms exhaustive match and cast are equivalent, but the cast is better represented in MIR: no branches, only one statement.

AFAIK, LLVM does not handle multiple disjoint intervals well. As an workaround, the patch emits `assume(ctpop(val) == 1)` to tell LLVM that the discriminant is a power of two.

LLM disclosure: search the codebase and fix grammer.
@rustbot rustbot added this to the 1.101.0 milestone Oct 8, 2026
@dianqk
dianqk deleted the codegen-discriminants-cast branch October 8, 2026 12:42
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Oct 9, 2026
…uwer

Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#162741 (codegen: tell LLVM that the discriminant is a power of two)
 - rust-lang/rust#162758 (Split PassMode::IndirectUnsized out of PassMode::Indirect)
 - rust-lang/rust#163931 (Move `loop_hint_attrs` from `Terminator` into `TerminatorKind::Goto`)
 - rust-lang/rust#163028 (autodiff: fix sysroot candidates in libEnzyme not found error)
 - rust-lang/rust#163257 (abby DSL: sanity checks on forall where clauses)
 - rust-lang/rust#163841 ([rustdoc] Fix more `incoherent_impl` linking)
 - rust-lang/rust#163908 (Update Enzyme submodule)
 - rust-lang/rust#163935 (Use BasicBlock::start_location and Location::START)
 - rust-lang/rust#163949 (disable next-solver with higher-ranked-assumptions)
 - rust-lang/rust#163951 (relax_elf_relocations is x86-only)
 - rust-lang/rust#163968 (Remove needs-triage label from relnotes issues)
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Oct 12, 2026
…uwer

Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#162741 (codegen: tell LLVM that the discriminant is a power of two)
 - rust-lang/rust#162758 (Split PassMode::IndirectUnsized out of PassMode::Indirect)
 - rust-lang/rust#163931 (Move `loop_hint_attrs` from `Terminator` into `TerminatorKind::Goto`)
 - rust-lang/rust#163028 (autodiff: fix sysroot candidates in libEnzyme not found error)
 - rust-lang/rust#163257 (abby DSL: sanity checks on forall where clauses)
 - rust-lang/rust#163841 ([rustdoc] Fix more `incoherent_impl` linking)
 - rust-lang/rust#163908 (Update Enzyme submodule)
 - rust-lang/rust#163935 (Use BasicBlock::start_location and Location::START)
 - rust-lang/rust#163949 (disable next-solver with higher-ranked-assumptions)
 - rust-lang/rust#163951 (relax_elf_relocations is x86-only)
 - rust-lang/rust#163968 (Remove needs-triage label from relnotes issues)
rust-bors Bot pushed a commit that referenced this pull request Oct 12, 2026
codegen: tell LLVM that the discriminant is a power of two

Fixes #162513.

We should not disable the pattern in MatchBranchSimplification. The two forms exhaustive match and cast are equivalent, but the cast is better represented in MIR: no branches, only one statement.

AFAIK, LLVM does not handle multiple disjoint intervals well. As an workaround, the patch emits `assume(ctpop(val) == 1)` to tell LLVM that the discriminant is a power of two.

LLM disclosure: search the codebase and fix grammer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

MatchBranchSimplification destroys power-of-two knowledge for #[repr(u8)] enums whose discriminants equal to match arms

7 participants