Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark &mut pointers as noalias once LLVM no longer miscompiles them #31681

Closed
bstrie opened this issue Feb 15, 2016 · 26 comments
Closed

Mark &mut pointers as noalias once LLVM no longer miscompiles them #31681

bstrie opened this issue Feb 15, 2016 · 26 comments
Labels
A-codegen Area: Code generation A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. I-slow Issue: Problems and improvements with respect to performance of generated code.

Comments

@bstrie
Copy link
Contributor

bstrie commented Feb 15, 2016

This issue tracks the undoing of the workaround introduced in #31545 on account of a bug in LLVM. cc @dotdash

@bstrie bstrie added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-codegen Area: Code generation A-optimization labels Feb 15, 2016
@jplatte
Copy link
Contributor

jplatte commented Feb 18, 2016

Was just reading about this, and it was a little hard to find the LLVM bug report, so for reference, here it is.

@eefriedman
Copy link
Contributor

eefriedman commented May 31, 2016

I've been working through the LLVM optimization passes to find noalias-related bugs. Known issues:

Some of these are less important because they can't caused a wrong value, only a segfault.

There are probably a few more lurking issues, but hopefully I've found most of them.


(Edited by bluss 2016-12-15 to strike out fixed bug)
(Edited by mbrubeck 2017-03-30 to link to new LLVM bugzilla domain)
(Edited by scottmcm 2018-03-29 to strike out fixed bug)

@mrhota
Copy link
Contributor

mrhota commented Aug 6, 2016

@eefriedman LLVM bug 27859 is closed.

bluss added a commit to bluss/rust that referenced this issue Sep 9, 2016
…with_element

