Skip to content

Commit d06bba0

Browse files
committed
Merge from 'main' to 'sycl-web' (4 commits)
CONFLICT (content): Merge conflict in clang/docs/ClangOffloadBundler.rst CONFLICT (content): Merge conflict in clang/lib/Driver/OffloadBundler.cpp CONFLICT (content): Merge conflict in clang/lib/Driver/ToolChains/Clang.cpp CONFLICT (content): Merge conflict in clang/test/Driver/clang-offload-bundler-asserts-on.c CONFLICT (content): Merge conflict in clang/test/Driver/clang-offload-bundler-standardize.c CONFLICT (content): Merge conflict in clang/test/Driver/clang-offload-bundler.c
2 parents 1d23343 + d85a81b commit d06bba0

36 files changed

+484
-149
lines changed

clang/docs/ClangOffloadBundler.rst

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,19 @@ in current implementations, facilitating interchangeable handling of code object
263263
without differentiation based on offload kind.
264264

265265
**target-triple**
266-
The target triple of the code object.
266+
The target triple of the code object. See `Target Triple
267+
<https://clang.llvm.org/docs/CrossCompilation.html#target-triple>`_.
268+
269+
LLVM target triples can be with or without the optional environment field:
270+
271+
``<arch><sub>-<vendor>-<sys>``, or
272+
``<arch><sub>-<vendor>-<sys>-<env>``
273+
274+
However, in order to standardize outputs for tools that consume bitcode bundles
275+
and to parse target ID containing dashes, the bundler only accepts target
276+
triples in the 4-field format:
277+
278+
``<arch><sub>-<vendor>-<sys>-<env>``
267279

268280
**target-id**
269281
The canonical target ID of the code object. Present only if the target
@@ -530,4 +542,4 @@ The compressed offload bundle begins with a header followed by the compressed bi
530542
- **Compressed Data**:
531543
The actual compressed binary data follows the header. Its size can be inferred from the total size of the file minus the header size.
532544

533-
> **Note**: Version 3 of the format is under development. It uses 64-bit fields for Total File Size and Uncompressed Binary Size to support files larger than 4GB. To experiment with version 3, set the environment variable `COMPRESSED_BUNDLE_FORMAT_VERSION=3`. This support is experimental and not recommended for production use.
545+
> **Note**: Version 3 of the format is under development. It uses 64-bit fields for Total File Size and Uncompressed Binary Size to support files larger than 4GB. To experiment with version 3, set the environment variable `COMPRESSED_BUNDLE_FORMAT_VERSION=3`. This support is experimental and not recommended for production use.

clang/include/clang/Driver/OffloadBundler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ class CompressedOffloadBundle {
164164
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
165165
decompress(const llvm::MemoryBuffer &Input, bool Verbose = false);
166166
};
167+
168+
/// Check whether the bundle id is in the following format:
169+
/// <kind>-<triple>[-<target id>[:target features]]
170+
/// <triple> := <arch>-<vendor>-<os>-<env>
171+
bool checkOffloadBundleID(const llvm::StringRef Str);
167172
} // namespace clang
168173

169174
#endif // LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H

