Repository navigation
Codegen regression involving assume/unreachable_unchecked #110551
Description
Code
I tried this code:
pub fn f(a: Option<u32>) -> u32 {
match a {
None => {}
Some(_) => unsafe { std::hint::unreachable_unchecked() }
}
a.unwrap()
}I expected to see this happen: no branch instructions emitted, unreachable_unchecked makes an assumption that a is None, so unwrap should be inlined and optimized as a panic.
Instead, this happened: there is a discriminant check still emitted.
Version it worked on
It most recently worked on: nightly-2023-03-26
Version with regression
; rustc +nightly-2023-03-27 --version --verbose
rustc 1.70.0-nightly (db0cbc48d 2023-03-26)
binary: rustc
commit-hash: db0cbc48d4aaa300713a95d9b317a365a474490c
commit-date: 2023-03-26
host: aarch64-unknown-linux-gnu
release: 1.70.0-nightly
LLVM version: 16.0.0
ASM diff
See godbolt: https://godbolt.org/z/5WKTY99Te
Bisection results
Regression occurred in #106428 (cc @saethlin).
searched nightlies: from nightly-2023-03-01 to nightly-2023-04-01
regressed nightly: nightly-2023-03-27
searched commit range: 0c61c7a...db0cbc4
regressed commit: 2420bd3
bisected with cargo-bisect-rustc v0.6.6
Host triple: aarch64-unknown-linux-gnu
Reproduce with:
cargo bisect-rustc --start=2023-03-01 --end=2023-04-01 --regress=success --script=./t.sht.sh
#!/bin/sh
set -ex
rustc t.rs --crate-type=lib --emit=asm -O && cat ./t.s | grep -E "cbz\s+w0, .LBB0_2"(if you want to test on x86_64 replace "cbz\s+w0, .LBB0_2" with "testl\s+%edi, %edi")
t.rs
pub fn f(a: Option<i32>) -> i32 {
unsafe { if !a.is_none() { std::hint::unreachable_unchecked() } }
return a.unwrap();
}History
@heckad originally noticed the problem and opened #110456, then @WaffleLapkin suggested that this is a compiler issue, then @bugadani noticed that this is a regression, then @WaffleLapkin bisected and opened this issue.
Activity
saethlin commentedon Apr 19, 2023
The end of this regression window is over 2 weeks from now. Why?
Godbolt usually has pretty old nightlies. If I add
--emit=mir: https://godbolt.org/z/YfxfhETfb you can see we have duplicate switch targets, which means that either this commit is broken or godbolt doesn't have it: 2a628bdlqd commentedon Apr 19, 2023
godbolt seems to have
rustc 1.71.0-nightly (d0f204e4d 2023-04-16)?WaffleLapkin commentedon Apr 19, 2023
Because I knew that
2023-04-01reproduces the regression, and wanted to cut some time bisecting. For reference I can reproduce the same issue with+nightly-2023-04-19.+nightly-2023-04-19 --emit=mir
saethlin commentedon Apr 19, 2023
To be clear, separate from this issue I believe that this MIR:
is a bug.
I do not know what impact resolving that would have on this issue. But the
InstCombinehelper that combines switch targets was (notionally) supposed to prevent this.saethlin commentedon Apr 19, 2023
Yeah, I'm pretty sure that is the root cause.
apiraino commentedon Apr 20, 2023
WG-prioritization assigning priority (Zulip discussion).
@rustbot label -I-prioritize +P-medium
Auto merge of #110569 - saethlin:mir-pass-cooperation, r=cjgillot
Auto merge of #110569 - saethlin:mir-pass-cooperation, r=cjgillot