Skip to content

Commit 469df54

Browse files
committed
[HIP] search fatbin symbols for libs passed by -l
For -fgpu-rdc linking, clang needs to collect undefined fatbin symbols and resolve them to the embedded fatbin. This has been done for object files and archive files passed as input files to clang. However, the same action is not performed for archive files passed through -l options, which causes missing fatbin symbols.
1 parent 808933f commit 469df54

File tree

2 files changed

+98
-5
lines changed

2 files changed

+98
-5
lines changed

clang/lib/Driver/ToolChains/HIPUtility.cpp

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,16 @@ static std::string normalizeForBundler(const llvm::Triple &T,
5252
// input object or archive files.
5353
class HIPUndefinedFatBinSymbols {
5454
public:
55-
HIPUndefinedFatBinSymbols(const Compilation &C)
56-
: C(C), DiagID(C.getDriver().getDiags().getCustomDiagID(
57-
DiagnosticsEngine::Error,
58-
"Error collecting HIP undefined fatbin symbols: %0")),
55+
HIPUndefinedFatBinSymbols(const Compilation &C,
56+
const llvm::opt::ArgList &Args_)
57+
: C(C), Args(Args_),
58+
DiagID(C.getDriver().getDiags().getCustomDiagID(
59+
DiagnosticsEngine::Error,
60+
"Error collecting HIP undefined fatbin symbols: %0")),
5961
Quiet(C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)),
6062
Verbose(C.getArgs().hasArg(options::OPT_v)) {
6163
populateSymbols();
64+
processStaticLibraries();
6265
if (Verbose) {
6366
for (const auto &Name : FatBinSymbols)
6467
llvm::errs() << "Found undefined HIP fatbin symbol: " << Name << "\n";
@@ -76,8 +79,75 @@ class HIPUndefinedFatBinSymbols {
7679
return GPUBinHandleSymbols;
7780
}
7881

82+
// Collect symbols from static libraries specified by -l options.
83+
void processStaticLibraries() {
84+
llvm::SmallVector<llvm::StringRef, 16> LibNames;
85+
llvm::SmallVector<llvm::StringRef, 16> LibPaths;
86+
llvm::SmallVector<llvm::StringRef, 16> ExactLibNames;
87+
llvm::Triple Triple(C.getDriver().getTargetTriple());
88+
bool IsMSVC = Triple.isWindowsMSVCEnvironment();
89+
llvm::StringRef Ext = IsMSVC ? ".lib" : ".a";
90+
91+
for (const auto *Arg : Args.filtered(options::OPT_l)) {
92+
llvm::StringRef Value = Arg->getValue();
93+
if (Value.starts_with(":"))
94+
ExactLibNames.push_back(Value.drop_front());
95+
else
96+
LibNames.push_back(Value);
97+
}
98+
for (const auto *Arg : Args.filtered(options::OPT_L)) {
99+
auto Path = Arg->getValue();
100+
LibPaths.push_back(Path);
101+
if (Verbose)
102+
llvm::errs() << "HIP fatbin symbol search uses library path: " << Path
103+
<< "\n";
104+
}
105+
106+
auto ProcessLib = [&](llvm::StringRef LibName, bool IsExact) {
107+
llvm::SmallString<256> FullLibName;
108+
if (IsExact)
109+
FullLibName = LibName;
110+
else {
111+
if (IsMSVC)
112+
(llvm::Twine(LibName) + Ext).toVector(FullLibName);
113+
else
114+
(llvm::Twine("lib") + LibName + Ext).toVector(FullLibName);
115+
}
116+
117+
bool Found = false;
118+
for (const auto &Path : LibPaths) {
119+
llvm::SmallString<256> FullPath = Path;
120+
llvm::sys::path::append(FullPath, FullLibName);
121+
122+
if (llvm::sys::fs::exists(FullPath)) {
123+
if (Verbose)
124+
llvm::errs() << "HIP fatbin symbol search found library: "
125+
<< FullPath << "\n";
126+
auto BufferOrErr = llvm::MemoryBuffer::getFile(FullPath);
127+
if (!BufferOrErr) {
128+
errorHandler(llvm::errorCodeToError(BufferOrErr.getError()));
129+
continue;
130+
}
131+
processInput(BufferOrErr.get()->getMemBufferRef());
132+
Found = true;
133+
break;
134+
}
135+
}
136+
if (!Found && Verbose)
137+
llvm::errs() << "HIP fatbin symbol search could not find library: "
138+
<< FullLibName << "\n";
139+
};
140+
141+
for (const auto &LibName : ExactLibNames)
142+
ProcessLib(LibName, true);
143+
144+
for (const auto &LibName : LibNames)
145+
ProcessLib(LibName, false);
146+
}
147+
79148
private:
80149
const Compilation &C;
150+
const llvm::opt::ArgList &Args;
81151
unsigned DiagID;
82152
bool Quiet;
83153
bool Verbose;
@@ -301,7 +371,7 @@ void HIP::constructGenerateObjFileFromHIPFatBinary(
301371
auto HostTriple =
302372
C.getSingleOffloadToolChain<Action::OFK_Host>()->getTriple();
303373

304-
HIPUndefinedFatBinSymbols Symbols(C);
374+
HIPUndefinedFatBinSymbols Symbols(C, Args);
305375

306376
std::string PrimaryHipFatbinSymbol;
307377
std::string PrimaryGpuBinHandleSymbol;

clang/test/Driver/hip-toolchain-rdc.hip

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,29 @@
2020
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
2121
// RUN: 2>&1 | FileCheck -check-prefixes=CHECK,MSVC %s
2222

23+
// Test fatbin symbol search for -l libraries.
24+
25+
// RUN: touch librdctest.a rdctest2.bin
26+
// RUN: %clang -### --target=x86_64-linux-gnu -v \
27+
// RUN: -fgpu-rdc -nogpuinc -nogpulib \
28+
// RUN: --no-offload-new-driver -L. -lrdctest -l:rdctest2.bin \
29+
// RUN: %s \
30+
// RUN: 2>&1 | FileCheck -check-prefixes=LIB,LNX-LIB %s
31+
// RUN: rm librdctest.a rdctest2.bin
32+
33+
// RUN: touch rdctest.lib rdctest2.bin
34+
// RUN: %clang -### --target=x86_64-pc-windows-msvc -v \
35+
// RUN: -fgpu-rdc -nogpuinc -nogpulib \
36+
// RUN: --no-offload-new-driver -L. -lrdctest -l:rdctest2.bin \
37+
// RUN: %s \
38+
// RUN: 2>&1 | FileCheck -check-prefixes=LIB,MSVC-LIB %s
39+
// RUN: rm rdctest.lib rdctest2.bin
40+
41+
// LIB: HIP fatbin symbol search uses library path: .
42+
// LIB: HIP fatbin symbol search found library: ./rdctest2.bin
43+
// LNX-LIB: HIP fatbin symbol search found library: ./librdctest.a
44+
// MSVC-LIB: HIP fatbin symbol search found library: ./rdctest.lib
45+
2346
// check HIP fatbin and gpubin handle symbols and code object alignment in dumped llvm-mc input
2447
// CHECK: Found undefined HIP fatbin symbol: __hip_fatbin_[[ID1:[0-9a-f]+]]
2548
// CHECK: Found undefined HIP fatbin symbol: __hip_fatbin_[[ID2:[0-9a-f]+]]

0 commit comments

Comments
 (0)