clang/lib/Driver/OffloadBundler.cpp

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,27 @@ OffloadTargetInfo::OffloadTargetInfo(const StringRef Target,
9595
const OffloadBundlerConfig &BC)
9696
: BundlerConfig(BC) {
9797

98-
// TODO: Add error checking from ClangOffloadBundler.cpp
99-
auto TargetFeatures = Target.split(':');
100-
auto TripleOrGPU = TargetFeatures.first.rsplit('-');
101-
102-
if (clang::StringToOffloadArch(TripleOrGPU.second) !=
103-
clang::OffloadArch::UNKNOWN) {
104-
auto KindTriple = TripleOrGPU.first.split('-');
105-
this->OffloadKind = KindTriple.first;
106-
this->Triple = llvm::Triple(KindTriple.second);
107-
this->TargetID = Target.substr(Target.find(TripleOrGPU.second));
108-
} else {
109-
auto KindTriple = TargetFeatures.first.split('-');
110-
this->OffloadKind = KindTriple.first;
111-
this->Triple = llvm::Triple(KindTriple.second);
98+
// <kind>-<triple>[-<target id>[:target features]]
99+
// <triple> := <arch>-<vendor>-<os>-<env>
100+
SmallVector<StringRef, 6> Components;
101+
Target.split(Components, '-', /*MaxSplit=*/5);
102+
assert((Components.size() == 5 || Components.size() == 6) &&
103+
"malformed target string");
104+
105+
StringRef TargetIdWithFeature =
106+
Components.size() == 6 ? Components.back() : "";
107+
StringRef TargetId = TargetIdWithFeature.split(':').first;
108+
if (!TargetId.empty() &&
109+
clang::StringToOffloadArch(TargetId) != clang::OffloadArch::UNKNOWN)
110+
this->TargetID = TargetIdWithFeature;
111+
else
112112
this->TargetID = "";
113-
}
113+
114+
this->OffloadKind = Components.front();
115+
ArrayRef<StringRef> TripleSlice{&Components[1], /*length=*/4};
116+
llvm::Triple T = llvm::Triple(llvm::join(TripleSlice, "-"));
117+
this->Triple = llvm::Triple(T.getArchName(), T.getVendorName(), T.getOSName(),
118+
T.getEnvironmentName());
114119
}
115120

