rust-lang / rust-lang/rust

`block-placement` LLVM pass introduces superfluous instruction in unrolled loop

Open
#145,176 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-LLVM C-bug I-heavy T-compiler
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

Here it is on Godbolt.

.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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.