Skip to content

Commit

Permalink
[SYCL] Fix backwards compatibility for libraries in archive format (#…
Browse files Browse the repository at this point in the history
…4685)

With `-sycldevice` triple environment removal (as performed in
#3929), backwards compatibility has been enforced for SYCL
objects/object-format libraries only. To ensure that `.a` libraries
(archives) built by older compiler versions are usable with newer
compiler version, adjust `clang-offload-deps` to consider
`-sycldevice`-marked symbols when encountering a SYCL target.

Signed-off-by: Artem Gindinson <[email protected]>
  • Loading branch information
AGindinson authored Oct 3, 2021
1 parent b79eb91 commit 53308b1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
17 changes: 15 additions & 2 deletions clang/test/Driver/clang-offload-deps.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,28 @@
// Generate dependencies for targets and check contents of the output bitcode files.
//
// RUN: clang-offload-deps -targets=openmp-x86_64-pc-linux-gnu,sycl-spir64 -outputs=%t.deps.x86_64,%t.deps.spir64 %t.fat
// RUN: clang-offload-deps -targets=openmp-x86_64-pc-linux-gnu,sycl-spir64 -outputs=%t.deps.x86_64,%t.deps.spir64 %t.fat
// RUN: llvm-dis -o - %t.deps.x86_64 | FileCheck %s --check-prefixes=CHECK-DEPS-X86_64
// RUN: llvm-dis -o - %t.deps.spir64 | FileCheck %s --check-prefixes=CHECK-DEPS-SPIR64
// RUN: llvm-dis -o - %t.deps.spir64 | FileCheck %s --check-prefixes=CHECK-DEPS-SPIR64 -DSPIRTriple=spir64
//
// Check that the legacy 'sycldevice' symbols are still identified correctly
// when 'unknown' environment has been specified/implied for SYCL via
// clang-offload-bundler's -targets
//
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu,sycl-spir64-unknown-unknown-sycldevice -inputs=%t.host,%t.x86_64,%t.spir64 -outputs=%t.legacy-sycldevice.fat
// Check correct behavior for multiple targets
// RUN: clang-offload-deps -targets=openmp-x86_64-pc-linux-gnu,sycl-spir64-unknown-unknown -outputs=%t.deps.legacy.x86_64,%t.deps.legacy.spir64 %t.legacy-sycldevice.fat
// RUN: llvm-dis -o - %t.deps.legacy.spir64 | FileCheck %s --check-prefixes=CHECK-DEPS-SPIR64 -DSPIRTriple=spir64-unknown-unknown
// Check correct behavior for shortened triple
// RUN: clang-offload-deps -targets=sycl-spir64 -outputs=%t.deps.legacy.spir64-short %t.legacy-sycldevice.fat
// RUN: llvm-dis -o - %t.deps.legacy.spir64-short | FileCheck %s --check-prefixes=CHECK-DEPS-SPIR64 -DSPIRTriple=spir64

// CHECK-DEPS-X86_64: target triple = "x86_64-pc-linux-gnu"
// CHECK-DEPS-X86_64: @bar = external global i8*
// CHECK-DEPS-X86_64: @foo = external global i8*
// CHECK-DEPS-X86_64: @offload.symbols = hidden local_unnamed_addr global [2 x i8*] [i8* bitcast (i8** @bar to i8*), i8* bitcast (i8** @foo to i8*)]

// CHECK-DEPS-SPIR64: target triple = "spir64"
// CHECK-DEPS-SPIR64: target triple = "[[SPIRTriple]]"
// CHECK-DEPS-SPIR64: @bar = external global i8*
// CHECK-DEPS-SPIR64: @foo = external global i8*
// CHECK-DEPS-SPIR64: @llvm.used = appending global [2 x i8*] [i8* bitcast (i8** @bar to i8*), i8* bitcast (i8** @foo to i8*)], section "llvm.metadata"
Expand Down
22 changes: 22 additions & 0 deletions clang/tools/clang-offload-deps/ClangOffloadDeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,33 @@ int main(int argc, const char **argv) {
for (StringRef Symbol = DataOrErr.get(); !Symbol.empty();) {
unsigned Len = strlen(Symbol.data());

// TODO: Consider storing Targets and Kinds in a single map-like struct,
// possibly reusing ClangOffloadBundler's 'OffloadTargetInfo'.
auto KindsIter = Kinds.begin();
for (const std::string &Target : Targets) {
std::string Prefix = Target + ".";
if (Symbol.startswith(Prefix))
Target2Symbols[Target].insert(
Symbol.substr(Prefix.size(), Len - Prefix.size()));
else if (KindsIter->equals("sycl")) {
// FIXME: Temporary solution for supporting libraries produced by old
// versions of SYCL toolchain. Old versions used triples with
// 'sycldevice' environment component of the triple, whereas new
// toolchain use 'unknown' value for that triple component.
// We check for the legacy 'sycldevice' variant upon the negative
// check for a SYCL triple with 'unknown' environment.
std::string LegacyPrefix(Target);
// In case vendor and OS are not set for this target, fill these with
// 'unknown' so that our target has the "canonical" form of:
// <kind>-<arch>-<vendor>-<os>-<sycldevice>
while (StringRef(LegacyPrefix).count("-") < 3)
LegacyPrefix += "-unknown";
LegacyPrefix += "-sycldevice.";
if (Symbol.startswith(LegacyPrefix))
Target2Symbols[Target].insert(
Symbol.substr(LegacyPrefix.size(), Len - LegacyPrefix.size()));
}
++KindsIter;
}

Symbol = Symbol.drop_front(Len + 1u);
Expand Down

0 comments on commit 53308b1

Please sign in to comment.