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

Cannot opt out of LLVM MergeFunctions pass on stable #64310

Closed
michaelwoerister opened this issue Sep 9, 2019 · 15 comments · Fixed by #67393
Closed

Cannot opt out of LLVM MergeFunctions pass on stable #64310

michaelwoerister opened this issue Sep 9, 2019 · 15 comments · Fixed by #67393
Labels
A-codegen Area: Code generation A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness O-macos Operating system: macOS T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@michaelwoerister
Copy link
Member

LLVM's MergeFunctions introduces aliases which can trigger a bug in macOS's ld64 linker when compiling with ThinLTO: https://github.com/froydnj/ld64-aliases-bug

For this reason Firefox has to be built with a patched version of ld64 when compiling with xLTO. Since the bug in question is pretty nasty (the above example shows a program just returning a different value with no indication that anything is wrong), we should probably try to not trigger it.

Right now, however, it seems that one cannot even turn the MergeFunctions pass off in stable Rust. (I wonder if the pass should even be disabled by default on macOS?)

cc @rust-lang/compiler, @rust-lang/wg-codegen & @peterhj (this seems related to #57356)

@michaelwoerister michaelwoerister added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-codegen Area: Code generation T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness labels Sep 9, 2019
@nox
Copy link
Contributor

nox commented Sep 9, 2019 via email

@michaelwoerister
Copy link
Member Author

It's not a bug in mergefunc. It might not even be a bug in ThinLTO. It's just that mergefunc is the only thing in rustc that generates symbol aliases in LLVM IR, and these are what can lead to "miscompilations" when using the macOS linker.

@nikic
Copy link
Contributor

nikic commented Sep 9, 2019

Has the ld64 bug been reported somewhere?

@nox
Copy link
Contributor

nox commented Sep 9, 2019

It's not a bug in mergefunc. It might not even be a bug in ThinLTO. It's just that mergefunc is the only thing in rustc that generates symbol aliases in LLVM IR, and these are what can lead to "miscompilations" when using the macOS linker.

We could use mergefunc-use-aliases to prevent the pass from emitting aliases on macOS, AFAIK.

https://github.com/llvm-mirror/llvm/blob/2afd9e698dbfc2f3011baf3bfdb47d03c253272b/lib/Transforms/IPO/MergeFunctions.cpp#L168-L171

@nikic
Copy link
Contributor

nikic commented Sep 9, 2019

@nox This is already supported via either -Z merge-functions=trampolines or merge_functions: MergeFunctions::Trampolines in the target spec.

@nox
Copy link
Contributor

nox commented Sep 9, 2019

@nikic Do you mean that the test case also fails with mergefunc-use-aliases enabled, or that we already have a knob to disable them?

@nox
Copy link
Contributor

nox commented Sep 9, 2019

if get_major_version() >= 8 {
match sess.opts.debugging_opts.merge_functions
.unwrap_or(sess.target.target.options.merge_functions) {
MergeFunctions::Disabled |
MergeFunctions::Trampolines => {}
MergeFunctions::Aliases => {
add("-mergefunc-use-aliases");
}
}
}

Answering my own question, we already have a knob for that.

@nox
Copy link
Contributor

nox commented Sep 9, 2019

Which was added because aliases already cause issues on other architectures.

@peterhj
Copy link
Contributor

peterhj commented Sep 9, 2019

As @nikic and @nox point to there is the unstable -Z merge-functions option which I've only tested on nightly. I guess there could be a stabilized -C merge-functions option, but maybe what you really want to do is to patch the x86_64 macos target definition (I believe this is the correct one: https://github.com/rust-lang/rust/blob/97ba4c95d00108ac79c86d2bbc6834b1fef008a2/src/librustc_target/spec/x86_64_apple_darwin.rs).

@michaelwoerister
Copy link
Member Author

@nikic

Has the ld64 bug been reported somewhere?

Yes, I've been told that it has been reported to Apple.

On nightly, one can already control the mergefunc pass. On stable, however, one is stuck with the default behavior. That's what this issue is mostly about.

@pnkfelix
Copy link
Member

pnkfelix commented Sep 10, 2019

@michaelwoerister just want to double-check my understanding: I would have thought one could use the -C options -C no-prepopulate-passes and -C passes=val to override the set of passes, even on the stable channel.

Am I incorrect about this?

(If I am correct, I nonetheless will admit that this is an ugly (and very fragile) method to opt out of the MergeFunctions pass)

@michaelwoerister
Copy link
Member Author

@pnkfelix I think that is correct, yes. It would be rather hard, however, to re-create the set of passes meaningfully, I suspect. Even the compiler delegates this to methods within LLVM, iirc.

@nikic
Copy link
Contributor

nikic commented Sep 10, 2019

I think using -C llvm-args=-mergefunc-use-aliases=false might work on stable.

@nox
Copy link
Contributor

nox commented Sep 22, 2019

So did that help, @michaelwoerister?

@michaelwoerister
Copy link
Member Author

Unfortunately not. Specifying this gives me:

rustc: for the -mergefunc-use-aliases option: may only occur zero or one times!

@jonas-schievink jonas-schievink added A-linkage Area: linking into static, shared libraries and binaries O-macos Operating system: macOS labels Dec 10, 2019
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue Dec 19, 2019
…, r=varkor

Enable opting out of specific default LLVM arguments.

`rustc` by default adds a few arguments to LLVM (like `-mergefunc-use-aliases` for example). With this PR `rustc` will only emit these arguments if the same argument has not already been specified by the user via `-Cllvm-args`. This enables opting out of these defaults.

The PR also removes a PGO specific `-Z` flag the effect of which can also be easily achieved by `-Cllvm-args`.

Fixes rust-lang#64310.
Centril added a commit to Centril/rust that referenced this issue Dec 21, 2019
…, r=varkor

Enable opting out of specific default LLVM arguments.

`rustc` by default adds a few arguments to LLVM (like `-mergefunc-use-aliases` for example). With this PR `rustc` will only emit these arguments if the same argument has not already been specified by the user via `-Cllvm-args`. This enables opting out of these defaults.

The PR also removes a PGO specific `-Z` flag the effect of which can also be easily achieved by `-Cllvm-args`.

Fixes rust-lang#64310.
@bors bors closed this as completed in 6e3b1d6 Dec 21, 2019
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-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness O-macos Operating system: macOS T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants