Skip to content

fno-plt问题 #32

@lfeng14

Description

@lfeng14
  • 提交的社区issue
  • 分析思路
    • x
    • y
    • z
  • openeuler社区补丁:
    From c4bb1e6f552d71c3fdcdac2fd1f5e12ad7d82003 Mon Sep 17 00:00:00 2001
    From: luofeng14 <luofeng13@huawei.com>
    Date: Thu, 13 Mar 2025 19:34:49 +0800
    Subject: [PATCH] [Huawei][AArch64] Fix -fno-plt to suppress PLT generation
    
    Clang 17/19 -fno-plt fix: Aligns with GCC by suppressing PLT entries as expected.
    
    Co-authored-by: Chen Zheng
    ---
     llvm/lib/CodeGen/DwarfEHPrepare.cpp           |  6 ++++
     llvm/lib/Target/AArch64/AArch64Subtarget.cpp  | 14 ++++++++
     llvm/test/CodeGen/AArch64/fno-plt.cpp         | 36 +++++++++++++++++++
     .../Analysis/TargetLibraryInfoTest.cpp        |  5 +++
     4 files changed, 61 insertions(+)
     create mode 100644 llvm/test/CodeGen/AArch64/fno-plt.cpp
    
    diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp
    index 32c94de7280c..d8882bd53ed6 100644
    --- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp
    +++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp
    @@ -234,6 +234,12 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() {
       }
       RewindFunction = F.getParent()->getOrInsertFunction(RewindName, FTy);
     
    +#if defined(BUILD_FOR_OPENEULER)
    +  // If -fno-plt is enabled, add NonLazyBind for this library call.
    +  if (F.getParent()->getRtLibUseGOT())
    +    (cast<Function>(RewindFunction.getCallee()))->addFnAttr(Attribute::NonLazyBind);
    +#endif
    +
       // Create the basic block where the _Unwind_Resume call will live.
       if (ResumesLeft == 1) {
         // Instead of creating a new BB and PHI node, just append the call to
    diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
    index 538021ddb2fd..aa6527efbb17 100644
    --- a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
    +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
    @@ -24,6 +24,9 @@
     #include "llvm/CodeGen/MachineFrameInfo.h"
     #include "llvm/CodeGen/MachineScheduler.h"
     #include "llvm/IR/GlobalValue.h"
    +#if defined(BUILD_FOR_OPENEULER)
    +#include "llvm/IR/Module.h"
    +#endif
     #include "llvm/TargetParser/AArch64TargetParser.h"
     
     using namespace llvm;
    @@ -433,9 +436,20 @@ unsigned AArch64Subtarget::classifyGlobalFunctionReference(
     
       // NonLazyBind goes via GOT unless we know it's available locally.
       auto *F = dyn_cast<Function>(GV);
    +#if defined(BUILD_FOR_OPENEULER)
    +// Check if NonLazyBind should go via GOT:
    +// 1. The target is not MachO, or MachO uses NonLazyBind.
    +// 2. The function's parent module requires GOT for runtime library calls.
    +// 3. The symbol is not assumed to be DSO-local.
    +// 4. The symbol does not have local linkage.
    +  if ((!isTargetMachO() || MachOUseNonLazyBind) && F &&
    +      F->getParent()->getRtLibUseGOT() && 
    +      !(TM.shouldAssumeDSOLocal(*GV->getParent(), GV) || GV->hasLocalLinkage()))
    +#else
       if ((!isTargetMachO() || MachOUseNonLazyBind) && F &&
           F->hasFnAttribute(Attribute::NonLazyBind) &&
           !TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
    +#endif
         return AArch64II::MO_GOT;
     
       if (getTargetTriple().isOSWindows()) {
    diff --git a/llvm/test/CodeGen/AArch64/fno-plt.cpp b/llvm/test/CodeGen/AArch64/fno-plt.cpp
    new file mode 100644
    index 000000000000..619e5d1cc60e
    --- /dev/null
    +++ b/llvm/test/CodeGen/AArch64/fno-plt.cpp
    @@ -0,0 +1,36 @@
    +// REQUIRES: build_for_openeuler
    +// RUN: clang -x c++ %s -shared -fno-plt  -O2 -fno-inline  -fPIC   -o noplt.so
    +// RUN: llvm-objdump -d noplt.so | FileCheck %s --check-prefix=CHECK-NO-PLT
    +
    +// RUN: clang -x c++ %s -shared  -O0  -fPIC   -o plt.so
    +// RUN: llvm-objdump -d plt.so | FileCheck %s --check-prefix=CHECK-PLT
    +
    +// RUN: clang -x c++ %s -shared  -O2 -fno-inline  -fPIC   -o plt.so
    +// RUN: llvm-objdump -d plt.so | FileCheck %s --check-prefix=CHECK-PLT
    +
    +// CHECK-PLT: bar@plt
    +// CHECK-PLT: bar1@plt
    +// CHECK-NO-PLT-NOT: bar@plt
    +// CHECK-NO-PLT-NOT: bar1@plt
    +// CHECK-NO-PLT-NOT: bar2@plt
    +
    +__attribute__((optnone))
    +void bar(int a) {
    +    return;
    +}
    +
    +__attribute__((optnone))
    +extern void bar1(int);
    +
    +__attribute__((optnone))
    +static void bar2(int a) {
    +    return;
    +}
    +
    +void foo(int a) {
    +    bar(a);
    +    bar1(a);
    +    bar2(a);
    +    return;
    +}
    +
    diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
    index b91c2617c507..dc8eb84469f4 100644
    --- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
    +++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
    @@ -412,6 +412,8 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
           "declare i32 @fseeko64(%struct*, i64, i32)\n"
           "declare i64 @ftello64(%struct*)\n"
     
    +      "declare void @_Unwind_Resume(%struct*)\n"
    +      "declare void @_ZSt9terminatev()\n"
           "declare void @_ZdaPv(i8*)\n"
           "declare void @_ZdaPvRKSt9nothrow_t(i8*, %struct*)\n"
           "declare void @_ZdaPvSt11align_val_t(i8*, i64)\n"
    @@ -478,7 +480,9 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
           "declare void @\"??_V@YAXPAXI@Z\"(i8*, i32)\n"
     
           // These other functions were derived from the .def C declaration.
    +      "declare i8* @__cxa_allocate_exception(i64)\n"
           "declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)\n"
    +      "declare i8* @__cxa_begin_catch(i8*)\n"
           "declare void @__cxa_guard_abort(%struct*)\n"
           "declare i32 @__cxa_guard_acquire(%struct*)\n"
           "declare void @__cxa_guard_release(%struct*)\n"
    @@ -569,6 +573,7 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
           "declare double @__cosh_finite(double)\n"
           "declare float @__coshf_finite(float)\n"
           "declare x86_fp80 @__coshl_finite(x86_fp80)\n"
    +      "declare void @__cxa_throw(i8*, i8*, i8*)\n"
           "declare double @__exp10_finite(double)\n"
           "declare float @__exp10f_finite(float)\n"
           "declare x86_fp80 @__exp10l_finite(x86_fp80)\n"
    -- 
    2.43.0
    

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions