diff --git a/bolt/docs/CommandLineArgumentReference.md b/bolt/docs/CommandLineArgumentReference.md index 0dbf6f59d5e88..bf706ba3a1cdc 100644 --- a/bolt/docs/CommandLineArgumentReference.md +++ b/bolt/docs/CommandLineArgumentReference.md @@ -724,7 +724,7 @@ - `--plt=` - Optimize PLT calls (requires linking with -znow) + Optimize PLT calls (requires linking with -znow on non-x86 architectures) - `none`: do not optimize PLT calls - `hot`: optimize executed (hot) PLT calls - `all`: optimize all PLT calls diff --git a/bolt/lib/Passes/PLTCall.cpp b/bolt/lib/Passes/PLTCall.cpp index 90b5f586a7bad..a41b3870af666 100644 --- a/bolt/lib/Passes/PLTCall.cpp +++ b/bolt/lib/Passes/PLTCall.cpp @@ -23,7 +23,9 @@ namespace opts { extern cl::OptionCategory BoltOptCategory; static cl::opt - PLT("plt", cl::desc("optimize PLT calls (requires linking with -znow)"), + PLT("plt", + cl::desc("optimize PLT calls (requires linking with -znow on " + "non-x86 architectures)"), cl::init(bolt::PLTCall::OT_NONE), cl::values(clEnumValN(bolt::PLTCall::OT_NONE, "none", "do not optimize PLT calls"), @@ -76,7 +78,12 @@ Error PLTCall::runOnFunctions(BinaryContext &BC) { } if (NumCallsOptimized) { - BC.RequiresZNow = true; + // On X86-64, PLT optimization does not require -znow because the indirect + // call through GOT works correctly with lazy binding. At runtime, the + // resolver will populate the GOT entry on first call just like with a + // regular PLT call. + if (!BC.isX86()) + BC.RequiresZNow = true; BC.outs() << "BOLT-INFO: " << NumCallsOptimized << " PLT calls in the binary were optimized.\n"; } diff --git a/bolt/test/runtime/X86/plt-call.c b/bolt/test/runtime/X86/plt-call.c new file mode 100644 index 0000000000000..3ece4c7c16cca --- /dev/null +++ b/bolt/test/runtime/X86/plt-call.c @@ -0,0 +1,14 @@ +// Check that PLT optimization works on X86-64 without -znow. + +// RUN: %clang %cflags %s -o %t.exe -Wl,-q +// RUN: llvm-bolt %t.exe -o %t.bolt --plt=all +// RUN: %t.bolt | FileCheck %s + +// CHECK: Success + +#include + +int main() { + puts("Success"); + return 0; +}