Due to missing noalias annotations for &mut T in general (issue rust-lang#31681),
in larger programs extend_from_slice and extend_with_element may both
compile very poorly. What is observed is that the .set_len() calls are
not lifted out of the loop, even for `Vec<u8>`.

Use a local length variable for the Vec length instead, and use a scope
guard to write this value back to self.len when the scope ends or on
panic. Then the alias analysis is easy.

This affects extend_from_slice, extend_with_element, the vec![x; n]
macro, Write impls for Vec<u8>, BufWriter, etc (but may / may not
have triggered since inlining can be enough for the compiler to get it right).
bors added a commit that referenced this issue Sep 12, 2016
…d, r=alexcrichton

Work around pointer aliasing issue in Vec::extend_from_slice, extend_with_element

Due to missing noalias annotations for &mut T in general (issue #31681),
in larger programs extend_from_slice and extend_with_element may both
compile very poorly. What is observed is that the .set_len() calls are
not lifted out of the loop, even for `Vec<u8>`.

Use a local length variable for the Vec length instead, and use a scope
guard to write this value back to self.len when the scope ends or on
panic. Then the alias analysis is easy.

This affects extend_from_slice, extend_with_element, the vec![x; n]
macro, Write impls for Vec<u8>, BufWriter, etc (but may / may not
have triggered since inlining can be enough for the compiler to get it right).

Fixes #32155
Fixes #33518
Closes #17844
@gnzlbg
Copy link
Contributor

gnzlbg commented Sep 15, 2016

@eefriedman bug 25422 should be fixed.

Any progress on bug 27860 ?


(Edited by mbrubeck 2017-03-30 to link to new LLVM bugzilla domain)

@pmarcelll
Copy link
Contributor

pmarcelll commented Jan 16, 2017

NewGVN was recently merged into LLVM (still experimental), it's a rewrite of the global value numbering algorithm. The last remaining bug on our list is bug in the old gvn implementation. I compiled the example codes in the bug report with the new gvn algorithm, and they work fine, so hopefully LLVM 5.0 will stabilize NewGVN and we can turn this optimization back on.
EDIT: NewGVN integration into LLVM tracked here

@jrmuizel
Copy link
Contributor

I talked with Davide Italiano from LLVM and the goal is for NewGVN to be turned on in LLVM 6.0.
Given that and the fact that https://bugs.llvm.org//show_bug.cgi?id=27860 also affects code that doesn't use restrict/noalias I wonder if we could try turning this on? Even if we could only use this when compiling in panic=abort mode (as it seems many of the codegen issues were related to exceptions).

#42047 is a reduced test case of a real performance problem that's helped by this that we're running into with WebRender so it would be nice to fix this sooner rather than later.

@eira-fransham
Copy link

eira-fransham commented Aug 2, 2017

I support enabling this if and only if panic = "abort". Even if having the codegen be different depending on panic mode is not currently supported it would be something deserving of an RFC in my opinion, since there are a bunch of possible optimisations that this could enable, like removing zeroing when initialising an array.

Maybe if "treat function calls as possible branch point" is a function-level annotation in LLVM the only difference would be emitting/not emitting that.

@jrmuizel
Copy link
Contributor

jrmuizel commented Aug 4, 2017

Is it possible for us to get a cargobomb run with the patch reverted to see if we trigger any bad codegen?

@dpc
Copy link
Contributor

dpc commented Aug 5, 2017

Any best guesses when this improvement would be available in Rust nightly (with and without panic = "abort")? It would affect the design and implementation of performance critical crates I'm working on. If it's couple of months, it might be worth waiting. If it's a year, it might be worth to workaround in the code.

@arielb1
Copy link
Contributor

arielb1 commented Aug 6, 2017

@eefriedman

Is PR27860 actually a problem for Rust? I think every time we emit noalias we also emit dereferencable. Unless LLVM considers every GEP of the pointer as dereferencable, even in the presence of e.g. bounds checks (oops).

@arielb1 arielb1 reopened this Aug 9, 2017
@oyvindln
Copy link
Contributor

oyvindln commented Aug 9, 2017

I support enabling this if and only if panic = "abort".

Maybe a -Z enable-noalias or similar option could be added as a start to make it easier to test where the lack of noalias makes a difference.

@bstrie bstrie added the I-slow Issue: Problems and improvements with respect to performance of generated code. label Sep 15, 2017
@matthiaskrgr
Copy link
Member

@oyvindln if you want to turn on newgvn to compare things, RUSTFLAGS="-C llvm-args=-enable-newgvn" might work.

@pcwalton
Copy link
Contributor

It's unclear from reading this what the state of this bug is. Do we still believe that NewGVN will fix this issue?

@arielb1
Copy link
Contributor

arielb1 commented Sep 28, 2017

@pcwalton

I think all "noalias-exclusive" bugs are fixed, so it might be worth giving it a try and opening a PR.

@cuviper
Copy link
Member

cuviper commented Sep 28, 2017

Does that enablement need to be conditional on LLVM version?

@arielb1
Copy link
Contributor

arielb1 commented Sep 28, 2017

I think. 4.0 should be fine.

@bstrie
Copy link
Contributor Author

bstrie commented Oct 20, 2017

Update: there's now a -Z flag for opting-in to this on an experimental basis: #45012. It also seems as though the behavior is enabled by default for panic=abort builds. However, I think this might be worth keeping open until we concretely determine whether or not we'll be able to turn this on for panic=unwind builds (see #45029 ).

@alexbool
Copy link
Contributor

What's the state of this given that LLVM has been upgraded to 6.0?

@scottmcm
Copy link
Member

scottmcm commented Mar 3, 2018

To help finding this issue: the -Z flag is mutable_noalias.

@scottmcm
Copy link
Member

Looks like the last part of the checklist above landed with https://reviews.llvm.org/D38619#937247

@nox
Copy link
Contributor

nox commented Apr 2, 2018

Should we make a PR to always enable mutable_noalias and see what happens on the CI and Crater?

Cc @rust-lang/wg-codegen

nikic added a commit to nikic/rust that referenced this issue May 17, 2018
This used to be disabled due to LLVM bugs in the handling of
noalias information in conjunction with unwinding. However,
according to rust-lang#31681 all known LLVM bugs have been fixed by
LLVM 6.0, so it's probably time to reenable this optimization.

Noalias annotations will not be emitted by default if either
-C panic=abort (as previously) or LLVM >= 6.0 (new).

-Z mutable-noalias=no is left as an escape-hatch to allow
debugging problems suspected to stem from this change.
bors added a commit that referenced this issue May 19, 2018
Emit noalias on &mut parameters by default

This used to be disabled due to LLVM bugs in the handling of
noalias information in conjunction with unwinding. However,
according to #31681 all known LLVM bugs have been fixed by
LLVM 6.0, so it's probably time to reenable this optimization.

-Z no-mutable-noalias is left as an escape-hatch to debug problems
suspected to stem from this change.
@nikic
Copy link
Contributor

nikic commented May 21, 2018

As #50744 has landed, this can be closed.

@alexcrichton
Copy link
Member

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. I-slow Issue: Problems and improvements with respect to performance of generated code.
Projects
None yet
Development

No branches or pull requests