https://github.com/jhansali updated 
https://github.com/llvm/llvm-project/pull/234446

>From 8f02987d8bfab5b3b08c23b68c31e2efb50ea814 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

Reply via email to