116121
bool OffloadTargetInfo::hasHostKind() const {
@@ -151,7 +156,18 @@ bool OffloadTargetInfo::operator==(const OffloadTargetInfo &Target) const {
151156
}
152157

153158
std::string OffloadTargetInfo::str() const {
154-
return Twine(OffloadKind + "-" + Triple.str() + "-" + TargetID).str();
159+
std::string NormalizedTriple;
160+
// Unfortunately we need some special sauce for AMDGPU because all the runtime
161+
// assumes the triple to be "amdgcn-amd-amdhsa-" (empty environment) instead
162+
// of "amdgcn-amd-amdhsa-unknown". It's gonna be very tricky to patch
163+
// different layers of runtime.
164+
if (Triple.isAMDGPU()) {
165+
NormalizedTriple = Triple.normalize(Triple::CanonicalForm::THREE_IDENT);
166+
NormalizedTriple.push_back('-');
167+
} else {
168+
NormalizedTriple = Triple.normalize(Triple::CanonicalForm::FOUR_IDENT);
169+
}
170+
return Twine(OffloadKind + "-" + NormalizedTriple + "-" + TargetID).str();
155171
}
156172

157173
static Triple getTargetTriple(StringRef Target,
@@ -2052,6 +2068,9 @@ Error OffloadBundler::UnbundleFiles() {
20522068
StringMap<StringRef> Worklist;
20532069
auto Output = BundlerConfig.OutputFileNames.begin();
20542070
for (auto &Triple : BundlerConfig.TargetNames) {
2071+
if (!checkOffloadBundleID(Triple))
2072+
return createStringError(errc::invalid_argument,
2073+
"invalid bundle id from bundle config");
20552074
Worklist[Triple] = *Output;
20562075
++Output;
20572076
}
@@ -2071,6 +2090,9 @@ Error OffloadBundler::UnbundleFiles() {
20712090

20722091
StringRef CurTriple = **CurTripleOrErr;
20732092
assert(!CurTriple.empty());
2093+
if (!checkOffloadBundleID(CurTriple))
2094+
return createStringError(errc::invalid_argument,
2095+
"invalid bundle id read from the bundle");
20742096

20752097
auto Output = Worklist.begin();
20762098
for (auto E = Worklist.end(); Output != E; Output++) {
@@ -2128,8 +2150,9 @@ Error OffloadBundler::UnbundleFiles() {
21282150
if (EC)
21292151
return createFileError(E.second, EC);
21302152

2131-
// If this entry has a host kind, copy the input file to the output file
2132-
// except for the archive unbundling where output is a list file.
2153+
// If this entry has a host kind, copy the input file to the output file.
2154+
// We don't need to check E.getKey() here through checkOffloadBundleID
2155+
// because the entire WorkList has been checked above.
21332156
auto OffloadInfo = OffloadTargetInfo(E.getKey(), BundlerConfig);
21342157
if (OffloadInfo.hasHostKind() &&
21352158
!FilesTypeIsArchiveToList(BundlerConfig.FilesType))
@@ -2412,6 +2435,10 @@ Error OffloadBundler::UnbundleArchive() {
24122435
// archive.
24132436
while (!CodeObject.empty()) {
24142437
SmallVector<StringRef> CompatibleTargets;
2438+
if (!checkOffloadBundleID(CodeObject)) {
2439+
return createStringError(errc::invalid_argument,
2440+
"Invalid bundle id read from code object");
2441+
}
24152442
auto CodeObjectInfo = OffloadTargetInfo(CodeObject, BundlerConfig);
24162443
if (getCompatibleOffloadTargets(CodeObjectInfo, CompatibleTargets,
24172444
BundlerConfig)) {
@@ -2493,3 +2520,11 @@ Error OffloadBundler::UnbundleArchive() {
24932520

24942521
return Error::success();
24952522
}
2523+
2524+
bool clang::checkOffloadBundleID(const llvm::StringRef Str) {
2525+
// <kind>-<triple>[-<target id>[:target features]]
2526+
// <triple> := <arch>-<vendor>-<os>-<env>
2527+
SmallVector<StringRef, 6> Components;
2528+
Str.split(Components, '-', /*MaxSplit=*/5);
2529+
return Components.size() == 5 || Components.size() == 6;
2530+
}

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9924,7 +9924,7 @@ void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
99249924
T.setArchName(ArchName);
99259925
Triples += T.normalize();
99269926
} else {
9927-
Triples += CurTC->getTriple().normalize();
9927+
Triples += CurTC->getTriple().normalize(llvm::Triple::CanonicalForm::FOUR_IDENT);
99289928
}
99299929
if ((CurKind == Action::OFK_HIP || CurKind == Action::OFK_OpenMP ||
99309930
CurKind == Action::OFK_Cuda || CurKind == Action::OFK_SYCL) &&
@@ -10153,9 +10153,11 @@ void OffloadBundler::ConstructJobMultipleOutputs(
1015310153
StringRef Val(
1015410154
TCArgs.getLastArg(options::OPT_fsycl_force_target_EQ)->getValue());
1015510155
llvm::Triple TT(C.getDriver().getSYCLDeviceTriple(Val));
10156-
Triples += TT.normalize();
10156+
Triples += TT.normalize(
10157+
llvm::Triple::CanonicalForm::FOUR_IDENT);
1015710158
} else
10158-
Triples += Dep.DependentToolChain->getTriple().normalize();
10159+
Triples += Dep.DependentToolChain->getTriple().normalize(
10160+
llvm::Triple::CanonicalForm::FOUR_IDENT);
1015910161
if ((Dep.DependentOffloadKind == Action::OFK_HIP ||
1016010162
Dep.DependentOffloadKind == Action::OFK_OpenMP ||
1016110163
Dep.DependentOffloadKind == Action::OFK_Cuda ||

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2590,7 +2590,8 @@ static void GetSDLFromOffloadArchive(
25902590
SmallString<128> DeviceTriple;
25912591
DeviceTriple += Action::GetOffloadKindName(JA.getOffloadingDeviceKind());
25922592
DeviceTriple += '-';
2593-
std::string NormalizedTriple = T.getToolChain().getTriple().normalize();
2593+
std::string NormalizedTriple = T.getToolChain().getTriple().normalize(
2594+
llvm::Triple::CanonicalForm::FOUR_IDENT);
25942595
DeviceTriple += NormalizedTriple;
25952596
if (!Target.empty()) {
25962597
DeviceTriple += '-';

clang/lib/Driver/ToolChains/HIPUtility.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static std::string normalizeForBundler(const llvm::Triple &T,
4545
return HasTargetID ? (T.getArchName() + "-" + T.getVendorName() + "-" +
4646
T.getOSName() + "-" + T.getEnvironmentName())
4747
.str()
48-
: T.normalize();
48+
: T.normalize(llvm::Triple::CanonicalForm::FOUR_IDENT);
4949
}
5050

5151
// Collect undefined __hip_fatbin* and __hip_gpubin_handle* symbols from all

clang/test/Driver/clang-offload-bundler-asserts-on.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,20 @@
1515
// Check code object compatibility for archive unbundling
1616
//
1717
// Create few code object bundles and archive them to create an input archive
18-
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-amdgcn-amd-amdhsa-gfx906,openmp-amdgcn-amd-amdhsa--gfx908 -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.simple.bundle
18+
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-amdgcn-amd-amdhsa--gfx906,openmp-amdgcn-amd-amdhsa--gfx908 -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.simple.bundle
1919
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-amdgcn-amd-amdhsa--gfx906:sramecc+:xnack+,openmp-amdgcn-amd-amdhsa--gfx908:sramecc+:xnack+ -inputs=%t.o,%t.tgt1,%t.tgt1 -outputs=%t.targetID1.bundle
2020
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-amdgcn-amd-amdhsa--gfx906:sramecc+:xnack-,openmp-amdgcn-amd-amdhsa--gfx908:sramecc+:xnack- -inputs=%t.o,%t.tgt1,%t.tgt1 -outputs=%t.targetID2.bundle
2121
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-amdgcn-amd-amdhsa--gfx906:xnack-,openmp-amdgcn-amd-amdhsa--gfx908:xnack- -inputs=%t.o,%t.tgt1,%t.tgt1 -outputs=%t.targetID3.bundle
2222
// RUN: llvm-ar cr %t.input-archive.a %t.simple.bundle %t.targetID1.bundle %t.targetID2.bundle %t.targetID3.bundle
2323

2424
// Tests to check compatibility between Bundle Entry ID formats i.e. between presence/absence of extra hyphen in case of missing environment field
25-
// RUN: clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa--gfx906,openmp-amdgcn-amd-amdhsa-gfx908 -input=%t.input-archive.a -output=%t-archive-gfx906-simple.a -output=%t-archive-gfx908-simple.a -debug-only=CodeObjectCompatibility 2>&1 | FileCheck %s -check-prefix=BUNDLECOMPATIBILITY
26-
// BUNDLECOMPATIBILITY: Compatible: Exact match: [CodeObject: openmp-amdgcn-amd-amdhsa-gfx906] : [Target: openmp-amdgcn-amd-amdhsa--gfx906]
27-
// BUNDLECOMPATIBILITY: Compatible: Exact match: [CodeObject: openmp-amdgcn-amd-amdhsa--gfx908] : [Target: openmp-amdgcn-amd-amdhsa-gfx908]
25+
// RUN: clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa--gfx906,openmp-amdgcn-amd-amdhsa--gfx908 -input=%t.input-archive.a -output=%t-archive-gfx906-simple.a -output=%t-archive-gfx908-simple.a -debug-only=CodeObjectCompatibility 2>&1 | FileCheck %s -check-prefix=BUNDLECOMPATIBILITY
26+
// BUNDLECOMPATIBILITY: Compatible: Exact match: [CodeObject: openmp-amdgcn-amd-amdhsa--gfx906] : [Target: openmp-amdgcn-amd-amdhsa--gfx906]
27+
// BUNDLECOMPATIBILITY: Compatible: Exact match: [CodeObject: openmp-amdgcn-amd-amdhsa--gfx908] : [Target: openmp-amdgcn-amd-amdhsa--gfx908]
2828

29-
// RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx906,hipv4-amdgcn-amd-amdhsa-gfx908 -input=%t.input-archive.a -output=%t-hip-archive-gfx906-simple.a -output=%t-hipv4-archive-gfx908-simple.a -hip-openmp-compatible -debug-only=CodeObjectCompatibility 2>&1 | FileCheck %s -check-prefix=HIPOpenMPCOMPATIBILITY
30-
// HIPOpenMPCOMPATIBILITY: Compatible: Target IDs are compatible [CodeObject: openmp-amdgcn-amd-amdhsa-gfx906] : [Target: hip-amdgcn-amd-amdhsa--gfx906]
31-
// HIPOpenMPCOMPATIBILITY: Compatible: Target IDs are compatible [CodeObject: openmp-amdgcn-amd-amdhsa--gfx908] : [Target: hipv4-amdgcn-amd-amdhsa-gfx908]
29+
// RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx906,hipv4-amdgcn-amd-amdhsa--gfx908 -input=%t.input-archive.a -output=%t-hip-archive-gfx906-simple.a -output=%t-hipv4-archive-gfx908-simple.a -hip-openmp-compatible -debug-only=CodeObjectCompatibility 2>&1 | FileCheck %s -check-prefix=HIPOpenMPCOMPATIBILITY
30+
// HIPOpenMPCOMPATIBILITY: Compatible: Target IDs are compatible [CodeObject: openmp-amdgcn-amd-amdhsa--gfx906] : [Target: hip-amdgcn-amd-amdhsa--gfx906]
31+
// HIPOpenMPCOMPATIBILITY: Compatible: Target IDs are compatible [CodeObject: openmp-amdgcn-amd-amdhsa--gfx908] : [Target: hipv4-amdgcn-amd-amdhsa--gfx908]
3232

3333
// Some code so that we can create a binary out of this file.
3434
int A = 0;

clang/test/Driver/clang-offload-bundler-standardize.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,12 @@
1515
//
1616
// Check code object compatibility for archive unbundling
1717
//
18-
// Create an object bundle with and without env fields
19-
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx908 -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.bundle.no.env
20-
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple-,hip-amdgcn-amd-amdhsa--gfx906,hip-amdgcn-amd-amdhsa--gfx908 -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.bundle.env
18+
// Create an object bundle
19+
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,hip-amdgcn-amd-amdhsa--gfx906,hip-amdgcn-amd-amdhsa--gfx908 -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.bundle
2120

22-
23-
// Unbundle bundle.no.env while providing targets with env
24-
// RUN: clang-offload-bundler -unbundle -type=o -targets=hip-amdgcn-amd-amdhsa--gfx906,hip-amdgcn-amd-amdhsa--gfx908 -input=%t.bundle.no.env -output=%t-hip-amdgcn-amd-amdhsa--gfx906.bc -output=%t-hip-amdgcn-amd-amdhsa--gfx908.bc -debug-only=CodeObjectCompatibility 2>&1 | FileCheck %s -check-prefix=BUNDLE-NO-ENV
25-
// BUNDLE-NO-ENV: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa-gfx906] : [Target: hip-amdgcn-amd-amdhsa--gfx906]
26-
// BUNDLE-NO-ENV: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa-gfx908] : [Target: hip-amdgcn-amd-amdhsa--gfx908]
27-
28-
// Unbundle bundle.env while providing targets with no env
29-
// RUN: clang-offload-bundler -unbundle -type=o -targets=hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx908 -input=%t.bundle.env -output=%t-hip-amdgcn-amd-amdhsa-gfx906.bc -output=%t-hip-amdgcn-amd-amdhsa-gfx908.bc -debug-only=CodeObjectCompatibility 2>&1 | FileCheck %s -check-prefix=BUNDLE-ENV
30-
// BUNDLE-ENV: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa--gfx906] : [Target: hip-amdgcn-amd-amdhsa-gfx906]
31-
// BUNDLE-ENV: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa--gfx908] : [Target: hip-amdgcn-amd-amdhsa-gfx908]
21+
// RUN: clang-offload-bundler -unbundle -type=o -targets=hip-amdgcn-amd-amdhsa--gfx906,hip-amdgcn-amd-amdhsa--gfx908 -input=%t.bundle -output=%t-hip-amdgcn-amd-amdhsa--gfx906.bc -output=%t-hip-amdgcn-amd-amdhsa--gfx908.bc -debug-only=CodeObjectCompatibility 2>&1 | FileCheck %s -check-prefix=BUNDLE
22+
// BUNDLE: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa--gfx906] : [Target: hip-amdgcn-amd-amdhsa--gfx906]
23+
// BUNDLE: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa--gfx908] : [Target: hip-amdgcn-amd-amdhsa--gfx908]
3224

3325
// Some code so that we can create a binary out of this file.
3426
int A = 0;

0 commit comments

Comments
 (0)