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

Workaround LLVM optimizer bug by not marking &mut pointers as noalias #31545

Merged
merged 1 commit into from
Feb 12, 2016

Conversation

dotdash
Copy link
Contributor

@dotdash dotdash commented Feb 10, 2016

LLVM's memory dependence analysis doesn't properly account for calls
that could unwind and thus effectively act as a branching point. This
can lead to stores that are only visible when the call unwinds being
removed, possibly leading to calls to drop() functions with b0rked
memory contents.

As there is no fix for this in LLVM yet and we want to keep
compatibility to current LLVM versions anyways, we have to workaround
this bug by omitting the noalias attribute on &mut function arguments.
Benchmarks suggest that the performance loss by this change is very
small.

Thanks to @RalfJung for pushing me towards not removing too many
noalias annotations and @alexcrichton for helping out with the test for
this bug.

Fixes #29485

@rust-highfive
Copy link
Collaborator

r? @jroesch

(rust_highfive has picked a reviewer for you, use r? to override)

@@ -265,7 +265,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
// on memory dependencies rather than pointer equality
let interior_unsafe = mt.ty.type_contents(ccx.tcx()).interior_unsafe();

if mt.mutbl == hir::MutMutable || !interior_unsafe {
if mt.mutbl != hir::MutMutable && !interior_unsafe {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may not quite be understanding what's going on here, but doesn't this mean that &usize will have the noalias attribute applied?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and that's intentional. The change is supposed to only affect &mut references (and '&' ones with unsafe interiors), because those are the ones that could have stores that would expose this bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, also note that WRT &usize this is not a change, those pointers got the noalias attribute before as well (the || got changed into a &&). As the comment above this change says, noalias is about memory dependencies rather than plain pointer equality.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, right!

@alexcrichton
Copy link
Member

Looks like the travis failure is legit in that a codegen test needs to be udpated.

LLVM's memory dependence analysis doesn't properly account for calls
that could unwind and thus effectively act as a branching point. This
can lead to stores that are only visible when the call unwinds being
removed, possibly leading to calls to drop() functions with b0rked
memory contents.

As there is no fix for this in LLVM yet and we want to keep
compatibility to current LLVM versions anyways, we have to workaround
this bug by omitting the noalias attribute on &mut function arguments.
Benchmarks suggest that the performance loss by this change is very
small.

Thanks to @RalfJung for pushing me towards not removing too many
noalias annotations and @alexcrichton for helping out with the test for
this bug.

Fixes rust-lang#29485
@dotdash
Copy link
Contributor Author

dotdash commented Feb 10, 2016

Updated the codegen test, completely forgot about those and only ran the new test before opening the PR

@alexcrichton
Copy link
Member

@bors: r+ a17fb64

@bors
Copy link
Contributor

bors commented Feb 11, 2016

⌛ Testing commit a17fb64 with merge 98ec51a...

bors added a commit that referenced this pull request Feb 11, 2016
LLVM's memory dependence analysis doesn't properly account for calls
that could unwind and thus effectively act as a branching point. This
can lead to stores that are only visible when the call unwinds being
removed, possibly leading to calls to drop() functions with b0rked
memory contents.

As there is no fix for this in LLVM yet and we want to keep
compatibility to current LLVM versions anyways, we have to workaround
this bug by omitting the noalias attribute on &mut function arguments.
Benchmarks suggest that the performance loss by this change is very
small.

Thanks to @RalfJung for pushing me towards not removing too many
noalias annotations and @alexcrichton for helping out with the test for
this bug.

Fixes #29485
@bors bors merged commit a17fb64 into rust-lang:master Feb 12, 2016
@ticki
Copy link
Contributor

ticki commented Feb 15, 2016

This seems like a horrible performance loss. Can you post the benchmarks?

@dotdash
Copy link
Contributor Author

dotdash commented Feb 15, 2016

@ticki the results of the benchmarks we made are in #29485 -- do you have any results that show that "horrible performance loss"?

@ticki
Copy link
Contributor

ticki commented Feb 15, 2016

Well, I haven't benchmarked this change, but in my experience, disabling noalias in GCC gave bad performance.

@dotdash
Copy link
Contributor Author

dotdash commented Feb 15, 2016

@ticki what exactly do you mean by "disabling noalias in GCC"? Making it ignore the restrict keyword? Because when comparing to C, that's basically the only change we made here.

@ticki
Copy link
Contributor

ticki commented Feb 15, 2016

-fno-strict-aliasing, that is.

@dotdash
Copy link
Contributor Author

dotdash commented Feb 15, 2016

That option disables TBAA, which rust does not use at all. The scope of
this change is smaller than that of that option.

-fno-strict-aliasing, that is.


Reply to this email directly or view it on GitHub
#31545 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unwinding through fn() references across crates causes the behavior to depend on the optimization level
6 participants