Skip to content

Commit b9fb063

Browse files
committed
[clang-offload-bundler] Add option -allow-missing-bundles
There are out-of-tree tools using clang-offload-bundler to extract bundles from bundled files. When a bundle is not in the bundled file, clang-offload-bundler is expected to emit an error message and return non-zero value. However currently clang-offload-bundler silently generates empty file for the missing bundles. Since OpenMP/HIP toolchains expect the current behavior, an option -allow-missing-bundles is added to let clang-offload-bundler create empty file when a bundle is missing when unbundling. The unbundling job action is updated to use this option by default. clang-offload-bundler itself will emit error when a bundle is missing when unbundling by default. Changes are also made to check duplicate targets in -targets option and emit error. Differential Revision: https://reviews.llvm.org/D93068
1 parent 7685d81 commit b9fb063

File tree

5 files changed

+84
-18
lines changed

5 files changed

+84
-18
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7392,6 +7392,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
73927392
}
73937393
CmdArgs.push_back(TCArgs.MakeArgString(UB));
73947394
CmdArgs.push_back("-unbundle");
7395+
CmdArgs.push_back("-allow-missing-bundles");
73957396

73967397
// All the inputs are encoded as commands.
73977398
C.addCommand(std::make_unique<Command>(

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

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
// CK-HELP: {{.*}}one. The resulting file can also be unbundled into different files by
3434
// CK-HELP: {{.*}}this tool if -unbundle is provided.
3535
// CK-HELP: {{.*}}USAGE: clang-offload-bundler [options]
36+
// CK-HELP: {{.*}}-allow-missing-bundles {{.*}}- Create empty files if bundles are missing when unbundling
3637
// CK-HELP: {{.*}}-inputs=<string> - [<input file>,...]
3738
// CK-HELP: {{.*}}-outputs=<string> - [<output file>,...]
3839
// CK-HELP: {{.*}}-targets=<string> - [<offload kind>-<target triple>,...]
@@ -88,7 +89,7 @@
8889
// RUN: not clang-offload-bundler -type=i -targets=openmp-powerpc64le-linux,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -inputs=%t.i,%t.tgt1,%t.tgt2 -outputs=%t.bundle.i 2>&1 | FileCheck %s --check-prefix CK-ERR9A
8990
// RUN: not clang-offload-bundler -type=i -targets=host-%itanium_abi_triple,host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu -inputs=%t.i,%t.tgt1,%t.tgt2 -outputs=%t.bundle.i 2>&1 | FileCheck %s --check-prefix CK-ERR9B
9091
// CK-ERR9A: error: expecting exactly one host target but got 0
91-
// CK-ERR9B: error: expecting exactly one host target but got 2
92+
// CK-ERR9B: error: Duplicate targets are not allowed
9293

9394
//
9495
// Check text bundle. This is a readable format, so we check for the format we expect to find.
@@ -181,17 +182,17 @@
181182
// RUN: diff %t.tgt2 %t.res.tgt2
182183

183184
// Check if we can unbundle a file with no magic strings.
184-
// RUN: clang-offload-bundler -type=s -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.s,%t.res.tgt1,%t.res.tgt2 -inputs=%t.s -unbundle
185+
// RUN: clang-offload-bundler -type=s -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.s,%t.res.tgt1,%t.res.tgt2 -inputs=%t.s -unbundle -allow-missing-bundles
185186
// RUN: diff %t.s %t.res.s
186187
// RUN: diff %t.empty %t.res.tgt1
187188
// RUN: diff %t.empty %t.res.tgt2
188-
// RUN: clang-offload-bundler -type=s -targets=openmp-powerpc64le-ibm-linux-gnu,host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt1,%t.res.s,%t.res.tgt2 -inputs=%t.s -unbundle
189+
// RUN: clang-offload-bundler -type=s -targets=openmp-powerpc64le-ibm-linux-gnu,host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt1,%t.res.s,%t.res.tgt2 -inputs=%t.s -unbundle -allow-missing-bundles
189190
// RUN: diff %t.s %t.res.s
190191
// RUN: diff %t.empty %t.res.tgt1
191192
// RUN: diff %t.empty %t.res.tgt2
192193

193194
// Check that bindler prints an error if given host bundle does not exist in the fat binary.
194-
// RUN: not clang-offload-bundler -type=s -targets=host-x86_64-xxx-linux-gnu,openmp-powerpc64le-ibm-linux-gnu -outputs=%t.res.s,%t.res.tgt1 -inputs=%t.bundle3.s -unbundle 2>&1 | FileCheck %s --check-prefix CK-NO-HOST-BUNDLE
195+
// RUN: not clang-offload-bundler -type=s -targets=host-x86_64-xxx-linux-gnu,openmp-powerpc64le-ibm-linux-gnu -outputs=%t.res.s,%t.res.tgt1 -inputs=%t.bundle3.s -unbundle -allow-missing-bundles 2>&1 | FileCheck %s --check-prefix CK-NO-HOST-BUNDLE
195196
// CK-NO-HOST-BUNDLE: error: Can't find bundle for the host target
196197

197198
//
@@ -229,11 +230,11 @@
229230
// RUN: diff %t.tgt1 %t.res.tgt1
230231

231232
// Check if we can unbundle a file with no magic strings.
232-
// RUN: clang-offload-bundler -type=bc -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.bc,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bc -unbundle
233+
// RUN: clang-offload-bundler -type=bc -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.bc,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bc -unbundle -allow-missing-bundles
233234
// RUN: diff %t.bc %t.res.bc
234235
// RUN: diff %t.empty %t.res.tgt1
235236
// RUN: diff %t.empty %t.res.tgt2
236-
// RUN: clang-offload-bundler -type=bc -targets=openmp-powerpc64le-ibm-linux-gnu,host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt1,%t.res.bc,%t.res.tgt2 -inputs=%t.bc -unbundle
237+
// RUN: clang-offload-bundler -type=bc -targets=openmp-powerpc64le-ibm-linux-gnu,host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt1,%t.res.bc,%t.res.tgt2 -inputs=%t.bc -unbundle -allow-missing-bundles
237238
// RUN: diff %t.bc %t.res.bc
238239
// RUN: diff %t.empty %t.res.tgt1
239240
// RUN: diff %t.empty %t.res.tgt2
@@ -269,11 +270,11 @@
269270
// RUN: diff %t.tgt1 %t.res.tgt1
270271

271272
// Check if we can unbundle a file with no magic strings.
272-
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.o,%t.res.tgt1,%t.res.tgt2 -inputs=%t.o -unbundle
273+
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.o,%t.res.tgt1,%t.res.tgt2 -inputs=%t.o -unbundle -allow-missing-bundles
273274
// RUN: diff %t.o %t.res.o
274275
// RUN: diff %t.empty %t.res.tgt1
275276
// RUN: diff %t.empty %t.res.tgt2
276-
// RUN: clang-offload-bundler -type=o -targets=openmp-powerpc64le-ibm-linux-gnu,host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt1,%t.res.o,%t.res.tgt2 -inputs=%t.o -unbundle
277+
// RUN: clang-offload-bundler -type=o -targets=openmp-powerpc64le-ibm-linux-gnu,host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt1,%t.res.o,%t.res.tgt2 -inputs=%t.o -unbundle -allow-missing-bundles
277278
// RUN: diff %t.o %t.res.o
278279
// RUN: diff %t.empty %t.res.tgt1
279280
// RUN: diff %t.empty %t.res.tgt2
@@ -288,6 +289,36 @@
288289
// RUN: diff %t.tgt1 %t.res.tgt1
289290
// RUN: diff %t.tgt2 %t.res.tgt2
290291

292+
//
293+
// Check error due to missing bundles
294+
//
295+
// RUN: clang-offload-bundler -type=bc -targets=host-%itanium_abi_triple,hip-amdgcn-amd-amdhsa-gfx900 -inputs=%t.bc,%t.tgt1 -outputs=%t.hip.bundle.bc
296+
// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc -unbundle \
297+
// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906 \
298+
// RUN: 2>&1 | FileCheck -check-prefix=MISS1 %s
299+
// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc,%t.tmp2.bc -unbundle \
300+
// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx900 \
301+
// RUN: 2>&1 | FileCheck -check-prefix=MISS1 %s
302+
// MISS1: error: Can't find bundles for hip-amdgcn-amd-amdhsa-gfx906
303+
// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc,%t.tmp2.bc -unbundle \
304+
// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx803 \
305+
// RUN: 2>&1 | FileCheck -check-prefix=MISS2 %s
306+
// MISS2: error: Can't find bundles for hip-amdgcn-amd-amdhsa-gfx803 and hip-amdgcn-amd-amdhsa-gfx906
307+
// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc,%t.tmp2.bc,%t.tmp3.bc -unbundle \
308+
// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx1010 \
309+
// RUN: 2>&1 | FileCheck -check-prefix=MISS3 %s
310+
// MISS3: error: Can't find bundles for hip-amdgcn-amd-amdhsa-gfx1010, hip-amdgcn-amd-amdhsa-gfx803, and hip-amdgcn-amd-amdhsa-gfx906
311+
312+
//
313+
// Check error due to duplicate targets
314+
//
315+
// RUN: not clang-offload-bundler -type=bc -targets=host-%itanium_abi_triple,hip-amdgcn-amd-amdhsa-gfx900,hip-amdgcn-amd-amdhsa-gfx900 \
316+
// RUN: -inputs=%t.bc,%t.tgt1,%t.tgt1 -outputs=%t.hip.bundle.bc 2>&1 | FileCheck -check-prefix=DUP %s
317+
// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc,%t.tmp2.bc -unbundle \
318+
// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx906 \
319+
// RUN: 2>&1 | FileCheck -check-prefix=DUP %s
320+
// DUP: error: Duplicate targets are not allowed
321+
291322
// Some code so that we can create a binary out of this file.
292323
int A = 0;
293324
void test_func(void) {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,22 @@
8787
// LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o"
8888
// LINK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900"
8989
// LINK-SAME: "-inputs=[[A_O:.*a.o]]" "-outputs=[[A_OBJ_HOST:.*o]],{{.*o}},{{.*o}}"
90-
// LINK: "-unbundle"
90+
// LINK: "-unbundle" "-allow-missing-bundles"
9191

9292
// LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o"
9393
// LINK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900"
9494
// LINK-SAME: "-inputs=[[B_O:.*b.o]]" "-outputs=[[B_OBJ_HOST:.*o]],{{.*o}},{{.*o}}"
95-
// LINK: "-unbundle"
95+
// LINK: "-unbundle" "-allow-missing-bundles"
9696

9797
// LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o"
9898
// LINK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900"
9999
// LINK-SAME: "-inputs=[[A_O]]" "-outputs={{.*o}},[[A_BC1:.*o]],[[A_BC2:.*o]]"
100-
// LINK: "-unbundle"
100+
// LINK: "-unbundle" "-allow-missing-bundles"
101101

102102
// LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o"
103103
// LINK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900"
104104
// LINK-SAME: "-inputs=[[B_O]]" "-outputs={{.*o}},[[B_BC1:.*o]],[[B_BC2:.*o]]"
105-
// LINK: "-unbundle"
105+
// LINK: "-unbundle" "-allow-missing-bundles"
106106

107107
// LINK-NOT: "*.llvm-link"
108108
// LINK-NOT: ".*opt"

clang/test/Driver/openmp-offload.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@
495495
// CHK-UBJOBS-SAME: [[INPUT:[^\\/]+\.i]]" "-outputs=
496496
// CHK-UBJOBS-SAME: [[HOSTPP:[^\\/]+\.i]],
497497
// CHK-UBJOBS-SAME: [[T1PP:[^\\/]+\.i]],
498-
// CHK-UBJOBS-SAME: [[T2PP:[^\\/]+\.i]]" "-unbundle"
498+
// CHK-UBJOBS-SAME: [[T2PP:[^\\/]+\.i]]" "-unbundle" "-allow-missing-bundles"
499499
// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-disable-llvm-passes" {{.*}}"-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu" {{.*}}"-o" "
500500
// CHK-UBJOBS-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]"
501501
// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
@@ -504,7 +504,7 @@
504504
// CHK-UBJOBS-ST-SAME: [[INPUT:[^\\/]+\.i]]" "-outputs=
505505
// CHK-UBJOBS-ST-SAME: [[HOSTPP:[^\\/,]+\.i]],
506506
// CHK-UBJOBS-ST-SAME: [[T1PP:[^\\/,]+\.i]],
507-
// CHK-UBJOBS-ST-SAME: [[T2PP:[^\\/,]+\.i]]" "-unbundle"
507+
// CHK-UBJOBS-ST-SAME: [[T2PP:[^\\/,]+\.i]]" "-unbundle" "-allow-missing-bundles"
508508
// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-disable-llvm-passes" {{.*}}"-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu" {{.*}}"-o" "
509509
// CHK-UBJOBS-ST-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]"
510510
// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
@@ -563,7 +563,7 @@
563563
// CHK-UBJOBS2-SAME: [[INPUT:[^\\/]+\.o]]" "-outputs=
564564
// CHK-UBJOBS2-SAME: [[HOSTOBJ:[^\\/]+\.o]],
565565
// CHK-UBJOBS2-SAME: [[T1OBJ:[^\\/]+\.o]],
566-
// CHK-UBJOBS2-SAME: [[T2OBJ:[^\\/]+\.o]]" "-unbundle"
566+
// CHK-UBJOBS2-SAME: [[T2OBJ:[^\\/]+\.o]]" "-unbundle" "-allow-missing-bundles"
567567
// CHK-UBJOBS2: ld{{(\.exe)?}}" {{.*}}"-o" "
568568
// CHK-UBJOBS2-SAME: [[T1BIN:[^\\/]+\.out]]" {{.*}}"{{.*}}[[T1OBJ]]"
569569
// CHK-UBJOBS2: ld{{(\.exe)?}}" {{.*}}"-o" "
@@ -579,7 +579,7 @@
579579
// CHK-UBJOBS2-ST-SAME: [[INPUT:[^\\/]+\.o]]" "-outputs=
580580
// CHK-UBJOBS2-ST-SAME: [[HOSTOBJ:[^\\/,]+\.o]],
581581
// CHK-UBJOBS2-ST-SAME: [[T1OBJ:[^\\/,]+\.o]],
582-
// CHK-UBJOBS2-ST-SAME: [[T2OBJ:[^\\/,]+\.o]]" "-unbundle"
582+
// CHK-UBJOBS2-ST-SAME: [[T2OBJ:[^\\/,]+\.o]]" "-unbundle" "-allow-missing-bundles"
583583
// CHK-UBJOBS2-ST-NOT: clang-offload-bundler{{.*}}in.so
584584
// CHK-UBJOBS2-ST: ld{{(\.exe)?}}" {{.*}}"-o" "
585585
// CHK-UBJOBS2-ST-SAME: [[T1BIN:[^\\/]+\.out-openmp-powerpc64le-ibm-linux-gnu]]" {{.*}}"{{.*}}[[T1OBJ]]"
@@ -609,15 +609,15 @@
609609
// CHK-UBUJOBS-SAME: [[INPUT:[^\\/]+\.i]]" "-outputs=
610610
// CHK-UBUJOBS-SAME: [[HOSTPP:[^\\/]+\.i]],
611611
// CHK-UBUJOBS-SAME: [[T1PP:[^\\/]+\.i]],
612-
// CHK-UBUJOBS-SAME: [[T2PP:[^\\/]+\.i]]" "-unbundle"
612+
// CHK-UBUJOBS-SAME: [[T2PP:[^\\/]+\.i]]" "-unbundle" "-allow-missing-bundles"
613613
// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-disable-llvm-passes" {{.*}}"-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu" {{.*}}"-o" "
614614
// CHK-UBUJOBS-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]"
615615

616616
// CHK-UBUJOBS-ST: clang-offload-bundler{{.*}}" "-type=i" "-targets=host-powerpc64le-unknown-linux,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu" "-inputs=
617617
// CHK-UBUJOBS-ST-SAME: [[INPUT:[^\\/]+\.i]]" "-outputs=
618618
// CHK-UBUJOBS-ST-SAME: [[HOSTPP:[^\\/,]+\.i]],
619619
// CHK-UBUJOBS-ST-SAME: [[T1PP:[^\\/,]+\.i]],
620-
// CHK-UBUJOBS-ST-SAME: [[T2PP:[^\\/,]+\.i]]" "-unbundle"
620+
// CHK-UBUJOBS-ST-SAME: [[T2PP:[^\\/,]+\.i]]" "-unbundle" "-allow-missing-bundles"
621621
// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-disable-llvm-passes" {{.*}}"-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu" {{.*}}"-o" "
622622
// CHK-UBUJOBS-ST-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]"
623623

clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <cstdint>
4444
#include <forward_list>
4545
#include <memory>
46+
#include <set>
4647
#include <string>
4748
#include <system_error>
4849
#include <utility>
@@ -95,6 +96,12 @@ static cl::opt<bool> PrintExternalCommands(
9596
"instead of actually executing them - for testing purposes.\n"),
9697
cl::init(false), cl::cat(ClangOffloadBundlerCategory));
9798

99+
static cl::opt<bool>
100+
AllowMissingBundles("allow-missing-bundles",
101+
cl::desc("Create empty files if bundles are missing "
102+
"when unbundling.\n"),
103+
cl::init(false), cl::cat(ClangOffloadBundlerCategory));
104+
98105
static cl::opt<unsigned>
99106
BundleAlignment("bundle-align",
100107
cl::desc("Alignment of bundle for binary files"),
@@ -883,6 +890,25 @@ static Error UnbundleFiles() {
883890
FoundHostBundle = true;
884891
}
885892

893+
if (!AllowMissingBundles && !Worklist.empty()) {
894+
std::string ErrMsg = "Can't find bundles for";
895+
std::set<StringRef> Sorted;
896+
for (auto &E : Worklist)
897+
Sorted.insert(E.first());
898+
unsigned I = 0;
899+
unsigned Last = Sorted.size() - 1;
900+
for (auto &E : Sorted) {
901+
if (I != 0 && Last > 1)
902+
ErrMsg += ",";
903+
ErrMsg += " ";
904+
if (I == Last && I != 0)
905+
ErrMsg += "and ";
906+
ErrMsg += E.str();
907+
++I;
908+
}
909+
return createStringError(inconvertibleErrorCode(), ErrMsg);
910+
}
911+
886912
// If no bundles were found, assume the input file is the host bundle and
887913
// create empty files for the remaining targets.
888914
if (Worklist.size() == TargetNames.size()) {
@@ -974,7 +1000,15 @@ int main(int argc, const char **argv) {
9741000
// have exactly one host target.
9751001
unsigned Index = 0u;
9761002
unsigned HostTargetNum = 0u;
1003+
llvm::DenseSet<StringRef> ParsedTargets;
9771004
for (StringRef Target : TargetNames) {
1005+
if (ParsedTargets.contains(Target)) {
1006+
reportError(createStringError(errc::invalid_argument,
1007+
"Duplicate targets are not allowed"));
1008+
return 1;
1009+
}
1010+
ParsedTargets.insert(Target);
1011+
9781012
StringRef Kind;
9791013
StringRef Triple;
9801014
getOffloadKindAndTriple(Target, Kind, Triple);

0 commit comments

Comments
 (0)