Uh oh!
There was an error while loading. Please reload this page.
Never return uninhabited values at all - #59639
Conversation
sanxiyn
commented
Apr 3, 2019
@bors r+ |
bors
commented
Apr 3, 2019
📌 Commit fb575c0 has been approved by |
Never return uninhabited values at all Functions with uninhabited return values are already marked `noreturn`, but we were still generating return instructions for this. When running with `C passes=lint`, LLVM prints: Unusual: Return statement in function with noreturn attribute The LLVM manual makes a stronger statement about `noreturn` though: > This produces undefined behavior at runtime if the function ever does dynamically return. We now mark such return values with a new `IgnoreMode::Uninhabited`, and emit an `abort` anywhere that would have returned. Fixesrust-lang#48227 cc rust-lang#7463rust-lang#48229 r? @eddyb
Rollup of 5 pull requests Successful merges: - #59076 (Include trailing comma in multiline Debug representation) - #59619 (wasi: Implement more of the standard library) - #59639 (Never return uninhabited values at all) - #59643 (std: Upgrade `compiler_builtins` to fix wasi linkage) - #59664 (Updated the documentation of spin_loop and spin_loop_hint) Failed merges: r? @ghost
Never return uninhabited values at all Functions with uninhabited return values are already marked `noreturn`, but we were still generating return instructions for this. When running with `C passes=lint`, LLVM prints: Unusual: Return statement in function with noreturn attribute The LLVM manual makes a stronger statement about `noreturn` though: > This produces undefined behavior at runtime if the function ever does dynamically return. We now mark such return values with a new `IgnoreMode::Uninhabited`, and emit an `abort` anywhere that would have returned. Fixesrust-lang#48227 cc rust-lang#7463rust-lang#48229 r? @eddyb
Uh oh!
There was an error while loading. Please reload this page.
eddyb
commented
Apr 3, 2019
@bors r- (please do not r+ PRs assigned to me without first trying to ping me on IRC or Discord PM) |
bors
commented
Apr 3, 2019
😪 I'm awake I'm awake |
bors
commented
Apr 3, 2019
💡 This pull request was already approved, no need to approve it again.
|
bors
commented
Apr 3, 2019
📌 Commit fb575c0 has been approved by |
eddyb
commented
Apr 3, 2019
Oh bors is just extremely confusable. @bors r- |
Functions with uninhabited return values are already marked `noreturn`, but we were still generating return instructions for this. When running with `-C passes=lint`, LLVM prints: Unusual: Return statement in function with noreturn attribute The LLVM manual makes a stronger statement about `noreturn` though: > This produces undefined behavior at runtime if the function ever does dynamically return. We now emit an `abort` anywhere that would have tried to return an uninhabited value.
cuviper
commented
Apr 3, 2019
OK, I updated |
eddyb
commented
Apr 4, 2019
Thanks! @bors r+ |
bors
commented
Apr 4, 2019
📌 Commit c2e0d7f has been approved by |
RalfJung
commented
Apr 4, 2019
So we are fine with not letting LLVM remove these branches entirely as being dead code? I recall @cramertj asking for more aggressive dead code removal around uninhabited types. |
sanxiyn
commented
Apr 4, 2019
As can be seen on codegen tests, we generate unreachable for uninhabited types after this PR. This should allow LLVM to optimize. (Whether LLVM in fact optimizes is a different question though.) |
Never return uninhabited values at all Functions with uninhabited return values are already marked `noreturn`, but we were still generating return instructions for this. When running with `-C passes=lint`, LLVM prints: Unusual: Return statement in function with noreturn attribute The LLVM manual makes a stronger statement about `noreturn` though: > This produces undefined behavior at runtime if the function ever does dynamically return. We now emit an `abort` anywhere that would have tried to return an uninhabited value. Fixesrust-lang#48227 cc rust-lang#7463rust-lang#48229 r? @eddyb
Never return uninhabited values at all Functions with uninhabited return values are already marked `noreturn`, but we were still generating return instructions for this. When running with `-C passes=lint`, LLVM prints: Unusual: Return statement in function with noreturn attribute The LLVM manual makes a stronger statement about `noreturn` though: > This produces undefined behavior at runtime if the function ever does dynamically return. We now emit an `abort` anywhere that would have tried to return an uninhabited value. Fixesrust-lang#48227 cc rust-lang#7463rust-lang#48229 r? @eddyb
RalfJung
commented
Apr 4, 2019
We generate |
Never return uninhabited values at all Functions with uninhabited return values are already marked `noreturn`, but we were still generating return instructions for this. When running with `-C passes=lint`, LLVM prints: Unusual: Return statement in function with noreturn attribute The LLVM manual makes a stronger statement about `noreturn` though: > This produces undefined behavior at runtime if the function ever does dynamically return. We now emit an `abort` anywhere that would have tried to return an uninhabited value. Fixesrust-lang#48227 cc rust-lang#7463rust-lang#48229 r? @eddyb
Never return uninhabited values at all Functions with uninhabited return values are already marked `noreturn`, but we were still generating return instructions for this. When running with `-C passes=lint`, LLVM prints: Unusual: Return statement in function with noreturn attribute The LLVM manual makes a stronger statement about `noreturn` though: > This produces undefined behavior at runtime if the function ever does dynamically return. We now emit an `abort` anywhere that would have tried to return an uninhabited value. Fixesrust-lang#48227 cc rust-lang#7463rust-lang#48229 r? @eddyb
Never return uninhabited values at all Functions with uninhabited return values are already marked `noreturn`, but we were still generating return instructions for this. When running with `-C passes=lint`, LLVM prints: Unusual: Return statement in function with noreturn attribute The LLVM manual makes a stronger statement about `noreturn` though: > This produces undefined behavior at runtime if the function ever does dynamically return. We now emit an `abort` anywhere that would have tried to return an uninhabited value. Fixesrust-lang#48227 cc rust-lang#7463rust-lang#48229 r? @eddyb
eddyb
commented
Apr 4, 2019
@RalfJung Can you open an issue? It's not clear to me what effect this has, AFAIK we produce an |
Rollup of 8 pull requests Successful merges: - #59470 (Document std::fs::File close behavior ignoring errors) - #59555 (update miri) - #59556 (update stdsimd) - #59596 (Forward formatter settings to bounds of `Range<T>` in `fmt::Debug` impl) - #59639 (Never return uninhabited values at all) - #59671 (Make some of lexer's API private) - #59685 (Add description for -Os and -Oz in rustc.1) - #59686 (Temporarily disable stack probing for gnux32.) Failed merges: r? @ghost
cuviper
commented
Apr 4, 2019
I'll happily investigate any bad codegen from this. I would think that any paths that would reach one of these really ought to be statically unreachable anyway, such that LLVM will still know that even the |
cuviper
commented
Apr 5, 2019
The nightlies before and after this change are: I looked at the I also did a crude search for That's a fair increase, although we can't immediately tell if those are in performance sensitive areas, and they may just be from normal new code. (For more, 2019-04-03 had 76947, and beta 70510.) Here is the perf report before and after the #59695 rollup PR that included this. |
cuviper
commented
Apr 5, 2019
It serves as the block terminator, if nothing else. https://llvm.org/docs/LangRef.html#unreachable-instruction
|
RalfJung
commented
Apr 8, 2019
The I opened an issue at #59793 where I also demonstrate the effect of this. |
RalfJung
commented
Apr 8, 2019
Which exact example did you use for this? I cannot reproduce. |
cuviper
commented
Apr 8, 2019
Yes, but a Now, we could change this to just
From #48227: #![crate_type = "lib"]pubfnlines<'a>(left:&'astr){iter(left.lines());}fniter<I,T>(left:I)whereI:Clone + Iterator<Item = T> + DoubleEndedIterator,T:PartialEq,{let _left_count = left.clone().count();}Optimization removes it: From #48229: fnmain(){(1 .. 9).filter(|_| true).sum::<u32>();}Optimization removes it: |
cuviper
commented
Apr 8, 2019
FWIW, both of those example traps come from the blanket rust/src/libcore/iter/traits/iterator.rs Lines 1681 to 1685 in 3750348 |
RalfJung
commented
Apr 8, 2019
Ah, those are truly unreachable traps get removed -- LLVM statically proves that that line cannot be reached. That has nothing to do with the
I see. That's a bit weird but whatever, if that's how LLVM works that's fine for me. ;) My point was that the |
Functions with uninhabited return values are already marked
noreturn,but we were still generating return instructions for this. When running
with
-C passes=lint, LLVM prints:The LLVM manual makes a stronger statement about
noreturnthough:We now emit an
abortanywhere that would have tried to return anuninhabited value.
Fixes#48227
cc #7463#48229
r? @eddyb