Repository navigation
Miscompilation: program prints 3 instead of 2 at opt-level=2 and 3 #163311
Description
I tried this code:
static mut OUT: u8 = 1;
unsafe fn f() {
let (mut w, mut z, mut y, mut n, mut o, mut q, mut c, mut d, mut a) =
(false, false, true, false, false, false, false, false, false);
for mut x in 0..2 {
let mut branch = false;
loop {
'step: {
if x < 1 {
y = false;
branch = OUT > 0;
if branch {
break 'step;
}
}
loop {
if !o {
o = !y;
z = x < 1;
if o {
x = 3;
} else {
q = true;
}
}
if !z || q {
if !z {
OUT = x;
n = w;
d = n;
}
if !d {
if !z {
c = !n;
}
if z || !c {
d = true;
}
if c || !d {
c = false;
OUT = x;
}
}
if d {
return;
}
}
z = false;
w = !o;
if o {
if x < 1 {
a = true;
}
break;
}
}
}
if branch {
break;
}
if a {
break;
}
OUT = 2;
break;
}
if !branch {
break;
}
}
}
fn main() {
print!("{}", unsafe {
f();
OUT
});
}Save the code as case.rs, then run:
rustc +nightly --edition=2024 -C opt-level=1 case.rs -o case-o1
./case-o1
# Prints: 2
rustc +nightly --edition=2024 -C opt-level=2 case.rs -o case-o2
./case-o2
# Prints: 3I expected to see this happen:
The program should print 2 at every optimization level.
On the first outer iteration (x = 0), y becomes false and
branch becomes true, so the inner processing is skipped.
On the second iteration (x = 1), the inner loop changes x to 3
and writes 3 to OUT. However, d remains false, so the function
does not return early. After leaving the inner loop, both branch
and a are false, so OUT = 2 is executed before the function exits.
Instead, this happened:
The program prints 3 at opt-level=2 and opt-level=3.
Compilation and execution succeed; the executable exits with status 0.
Additional checks on the same nightly:
| Configuration | Output |
|---|---|
-C opt-level=0 |
2 |
-C opt-level=1 |
2 |
-C opt-level=2 |
3 |
-C opt-level=3 |
3 |
-C opt-level=2 -C no-prepopulate-passes |
2 |
-C opt-level=2 -Zmir-opt-level=0 |
2 |
I also ran the program with Miri in an edition-2024 Cargo project:
- With
RUSTFLAGS="-Awarnings -Zmir-opt-level=0"and
MIRIFLAGS="-Zmiri-strict-provenance", it prints2and exits
successfully without reporting undefined behavior. - With
RUSTFLAGS="-Awarnings -Zmir-opt-level=2", it also prints2
and exits successfully without reporting undefined behavior.
The program is single-threaded. The mutable static is accessed directly,
and its value is copied out for printing.
Meta
Tested in Ubuntu 22.04 under WSL, on x86_64-unknown-linux-gnu.
rustc +nightly --version --verbose:
rustc 1.100.0-nightly (f7575a9da 2026-09-24)
binary: rustc
commit-hash: f7575a9da8e4a4fca3b5668d5a2ea7476db44b3f
commit-date: 2026-09-24
host: x86_64-unknown-linux-gnu
release: 1.100.0-nightly
LLVM version: 23.1.1
Activity
theemathas commentedon Sep 25, 2026
Also reproduces on
1.99.0-beta.7 (2026-09-19 aa0593682acc35672839)May I know if this code is reduced from real-world code, found by a fuzzer, or something else?
466774321-code commentedon Sep 25, 2026
from a fuzzer
nikic commentedon Sep 25, 2026
https://gist.github.com/nikic/17d06ccb9a167ec350870135ebdfde41 (unreduced) produces different exit code from llubi after opt -passes=instcombine.
nikic commentedon Sep 25, 2026
llvm/llvm-project#226504
[-]Miscompilation on nightly: program prints 3 instead of 2 at opt-level=2 and 3[/-][+]Miscompilation: program prints 3 instead of 2 at opt-level=2 and 3[/+]3 remaining items
rustbot commentedon Sep 26, 2026
Assigning P-medium (discussion on Zulip).
andjo403 commentedon Sep 28, 2026
Fix merged upstream see llvm/llvm-project#226783
Hoverbear commentedon Oct 1, 2026
This started in 1b29cfd (unsurprisingly).
searched nightlies: from nightly-2026-07-05 to nightly-2026-08-15
regressed nightly: nightly-2026-08-06
searched commit range: 1ed2df6...7608eb7
regressed commit: 1b29cfd
bisected with cargo-bisect-rustc v0.6.11
Host triple: x86_64-unknown-linux-gnu
Reproduce with:
lqd commentedon Oct 1, 2026
1.99 was released earlier today, this is now on stable. Adjusting labels.
Auto merge of #164254 - nikic:llvm-update-4, r=cuviper
Auto merge of #164254 - nikic:llvm-update-4, r=cuviper
Auto merge of #164254 - nikic:llvm-update-4, r=cuviper