Skip to content

Commit a78861f

Browse files
authored
[NvlinkWrapper] Add support for --undefined (#113934)
Summary: This flag is pretty canonical in ELF linkers, it allows us to force the link job to extract a library if it defines a specific symbol. This is mostly useful for letting us forcibly extract things that don't fit the normal model (i.e. kernels) from static libraries.
1 parent 8193832 commit a78861f

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

clang/test/Driver/nvlink-wrapper.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ int bar() {
2121
}
2222
#else
2323
extern int y;
24-
int __attribute__((visibility("hidden"))) x = 999;
24+
extern int x;
2525
int baz() { return y + x; }
2626
#endif
2727

2828
// Create various inputs to test basic linking and LTO capabilities. Creating a
2929
// CUDA binary requires access to the `ptxas` executable, so we just use x64.
30+
// RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.o
3031
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DX -o %t-x.o
3132
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DY -o %t-y.o
3233
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -DZ -o %t-z.o
@@ -36,6 +37,7 @@ int baz() { return y + x; }
3637
// RUN: llvm-ar rcs %t-y.a %t-y.o
3738
// RUN: llvm-ar rcs %t-z.a %t-z.o
3839
// RUN: llvm-ar rcs %t-w.a %t-w.o
40+
// RUN: llvm-ar rcs %t-u.a %t-u.o
3941

4042
//
4143
// Check that we forward any unrecognized argument to 'nvlink'.
@@ -49,11 +51,16 @@ int baz() { return y + x; }
4951
// `libx.a` and `liby.a` because extern weak symbols do not extract and `libz.a`
5052
// is not used at all.
5153
//
52-
// RUN: clang-nvlink-wrapper --dry-run %t-x.a %t-u.o %t-y.a %t-z.a %t-w.a \
54+
// RUN: clang-nvlink-wrapper --dry-run %t-x.a %t-u.a %t-y.a %t-z.a %t-w.a %t.o \
5355
// RUN: -arch sm_52 -o a.out 2>&1 | FileCheck %s --check-prefix=LINK
5456
// LINK: nvlink{{.*}} -arch sm_52 -o a.out [[INPUT:.+]].cubin {{.*}}-x-{{.*}}.cubin{{.*}}-y-{{.*}}.cubin
5557

56-
// RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.o
58+
//
59+
// Same as above but we use '--undefined' to forcibly extract 'libz.a'
60+
//
61+
// RUN: clang-nvlink-wrapper --dry-run %t-x.a %t-u.a %t-y.a %t-z.a %t-w.a %t.o \
62+
// RUN: -u z -arch sm_52 -o a.out 2>&1 | FileCheck %s --check-prefix=LINK
63+
// UNDEFINED: nvlink{{.*}} -arch sm_52 -o a.out [[INPUT:.+]].cubin {{.*}}-x-{{.*}}.cubin{{.*}}-y-{{.*}}.cubin{{.*}}-z-{{.*}}.cubin
5764

5865
//
5966
// Check that the LTO interface works and properly preserves symbols used in a

clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ struct Symbol {
250250
};
251251

252252
Symbol() : File(), Flags(None), UsedInRegularObj(false) {}
253+
Symbol(Symbol::Flags Flags) : File(), Flags(Flags), UsedInRegularObj(true) {}
253254

254255
Symbol(MemoryBufferRef File, const irsymtab::Reader::SymbolRef Sym)
255256
: File(File), Flags(0), UsedInRegularObj(false) {
@@ -535,6 +536,8 @@ Expected<SmallVector<StringRef>> getInput(const ArgList &Args) {
535536

536537
bool Extracted = true;
537538
StringMap<Symbol> SymTab;
539+
for (auto &Sym : Args.getAllArgValues(OPT_u))
540+
SymTab[Sym] = Symbol(Symbol::Undefined);
538541
SmallVector<std::unique_ptr<MemoryBuffer>> LinkerInput;
539542
while (Extracted) {
540543
Extracted = false;

clang/tools/clang-nvlink-wrapper/NVLinkOpts.td

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,21 @@ def plugin : JoinedOrSeparate<["--", "-"], "plugin">,
4343
Flags<[HelpHidden, WrapperOnlyOption]>;
4444

4545
def arch : Separate<["--", "-"], "arch">,
46-
HelpText<"Specify the 'sm_' name of the target architecture.">;
46+
HelpText<"Specify the 'sm_' name of the target architecture">;
4747
def : Joined<["--", "-"], "plugin-opt=mcpu=">,
4848
Flags<[HelpHidden, WrapperOnlyOption]>, Alias<arch>;
4949

50-
def g : Flag<["-"], "g">, HelpText<"Specify that this was a debug compile.">;
50+
def g : Flag<["-"], "g">, HelpText<"Specify that this was a debug compile">;
5151
def debug : Flag<["--"], "debug">, Alias<g>;
5252

5353
def lto_emit_llvm : Flag<["--"], "lto-emit-llvm">, Flags<[WrapperOnlyOption]>,
5454
HelpText<"Emit LLVM-IR bitcode">;
5555
def lto_emit_asm : Flag<["--"], "lto-emit-asm">, Flags<[WrapperOnlyOption]>,
5656
HelpText<"Emit assembly code">;
5757

58+
def u : JoinedOrSeparate<["-"], "u">, HelpText<"Force undefined symbol during linking">;
59+
def undefined : JoinedOrSeparate<["--"], "undefined">, Alias<u>;
60+
5861
def O : Joined<["--", "-"], "plugin-opt=O">,
5962
Flags<[WrapperOnlyOption]>, MetaVarName<"<O0, O1, O2, or O3>">,
6063
HelpText<"Optimization level for LTO">;

0 commit comments

Comments
 (0)