Skip to content

Commit 6c1acb6

Browse files
yxsamliuSai-poorna Pasham
authored andcommitted
[HIP] search fatbin symbols for libs passed by -l (llvm#104638)
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 symbols. This patch adds that. Change-Id: I24c7b958428d46568de7bd7f335ab22912ec6ac7
1 parent 35133c2 commit 6c1acb6

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

clang/lib/Driver/ToolChains/HIPUtility.cpp

Lines changed: 70 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 (auto Name : FatBinSymbols)
6467
llvm::errs() << "Found undefined HIP fatbin symbol: " << Name << "\n";
@@ -76,8 +79,70 @@ 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+
IsExact ? Twine(LibName).str()
109+
: IsMSVC ? (Twine(LibName) + Ext).str()
110+
: (Twine("lib") + LibName + Ext).str());
111+
112+
bool Found = false;
113+
for (const auto Path : LibPaths) {
114+
llvm::SmallString<256> FullPath = Path;
115+
llvm::sys::path::append(FullPath, FullLibName);
116+
117+
if (llvm::sys::fs::exists(FullPath)) {
118+
if (Verbose)
119+
llvm::errs() << "HIP fatbin symbol search found library: "
120+
<< FullPath << "\n";
121+
auto BufferOrErr = llvm::MemoryBuffer::getFile(FullPath);
122+
if (!BufferOrErr) {
123+
errorHandler(llvm::errorCodeToError(BufferOrErr.getError()));
124+
continue;
125+
}
126+
processInput(BufferOrErr.get()->getMemBufferRef());
127+
Found = true;
128+
break;
129+
}
130+
}
131+
if (!Found && Verbose)
132+
llvm::errs() << "HIP fatbin symbol search could not find library: "
133+
<< FullLibName << "\n";
134+
};
135+
136+
for (const auto LibName : ExactLibNames)
137+
ProcessLib(LibName, true);
138+
139+
for (const auto LibName : LibNames)
140+
ProcessLib(LibName, false);
141+
}
142+
79143
private:
80144
const Compilation &C;
145+
const llvm::opt::ArgList &Args;
81146
unsigned DiagID;
82147
bool Quiet;
83148
bool Verbose;
@@ -301,7 +366,7 @@ void HIP::constructGenerateObjFileFromHIPFatBinary(
301366
auto HostTriple =
302367
C.getSingleOffloadToolChain<Action::OFK_Host>()->getTriple();
303368

304-
HIPUndefinedFatBinSymbols Symbols(C);
369+
HIPUndefinedFatBinSymbols Symbols(C, Args);
305370

306371
std::string PrimaryHipFatbinSymbol;
307372
std::string PrimaryGpuBinHandleSymbol;

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

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

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

0 commit comments

Comments
 (0)