diff --git a/clang/test/CodeGen/available-externally-suppress.c b/clang/test/CodeGen/available-externally-suppress.c --- a/clang/test/CodeGen/available-externally-suppress.c +++ b/clang/test/CodeGen/available-externally-suppress.c @@ -1,6 +1,9 @@ -// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s -// RUN: %clang_cc1 -O2 -fno-inline -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s -// RUN: %clang_cc1 -flto -O2 -fno-inline -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s -check-prefix=LTO +// RUN: %clang_cc1 -fno-experimental-new-pass-manager -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s +// RUN: %clang_cc1 -fno-experimental-new-pass-manager -O2 -fno-inline -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s +// RUN: %clang_cc1 -fno-experimental-new-pass-manager -flto -O2 -fno-inline -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s -check-prefix=LTO +// RUN: %clang_cc1 -fexperimental-new-pass-manager -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s +// RUN: %clang_cc1 -fexperimental-new-pass-manager -O2 -fno-inline -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s +// RUN: %clang_cc1 -fexperimental-new-pass-manager -flto -O2 -fno-inline -emit-llvm -o - -triple x86_64-apple-darwin10 %s | FileCheck %s -check-prefix=LTO // Ensure that we don't emit available_externally functions at -O0. // Also should not emit them at -O2, unless -flto is present in which case diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -812,8 +812,10 @@ // available externally globals. Eventually they will be suppressed during // codegen, but eliminating here enables more opportunity for GlobalDCE as it // may make globals referenced by available external functions dead and saves - // running remaining passes on the eliminated functions. - MPM.addPass(EliminateAvailableExternallyPass()); + // running remaining passes on the eliminated functions. These should be + // preserved during prelinking for link-time inlining decisions. + if (!LTOPreLink) + MPM.addPass(EliminateAvailableExternallyPass()); if (EnableOrderFileInstrumentation) MPM.addPass(InstrOrderFilePass()); diff --git a/llvm/test/Other/available-externally-lto.ll b/llvm/test/Other/available-externally-lto.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Other/available-externally-lto.ll @@ -0,0 +1,23 @@ +; Ensure that we don't emit available_externally functions at -O2, unless +; -flto is present in which case we should preserve them for link-time inlining +; decisions. +; RUN: opt < %s -S -passes='default' | FileCheck %s +; RUN: opt < %s -S -passes='lto-pre-link' | FileCheck %s --check-prefix=LTO + +@x = common local_unnamed_addr global i32 0, align 4 + +define void @test() local_unnamed_addr #0 { +entry: + tail call void @f0(i32 17) + ret void +} + +; CHECK: declare void @f0(i32) +; LTO: define available_externally void @f0(i32 %y) +define available_externally void @f0(i32 %y) local_unnamed_addr #0 { +entry: + store i32 %y, i32* @x, align 4 + ret void +} + +attributes #0 = { noinline }