This is an archive of the discontinued LLVM Phabricator instance.

[GlobalOpt] Don't replace the aliasee if it has other references.
ClosedPublic

Authored by DianQK on Mar 3 2023, 9:25 PM.

Details

Summary

As long as aliasee has @llvm.used or @llvm.compiler.used references, we cannot do the related replace or delete operations. Even if it is a Local Linkage, we cannot infer if there is no other use for it, such as asm or other future added cases.

This fixes https://github.com/rust-lang/rust/issues/108030.

This is a minimal reproduction that works on macOS and Linux (x86_64).

Diff Detail

Event Timeline

DianQK created this revision.Mar 3 2023, 9:25 PM
DianQK requested review of this revision.Mar 3 2023, 9:25 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 3 2023, 9:25 PM
DianQK retitled this revision from [GlobalOpt] Don't replace the aliasee if it has other references to [GlobalOpt] Don't replace the aliasee if it has other references..Mar 3 2023, 9:30 PM
DianQK added reviewers: MaskRay, nikic, fhahn, respindola.
DianQK edited the summary of this revision. (Show Details)Mar 3 2023, 9:40 PM
nikic added a reviewer: pcc.Mar 4 2023, 12:40 AM
nikic added a subscriber: pcc.

Looks reasonable to me, but @MaskRay or @pcc should review this wrt alias semantics. Note that you have a failing GlobalOpt test.

llvm/lib/Transforms/IPO/GlobalOpt.cpp
2219

The "OtherThanLLVMUsed" part here no longer makes sense?

DianQK updated this revision to Diff 502368.Mar 4 2023, 3:42 AM

Fix test.

DianQK marked an inline comment as done.Mar 4 2023, 3:44 AM
DianQK added inline comments.
llvm/lib/Transforms/IPO/GlobalOpt.cpp
2219

Yes, thanks.

DianQK edited the summary of this revision. (Show Details)Mar 4 2023, 3:53 AM
DianQK marked an inline comment as done.

How does rustc use llvm.compiler.used or llvm.uses?

As long as aliasee has @llvm.used or @llvm.compiler.used references, we cannot do the related replace or delete operations. Even if it is a Local Linkage, we cannot infer if there is no other use for it, such as asm or other future added cases.

This is vague. I think we need tests to demonstrate that it is unsafe to replace. If you can write an inline asm expression or module-level asm to demonstrate the issue, change the test to reflect the case.

Do we have a use case with an internal alias and an aliasee which are not in llvm.used/llvm.compiler.used? If no, we should add such a test.

pcc added a comment.Mar 7 2023, 9:41 PM

To be honest, I would rather we look at removing OptimizeGlobalAliases altogether. As I explained in D65118, these kinds of trivial alias "optimizations" on their own can be more harmful than helpful.

DianQK updated this revision to Diff 503342.Mar 8 2023, 6:06 AM

How does rustc use llvm.compiler.used or llvm.uses?

I have found at least two cases where rustc is used.

The first is the sym keyword used to keep the referenced symbol in the global_asm macro, which in this case would be marked as llvm.compiler.used.

extern "Rust" {
    pub fn foo1();
    pub fn foo2();
}

fn bar1() {}
fn bar2() {}

core::arch::global_asm!(".global foo1
foo1: jmp {}
.global foo2
foo2: jmp {}
", sym bar1, sym bar2);

The second is to used declare that the symbol is reserved.

#[used]
fn foo() {}

If we focus only on the first case, https://rust.godbolt.org/z/Ph419hqWv is a minimal example.
Due to the LTO pipeline of rustc, this optimized IR will be optimized again, which triggers the current problem, where bar2 replaces bar1 and removes bar1.

If you can write an inline asm expression or module-level asm to demonstrate the issue, change the test to reflect the case.

Added.

Do we have a use case with an internal alias and an aliasee which are not in llvm.used/llvm.compiler.used? If no, we should add such a test.

I think the @fa2 in the previous llvm/test/Transforms/GlobalOpt/alias-used.ll use case corresponds to this use case.

It looks like a similar problem occurs in MergeFunctions, see Rust #99059 and D127751.

DianQK added a comment.Mar 8 2023, 6:08 AM

To be honest, I would rather we look at removing OptimizeGlobalAliases altogether. As I explained in D65118, these kinds of trivial alias "optimizations" on their own can be more harmful than helpful.

Due to my limited skills, I can't evaluate the benefits of OptimizeGlobalAliases.
As you said, I find optimizing this kind of problem a bit complicated, especially when it comes to different linkage handling.
How about adding some additional assertions when removing aliases? If possible, this one that at least problems like could be detected much earlier.

DianQK updated this revision to Diff 503345.Mar 8 2023, 6:16 AM

Add comments

DianQK updated this revision to Diff 506936.Mar 21 2023, 6:07 AM

Fixes CI.

DianQK added inline comments.
polly/test/Support/dumpfunction.ll
23 ↗(On Diff #506936)

@Meinersbur GlobalOpt may optimize alias, and this patch modifies the behavior. In dumpfunction.ll, this alias doesn't seem to make sense. Can I remove it?

DianQK updated this revision to Diff 516023.Apr 21 2023, 9:05 PM

Rebase and ping. At least this prevents an unsound case.

nikic accepted this revision.Apr 26 2023, 12:45 AM

LGTM

This revision is now accepted and ready to land.Apr 26 2023, 12:45 AM
DianQK updated this revision to Diff 517407.Apr 26 2023, 5:41 PM

Thanks. Rebase and ensure that the pre-merge check passes.