`block-placement` LLVM pass introduces superfluous instruction in unrolled loop
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Since Rust code is affected by this, and because Rustc uses a fork of LLVM, I'm reporting this here, although the same issue probably affects other LLVM-based compilers.
The following code:
fn check(b: u8) -> Option<u8> {
if let 1..=127 = b { Some(b) } else { None }
}
pub fn conv(bytes: [u8; 4]) -> Option<u32> {
bytes
.into_iter()
.try_fold(0, |sum, ch| {
check(ch).map(|digit| sum + u32::from(digit))
})
}
has this at the end of its assembly output:
mov eax, 1
ret
.LBB0_5:
ret
.LBB0_5 could've been moved before the ret, reducing the number of rets in the function to 1. In fact, the LLVM IR only contains one ret up until the block placement pass, as can be seen in the optimization pipeline viewer on Godbolt.
Meta
rustc --version --verbose:
rustc 1.91.0-nightly (de3efa79f 2025-08-08)
binary: rustc
commit-hash: de3efa79f95852c7427587f1d535bfea7c0d6779
commit-date: 2025-08-08
host: x86_64-unknown-linux-gnu
release: 1.91.0-nightly
LLVM version: 21.1.0
Internal compiler ID: nightly
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the extra ret using the Rust code and Godbolt optimization pipeline described in the issue. Start by tracing LLVM's block-placement pass and compare the IR before and after it; done means the unrolled loop no longer produces the superfluous return block while preserving the generated behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100