https://github.com/jhansali updated https://github.com/llvm/llvm-project/pull/234446
>From 982e665991e52da93b75b642787e9d8437a927ab Mon Sep 17 00:00:00 2001 From: jhansali <[email protected]> Date: Wed, 21 Oct 2026 18:22:08 -0700 Subject: [PATCH] fix undefined-symbol handling in clang-nvlink-wrapper --- .../clang-nvlink-wrapper/nvlink-wrapper.c | 24 ++++++++++++++++--- .../ClangNVLinkWrapper.cpp | 4 ++-- .../tools/clang-nvlink-wrapper/NVLinkOpts.td | 3 ++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c b/clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c index 78ea92f1a60db7..4c9a5b2b0508c9 100644 --- a/clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c +++ b/clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c @@ -31,11 +31,13 @@ int baz() { return y + x; } // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DX -o %t-x.o // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DY -o %t-y.o // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DZ -o %t-z.o +// RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -fvisibility=hidden -DZ -o %t-z.bc // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DW -o %t-w.o // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DU -o %t-u.o // RUN: llvm-ar rcs %t-x.a %t-x.o // RUN: llvm-ar rcs %t-y.a %t-y.o // RUN: llvm-ar rcs %t-z.a %t-z.o +// RUN: llvm-ar rcs %t-z.bc.a %t-z.bc // RUN: llvm-ar rcs %t-w.a %t-w.o // RUN: llvm-ar rcs %t-u.a %t-u.o @@ -70,11 +72,27 @@ int baz() { return y + x; } // FORWARD: nvlink{{.*}} -arch sm_52 -o a.out [[INPUT:.+]].cubin {{.*}}-x-{{.*}}.o {{.*}}-u-{{.*}}.o {{.*}}-y-{{.*}}.o {{.*}}-z-{{.*}}.o {{.*}}-w-{{.*}}.o // -// Same as above but we use '--undefined' to forcibly extract 'libz.a' +// Same as above, but '-u' and '--undefined' forcibly extract 'libz.a' +// without being forwarded to 'nvlink'. // // RUN: clang-nvlink-wrapper --dry-run --assume-device-object %t-x.a %t-u.a %t-y.a %t-z.a %t-w.a %t.o \ -// RUN: -u z -arch sm_52 -o a.out 2>&1 | FileCheck %s --check-prefix=LINK -// UNDEFINED: nvlink{{.*}} -arch sm_52 -o a.out [[INPUT:.+]].cubin {{.*}}-x-{{.*}}.cubin{{.*}}-y-{{.*}}.cubin{{.*}}-z-{{.*}}.cubin +// RUN: -u z -arch sm_52 -o a.out > %t.undefined 2>&1 +// RUN: FileCheck %s --check-prefix=UNDEFINED < %t.undefined +// RUN: FileCheck %s --check-prefix=WRAPPER-ONLY < %t.undefined +// RUN: clang-nvlink-wrapper --dry-run --assume-device-object %t-x.a %t-u.a %t-y.a %t-z.a %t-w.a %t.o \ +// RUN: --undefined z -arch sm_52 -o a.out > %t.undefined 2>&1 +// RUN: FileCheck %s --check-prefix=UNDEFINED < %t.undefined +// RUN: FileCheck %s --check-prefix=WRAPPER-ONLY < %t.undefined +// UNDEFINED: nvlink{{.*}} -arch sm_52 -o a.out +// UNDEFINED-SAME: -z-{{[^ ]*}}.cubin +// WRAPPER-ONLY-NOT: {{(^|[[:space:]])(-u|--undefined)}} + +// Check that forced undefined symbols also extract bitcode archive members and +// keep hidden definitions alive during LTO. +// RUN: rm -f %t-z.s +// RUN: clang-nvlink-wrapper --dry-run %t-z.bc.a -u z -arch sm_52 --lto-emit-asm -o %t-z.s +// RUN: FileCheck %s --check-prefix=FORCED-LTO < %t-z.s +// FORCED-LTO: .global .align 4 .u32 z = 42; // // Check that the LTO interface works and properly preserves symbols used in a diff --git a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp index 6550902a6a6551..d6af68c72ce61f 100644 --- a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp +++ b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp @@ -459,7 +459,7 @@ Expected<bool> getSymbolsFromBitcode(MemoryBufferRef Buffer, ? PendingSymbols[IRSym.getName()] : SymTab[IRSym.getName()]; Symbol Sym = Symbol(Buffer, IRSym); - if (OldSym.File.getBuffer().empty()) + if (OldSym.File.getBuffer().empty() && !OldSym.isUndefined()) OldSym = Sym; bool ResolvesReference = @@ -492,7 +492,7 @@ Expected<bool> getSymbolsFromObject(ObjectFile &ObjFile, ? PendingSymbols[*NameOrErr] : SymTab[*NameOrErr]; Symbol Sym = Symbol(ObjFile.getMemoryBufferRef(), ObjSym); - if (OldSym.File.getBuffer().empty()) + if (OldSym.File.getBuffer().empty() && !OldSym.isUndefined()) OldSym = Sym; bool ResolvesReference = OldSym.isUndefined() && !Sym.isUndefined() && diff --git a/clang/tools/clang-nvlink-wrapper/NVLinkOpts.td b/clang/tools/clang-nvlink-wrapper/NVLinkOpts.td index e725d885797d2d..eb51fa426c8c98 100644 --- a/clang/tools/clang-nvlink-wrapper/NVLinkOpts.td +++ b/clang/tools/clang-nvlink-wrapper/NVLinkOpts.td @@ -59,7 +59,8 @@ def lto_emit_llvm : Flag<["--"], "lto-emit-llvm">, Flags<[WrapperOnlyOption]>, def lto_emit_asm : Flag<["--"], "lto-emit-asm">, Flags<[WrapperOnlyOption]>, HelpText<"Emit assembly code">; -def u : JoinedOrSeparate<["-"], "u">, HelpText<"Force undefined symbol during linking">; +def u : JoinedOrSeparate<["-"], "u">, Flags<[WrapperOnlyOption]>, + HelpText<"Force undefined symbol during linking">; def undefined : JoinedOrSeparate<["--"], "undefined">, Alias<u>; def O : Joined<["--", "-"], "plugin-opt=O">, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
