Skip to content

Cannot opt out of LLVM MergeFunctions pass on stable #64310

Closed
@michaelwoerister

Description

@michaelwoerister
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)

Activity

added
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.
A-codegenArea: Code generation
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
on Sep 9, 2019
nox

nox commented on Sep 9, 2019

@nox
Contributor
michaelwoerister

michaelwoerister commented on Sep 9, 2019

@michaelwoerister
MemberAuthor

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

nikic commented on Sep 9, 2019

@nikic
Contributor

Has the ld64 bug been reported somewhere?

nox

nox commented on Sep 9, 2019

@nox
Contributor

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

nikic commented on Sep 9, 2019

@nikic
Contributor

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

nox

nox commented on Sep 9, 2019

@nox
Contributor

@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

nox commented on Sep 9, 2019

@nox
Contributor

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

nox commented on Sep 9, 2019

@nox
Contributor
peterhj

peterhj commented on Sep 9, 2019

@peterhj
Contributor

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

michaelwoerister commented on Sep 10, 2019

@michaelwoerister
MemberAuthor

@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

pnkfelix commented on Sep 10, 2019

@pnkfelix
Member

@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)

11 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationA-linkageArea: linking into static, shared libraries and binariesI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessO-macosOperating system: macOST-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @nox@pnkfelix@nikic@peterhj@jonas-schievink

      Issue actions

        Cannot opt out of LLVM MergeFunctions pass on stable · Issue #64310 · rust-lang/rust