From dd5854c7438374b2ea548990086bd5b41fd19da1 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Sat, 27 May 2023 19:11:39 -0700 Subject: [PATCH 01/10] Reintroduce reverted commit "[clang-offload-bundler] Standardize TargetID field for bundler" This commit reintroduces the following LLVM open-source PR: https://reviews.llvm.org/D145770 Some changes on top of the community change have been made as well. Signed-off-by: Arvind Sudarsanam --- clang/docs/ClangOffloadBundler.rst | 15 +++++++- clang/lib/Driver/OffloadBundler.cpp | 35 +++++++++++++----- ...dle_aft_standardization_of_target_triple.o | Bin 0 -> 182592 bytes ...dle_bef_standardization_of_target_triple.o | Bin 0 -> 182592 bytes .../Driver/clang-offload-bundler-asserts-on.c | 8 ++-- .../clang-offload-bundler-standardize.c | 35 ++++++++++++++++++ .../Driver/clang-offload-bundler-tgtsym-asm.c | 4 +- .../Driver/clang-offload-bundler-tgtsym.c | 14 +++---- clang/test/Driver/clang-offload-bundler.c | 30 ++++++++------- clang/test/Driver/sycl-no-rdc-errors.cpp | 2 +- .../ClangOffloadBundler.cpp | 7 ++++ 11 files changed, 112 insertions(+), 38 deletions(-) create mode 100644 clang/test/Driver/Inputs/bundles/bundle_aft_standardization_of_target_triple.o create mode 100644 clang/test/Driver/Inputs/bundles/bundle_bef_standardization_of_target_triple.o create mode 100644 clang/test/Driver/clang-offload-bundler-standardize.c diff --git a/clang/docs/ClangOffloadBundler.rst b/clang/docs/ClangOffloadBundler.rst index 997948a8217e5..52981d6e1dbce 100644 --- a/clang/docs/ClangOffloadBundler.rst +++ b/clang/docs/ClangOffloadBundler.rst @@ -174,7 +174,20 @@ Where: ============= ============================================================== **target-triple** - The target triple of the code object. + The target triple of the code object. See `Target Triple + . + + The bundler accepts target triples with or without the optional environment + field: + + ``--``, or + ``---`` + + However, in order to standardize outputs for tools that consume bitcode + bundles, bundles written by the bundler internally use only the 4-field + target triple: + + ``---`` **target-id** The canonical target ID of the code object. Present only if the target diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp index 3802132d6ccf8..6147e19b1353e 100644 --- a/clang/lib/Driver/OffloadBundler.cpp +++ b/clang/lib/Driver/OffloadBundler.cpp @@ -82,12 +82,25 @@ OffloadTargetInfo::OffloadTargetInfo(const StringRef Target, if (clang::StringToCudaArch(TripleOrGPU.second) != clang::CudaArch::UNKNOWN) { auto KindTriple = TripleOrGPU.first.split('-'); this->OffloadKind = KindTriple.first; - this->Triple = llvm::Triple(KindTriple.second); - this->TargetID = Target.substr(Target.find(TripleOrGPU.second)); + + // Enforce optional env field to standardize bundles + llvm::Triple t = llvm::Triple(KindTriple.second); + this->Triple = llvm::Triple(t.getArchName(), t.getVendorName(), + t.getOSName(), t.getEnvironmentName()); + + if (TripleOrGPU.second.empty()) + this->TargetID = ""; + else + this->TargetID = Target.substr(Target.find(TripleOrGPU.second)); } else { auto KindTriple = TargetFeatures.first.split('-'); this->OffloadKind = KindTriple.first; - this->Triple = llvm::Triple(KindTriple.second); + + // Enforce optional env field to standardize bundles + llvm::Triple t = llvm::Triple(KindTriple.second); + this->Triple = llvm::Triple(t.getArchName(), t.getVendorName(), + t.getOSName(), t.getEnvironmentName()); + this->TargetID = ""; } } @@ -1499,34 +1512,34 @@ Error OffloadBundler::UnbundleFiles() { return Error::success(); } -// Unbundle the files. Return true if an error was found. +// Unbundle the files. Return false if an error was found. Expected clang::CheckBundledSection(const OffloadBundlerConfig &BundlerConfig) { // Open Input file. ErrorOr> CodeOrErr = MemoryBuffer::getFileOrSTDIN(BundlerConfig.InputFileNames.front()); if (std::error_code EC = CodeOrErr.getError()) - return createFileError(BundlerConfig.InputFileNames.front(), EC); + return false; MemoryBuffer &Input = *CodeOrErr.get(); // Select the right files handler. Expected> FileHandlerOrErr = CreateFileHandler(Input, BundlerConfig); if (!FileHandlerOrErr) - return FileHandlerOrErr.takeError(); + return false; std::unique_ptr &FH = *FileHandlerOrErr; // Quit if we don't have a handler. if (!FH) - return true; + return false; // Seed temporary filename generation with the stem of the input file. FH->SetTempFileNameBase(llvm::sys::path::stem(BundlerConfig.InputFileNames.front())); // Read the header of the bundled file. if (Error Err = FH->ReadHeader(Input)) - return std::move(Err); + return false; StringRef triple = BundlerConfig.TargetNames.front(); @@ -1537,13 +1550,15 @@ clang::CheckBundledSection(const OffloadBundlerConfig &BundlerConfig) { Expected> CurTripleOrErr = FH->ReadBundleStart(Input); if (!CurTripleOrErr) - return CurTripleOrErr.takeError(); + return false; // We don't have more bundles. if (!*CurTripleOrErr) break; - if (*CurTripleOrErr == triple) { + StringRef CurTriple = **CurTripleOrErr; + if (OffloadTargetInfo(CurTriple, BundlerConfig).Triple.str() == + OffloadTargetInfo(triple, BundlerConfig).Triple.str()) { found = true; break; } diff --git a/clang/test/Driver/Inputs/bundles/bundle_aft_standardization_of_target_triple.o b/clang/test/Driver/Inputs/bundles/bundle_aft_standardization_of_target_triple.o new file mode 100644 index 0000000000000000000000000000000000000000..f63d320cfb0788367ec8f42ff0238ae0ee896368 GIT binary patch literal 182592 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%0D`PQP)2Y6I>Ki*Zfg`$D?Gw~K+wP5W&M?J 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 Hbou`e)}R%= literal 0 HcmV?d00001 diff --git a/clang/test/Driver/Inputs/bundles/bundle_bef_standardization_of_target_triple.o b/clang/test/Driver/Inputs/bundles/bundle_bef_standardization_of_target_triple.o new file mode 100644 index 0000000000000000000000000000000000000000..d5e4f422f930dcfaa59b170ea234ffa17b445517 GIT binary patch literal 182592 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 p$4x{%pYsm^{fR()xctA&n0kEu`&1 | FileCheck %s -check-prefix=BUNDLECOMPATIBILITY -// BUNDLECOMPATIBILITY: Compatible: Exact match: [CodeObject: openmp-amdgcn-amd-amdhsa-gfx906] : [Target: openmp-amdgcn-amd-amdhsa--gfx906] -// BUNDLECOMPATIBILITY: Compatible: Exact match: [CodeObject: openmp-amdgcn-amd-amdhsa--gfx908] : [Target: openmp-amdgcn-amd-amdhsa-gfx908] +// BUNDLECOMPATIBILITY: Compatible: Exact match: [CodeObject: openmp-amdgcn-amd-amdhsa--gfx906] : [Target: openmp-amdgcn-amd-amdhsa--gfx906] +// BUNDLECOMPATIBILITY: Compatible: Exact match: [CodeObject: openmp-amdgcn-amd-amdhsa--gfx908] : [Target: openmp-amdgcn-amd-amdhsa--gfx908] // 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 -// HIPOpenMPCOMPATIBILITY: Compatible: Code Objects are compatible [CodeObject: openmp-amdgcn-amd-amdhsa-gfx906] : [Target: hip-amdgcn-amd-amdhsa--gfx906] -// HIPOpenMPCOMPATIBILITY: Compatible: Code Objects are compatible [CodeObject: openmp-amdgcn-amd-amdhsa--gfx908] : [Target: hipv4-amdgcn-amd-amdhsa-gfx908] +// HIPOpenMPCOMPATIBILITY: Compatible: Code Objects are compatible [CodeObject: openmp-amdgcn-amd-amdhsa--gfx906] : [Target: hip-amdgcn-amd-amdhsa--gfx906] +// HIPOpenMPCOMPATIBILITY: Compatible: Code Objects are compatible [CodeObject: openmp-amdgcn-amd-amdhsa--gfx908] : [Target: hipv4-amdgcn-amd-amdhsa--gfx908] // Some code so that we can create a binary out of this file. int A = 0; diff --git a/clang/test/Driver/clang-offload-bundler-standardize.c b/clang/test/Driver/clang-offload-bundler-standardize.c new file mode 100644 index 0000000000000..397164464560f --- /dev/null +++ b/clang/test/Driver/clang-offload-bundler-standardize.c @@ -0,0 +1,35 @@ +// REQUIRES: x86-registered-target +// UNSUPPORTED: target={{.*}}-darwin{{.*}}, target={{.*}}-aix{{.*}} + +// Generate the file we can bundle. +// RUN: %clang -O0 -target %itanium_abi_triple %s -c -o %t.o + +// +// Generate a couple of files to bundle with. +// +// RUN: echo 'Content of device file 1' > %t.tgt1 +// RUN: echo 'Content of device file 2' > %t.tgt2 + +// +// Check code object compatibility for archive unbundling +// +// Create an object bundle with and without env fields +// 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 +// 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 + + +// Unbundle bundle.no.env while providing targets with env +// 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 +// BUNDLE-NO-ENV: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa--gfx906] : [Target: hip-amdgcn-amd-amdhsa--gfx906] +// BUNDLE-NO-ENV: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa--gfx908] : [Target: hip-amdgcn-amd-amdhsa--gfx908] + +// Unbundle bundle.env while providing targets with no env +// 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 +// BUNDLE-ENV: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa--gfx906] : [Target: hip-amdgcn-amd-amdhsa--gfx906] +// BUNDLE-ENV: Compatible: Exact match: [CodeObject: hip-amdgcn-amd-amdhsa--gfx908] : [Target: hip-amdgcn-amd-amdhsa--gfx908] + +// Some code so that we can create a binary out of this file. +int A = 0; +void test_func(void) { + ++A; +} diff --git a/clang/test/Driver/clang-offload-bundler-tgtsym-asm.c b/clang/test/Driver/clang-offload-bundler-tgtsym-asm.c index cb9848b8df00e..c55cd6fd26232 100644 --- a/clang/test/Driver/clang-offload-bundler-tgtsym-asm.c +++ b/clang/test/Driver/clang-offload-bundler-tgtsym-asm.c @@ -13,8 +13,8 @@ // RUN: llvm-readobj --string-dump=.tgtsym %t.fat.o | FileCheck %s // CHECK: String dump of section '.tgtsym': -// CHECK-DAG: openmp-x86_64-pc-linux-gnu.foo -// CHECK-DAG: sycl-spir64.foo +// CHECK-DAG: openmp-x86_64-pc-linux-gnu-.foo +// CHECK-DAG: sycl-spir64----.foo __asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); void foo(void) {} diff --git a/clang/test/Driver/clang-offload-bundler-tgtsym.c b/clang/test/Driver/clang-offload-bundler-tgtsym.c index 04a65eb0be553..eac13b07d2c41 100644 --- a/clang/test/Driver/clang-offload-bundler-tgtsym.c +++ b/clang/test/Driver/clang-offload-bundler-tgtsym.c @@ -12,16 +12,16 @@ // RUN: llvm-readobj --string-dump=.tgtsym %t.fat.o | FileCheck %s // CHECK: String dump of section '.tgtsym': -// CHECK-DAG: openmp-x86_64-pc-linux-gnu.foo -// CHECK-DAG: openmp-x86_64-pc-linux-gnu.bar -// CHECK-DAG: sycl-spir64.foo -// CHECK-DAG: sycl-spir64.bar +// CHECK-DAG: openmp-x86_64-pc-linux-gnu-.foo +// CHECK-DAG: openmp-x86_64-pc-linux-gnu-.bar +// CHECK-DAG: sycl-spir64----.foo +// CHECK-DAG: sycl-spir64----.bar // CHECK-NOT: undefined_func // CHECK-NOT: static_func // CHECK-NOT: static_used -// CHECK-NOT: sycl-spir64.llvm.used -// CHECK-NOT: sycl-spir64.llvm.compiler.used -// CHECK-NOT: sycl-spir64.const_as +// CHECK-NOT: sycl-spir64----.llvm.used +// CHECK-NOT: sycl-spir64----.llvm.compiler.used +// CHECK-NOT: sycl-spir64----.const_as // RUN: clang-offload-bundler --add-target-symbols-to-bundled-object=false -type=o -targets=host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu,sycl-spir64 -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.fat.no.tgtsym.o // RUN: llvm-readobj --string-dump=.tgtsym %t.fat.no.tgtsym.o | FileCheck %s --check-prefix CHECK-NO-TGTSYM diff --git a/clang/test/Driver/clang-offload-bundler.c b/clang/test/Driver/clang-offload-bundler.c index 3cd48cab0ab20..f0cfd0233db7b 100644 --- a/clang/test/Driver/clang-offload-bundler.c +++ b/clang/test/Driver/clang-offload-bundler.c @@ -1,5 +1,4 @@ // REQUIRES: x86-registered-target -// REQUIRES: powerpc-registered-target // UNSUPPORTED: target={{.*}}-darwin{{.*}}, target={{.*}}-aix{{.*}} // @@ -311,11 +310,11 @@ // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.bundle3.o -### 2>&1 \ // RUN: | FileCheck %s -DHOST=%itanium_abi_triple -DINOBJ1=%t.o -DINOBJ2=%t.tgt1 -DINOBJ3=%t.tgt2 -DOUTOBJ=%t.bundle3.o --check-prefix CK-OBJ-CMD -// CK-OBJ-CMD: llvm-objcopy{{(.exe)?}}" "--add-section=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]={{.*}}" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]=readonly,exclude" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu=[[INOBJ2]]" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu=readonly,exclude" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu=[[INOBJ3]]" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu=readonly,exclude" "--" "[[INOBJ1]]" "[[OUTOBJ]]" +// CK-OBJ-CMD: llvm-objcopy{{(.exe)?}}" "--add-section=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]-={{.*}}" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]-=readonly,exclude" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu-=[[INOBJ2]]" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu-=readonly,exclude" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu-=[[INOBJ3]]" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu-=readonly,exclude" "--" "[[INOBJ1]]" "[[OUTOBJ]]" // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.bundle3.o -### 2>&1 \ // RUN: | FileCheck %s -DHOST=%itanium_abi_triple -DINOBJ1=%t.o -DINOBJ2=%t.tgt1 -DINOBJ3=%t.tgt2 -DOUTOBJ=%t.bundle3.o --check-prefix CK-OBJ-CMD-INPUTS -// CK-OBJ-CMD-INPUTS: llvm-objcopy{{(.exe)?}}" "--add-section=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]={{.*}}" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]=readonly,exclude" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu=[[INOBJ2]]" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu=readonly,exclude" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu=[[INOBJ3]]" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu=readonly,exclude" "--" "[[INOBJ1]]" "[[OUTOBJ]]" +// CK-OBJ-CMD-INPUTS: llvm-objcopy{{(.exe)?}}" "--add-section=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]-={{.*}}" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]-=readonly,exclude" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu-=[[INOBJ2]]" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu-=readonly,exclude" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu-=[[INOBJ3]]" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu-=readonly,exclude" "--" "[[INOBJ1]]" "[[OUTOBJ]]" // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.bundle3.o // RUN: clang-offload-bundler -type=o -input=%t.bundle3.o -list | FileCheck -check-prefix=CKLST %s @@ -392,15 +391,14 @@ // RUN: diff %t.tgt2 %t.res.tgt2 // Check archive mode. -// RUN: clang-offload-bundler -type=a -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -output=%t.host.a -output=%t.tgt1.a -output=%t.tgt2.a -input=%t.a -unbundle -// RUN: cmp %t.host.a %t.a +// RUN: clang-offload-bundler -type=a -targets=openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -output=%t.tgt1.a -output=%t.tgt2.a -input=%t.a -unbundle // RUN: llvm-ar t %t.tgt1.a | FileCheck %s --check-prefix=CHECK-AR-TGT1-LIST // RUN: llvm-ar t %t.tgt2.a | FileCheck %s --check-prefix=CHECK-AR-TGT2-LIST -// CHECK-AR-TGT1-LIST: openmp-powerpc64le-ibm-linux-gnu.{{.+}}.bundle3.o -// CHECK-AR-TGT1-LIST: openmp-powerpc64le-ibm-linux-gnu.{{.+}}.bundle4.o -// CHECK-AR-TGT2-LIST: openmp-x86_64-pc-linux-gnu.{{.+}}.bundle3.o -// CHECK-AR-TGT2-LIST: openmp-x86_64-pc-linux-gnu.{{.+}}.bundle4.o +// CHECK-AR-TGT1-LIST: openmp-powerpc64le-ibm-linux-gnu-{{.+}}.bundle3.o +// CHECK-AR-TGT1-LIST: openmp-powerpc64le-ibm-linux-gnu-{{.+}}.bundle4.o +// CHECK-AR-TGT2-LIST: openmp-x86_64-pc-linux-gnu-{{.+}}.bundle3.o +// CHECK-AR-TGT2-LIST: openmp-x86_64-pc-linux-gnu-{{.+}}.bundle4.o // // Check error due to missing bundles @@ -547,15 +545,15 @@ // RUN: llvm-ar t %t-archive-gfx906-simple.a | FileCheck %s -check-prefix=GFX906 // RUN: clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa-gfx906:xnack+ -input=%t.input-archive.a -output=%t-archive-gfx906-simple.a // RUN: llvm-ar t %t-archive-gfx906-simple.a | FileCheck %s -check-prefix=GFX906 -// GFX906: simple-openmp-amdgcn-amd-amdhsa-gfx906 +// GFX906: simple-openmp-amdgcn-amd-amdhsa--gfx906 // RUN: llvm-ar t %t-archive-gfx908-simple.a | FileCheck %s -check-prefix=GFX908 // GFX908-NOT: {{gfx906}} // RUN: not clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-amdgcn-amd-amdhsa-gfx906,openmp-amdgcn-amd-amdhsa-gfx906:sramecc+ -input=%t.o -input=%t.tgt1 -input=%t.tgt2 -output=%t.bad.bundle 2>&1 | FileCheck %s -check-prefix=BADTARGETS -// BADTARGETS: error: Cannot bundle inputs with conflicting targets: 'openmp-amdgcn-amd-amdhsa-gfx906' and 'openmp-amdgcn-amd-amdhsa-gfx906:sramecc+' +// BADTARGETS: error: Cannot bundle inputs with conflicting targets: 'openmp-amdgcn-amd-amdhsa--gfx906' and 'openmp-amdgcn-amd-amdhsa--gfx906:sramecc+' // Check for error if no compatible code object is found in the heterogeneous archive library // RUN: not clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa-gfx803 -input=%t.input-archive.a -output=%t-archive-gfx803-incompatible.a 2>&1 | FileCheck %s -check-prefix=INCOMPATIBLEARCHIVE -// INCOMPATIBLEARCHIVE: error: no compatible code object found for the target 'openmp-amdgcn-amd-amdhsa-gfx803' in heterogeneous archive library +// INCOMPATIBLEARCHIVE: error: no compatible code object found for the target 'openmp-amdgcn-amd-amdhsa--gfx803' in heterogeneous archive library // Check creation of empty archive if allow-missing-bundles is present and no compatible code object is found in the heterogeneous archive library // RUN: clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa-gfx803 -input=%t.input-archive.a -output=%t-archive-gfx803-empty.a -allow-missing-bundles @@ -565,7 +563,7 @@ // Check compatibility of OpenMP code objects found in the heterogeneous archive library with HIP code objects of the target // 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 // RUN: llvm-ar t %t-hip-archive-gfx906-simple.a | FileCheck %s -check-prefix=HIPOPENMPCOMPAT -// HIPOPENMPCOMPAT: simple-openmp-amdgcn-amd-amdhsa-gfx906 +// HIPOPENMPCOMPAT: simple-openmp-amdgcn-amd-amdhsa--gfx906 // RUN: llvm-ar t %t-hipv4-archive-gfx908-simple.a | FileCheck %s -check-prefix=HIPv4OPENMPCOMPAT // HIPv4OPENMPCOMPAT: simple-openmp-amdgcn-amd-amdhsa--gfx908 @@ -575,6 +573,12 @@ // RUN: llvm-ar t %T/hip-openmp_906.a | FileCheck -check-prefix=OPENMPHIPCOMPAT %s // OPENMPHIPCOMPAT: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 +// Check working of bundler before and after standardization +// RUN: clang-offload-bundler -type=o -targets=host-x86_64-unknown-linux-gnu,sycl-spir64-unknown-unknown -input=%S/Inputs/bundles/bundle_bef_standardization_of_target_triple.o -output=test-host-x86_64-unknown-linux-gnu.o -output=test-sycl-spir64-unknown-unknown.o -unbundle 2>&1 | FileCheck %s -check-prefix=CHECK-STD-OLD --allow-empty +// CHECK-STD-OLD-NOT: error: Can't find bundles for +// RUN: clang-offload-bundler -type=o -targets=host-x86_64-unknown-linux-gnu,sycl-spir64-unknown-unknown -input=%S/Inputs/bundles/bundle_aft_standardization_of_target_triple.o -output=test-host-x86_64-unknown-linux-gnu.o -output=test-sycl-spir64-unknown-unknown.o -unbundle 2>&1 | FileCheck %s -check-prefix=CHECK-STD-NEW --allow-empty +// CHECK-STD-NEW-NOT: error: Can't find bundles for + // Some code so that we can create a binary out of this file. int A = 0; void test_func(void) { diff --git a/clang/test/Driver/sycl-no-rdc-errors.cpp b/clang/test/Driver/sycl-no-rdc-errors.cpp index 3506333efcc9e..c10b3229c897b 100644 --- a/clang/test/Driver/sycl-no-rdc-errors.cpp +++ b/clang/test/Driver/sycl-no-rdc-errors.cpp @@ -5,7 +5,7 @@ // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,sycl-spir64_gen-unknown-unknown -input=%t -input=%t.o -output=%t.fat.o // RUN: not %clang -### -fsycl -fno-sycl-rdc %t.fat.o 2>&1 | FileCheck -check-prefix=CHECK-ARCH %s -// CHECK-ARCH: error: linked binaries do not contain expected 'spir64-unknown-unknown' target; found targets: 'spir64_gen-unknown-unknown', this is not supported with '-fno-sycl-rdc' +// CHECK-ARCH: error: linked binaries do not contain expected 'spir64-unknown-unknown' target; found targets: 'spir64_gen-unknown-unknown--', this is not supported with '-fno-sycl-rdc' // Some code so that we can create a binary out of this file. void test_func(void) { diff --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp index b68287303da9f..fe376989bcd71 100644 --- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp +++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp @@ -377,6 +377,8 @@ int main(int argc, const char **argv) { llvm::DenseSet ParsedTargets; // Map {offload-kind}-{triple} to target IDs. std::map> TargetIDs; + // Standardize target names to include env field + std::vector StandardizedTargetNames; for (StringRef Target : TargetNames) { if (ParsedTargets.contains(Target)) { reportError(createStringError(errc::invalid_argument, @@ -388,6 +390,8 @@ int main(int argc, const char **argv) { bool KindIsValid = OffloadInfo.isOffloadKindValid(); bool TripleIsValid = OffloadInfo.isTripleValid(); + StandardizedTargetNames.push_back(OffloadInfo.str()); + if (!KindIsValid || !TripleIsValid) { SmallVector Buf; raw_svector_ostream Msg(Buf); @@ -412,6 +416,9 @@ int main(int argc, const char **argv) { ++Index; } + + BundlerConfig.TargetNames = StandardizedTargetNames; + for (const auto &TargetID : TargetIDs) { if (auto ConflictingTID = clang::getConflictTargetIDCombination(TargetID.second)) { From 39ba7940eb115e51f7b590b1fb6761610476b72c Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Sat, 27 May 2023 20:28:06 -0700 Subject: [PATCH 02/10] Fix type --- clang/docs/ClangOffloadBundler.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ClangOffloadBundler.rst b/clang/docs/ClangOffloadBundler.rst index 52981d6e1dbce..ebbd502865dab 100644 --- a/clang/docs/ClangOffloadBundler.rst +++ b/clang/docs/ClangOffloadBundler.rst @@ -175,7 +175,7 @@ Where: **target-triple** The target triple of the code object. See `Target Triple - . + `. The bundler accepts target triples with or without the optional environment field: From 3e5e586cce3ae98e1cbc732f4c39061b29829ef8 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Sat, 27 May 2023 22:47:04 -0700 Subject: [PATCH 03/10] Fix test fail Signed-off-by: Arvind Sudarsanam --- clang/lib/Driver/Driver.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 30b88c5c58f80..24a78170a22d4 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -115,6 +115,12 @@ using namespace clang::driver; using namespace clang; using namespace llvm::opt; +static std::string standardizedTriple(std::string OrigTriple) { + llvm::Triple t = llvm::Triple(OrigTriple); + return llvm::Triple(t.getArchName(), t.getVendorName(), + t.getOSName(), t.getEnvironmentName()).str() + "-"; +} + static std::optional getOffloadTargetTriple(const Driver &D, const ArgList &Args) { auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ); @@ -5978,7 +5984,7 @@ class OffloadingActionBuilder final { SectionTriple += "-"; SectionTriple += SyclTarget.BoundArch; } - + SectionTriple = standardizedTriple(SectionTriple); // If any matching section is found, we are good. if (std::find(UniqueSections.begin(), UniqueSections.end(), SectionTriple) != UniqueSections.end()) From 60af2b0eac87b606a0fb83f2c66f3939b0635fc8 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Sun, 28 May 2023 06:40:55 -0700 Subject: [PATCH 04/10] Format fix Signed-off-by: Arvind Sudarsanam --- clang/lib/Driver/Driver.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 24a78170a22d4..c96db6dcf80c7 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -117,8 +117,10 @@ using namespace llvm::opt; static std::string standardizedTriple(std::string OrigTriple) { llvm::Triple t = llvm::Triple(OrigTriple); - return llvm::Triple(t.getArchName(), t.getVendorName(), - t.getOSName(), t.getEnvironmentName()).str() + "-"; + return llvm::Triple(t.getArchName(), t.getVendorName(), t.getOSName(), + t.getEnvironmentName()) + .str() + + "-"; } static std::optional getOffloadTargetTriple(const Driver &D, From 65a7ae1cdd2d11c0041b60a78a1056fc639ef171 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Sun, 28 May 2023 07:45:51 -0700 Subject: [PATCH 05/10] Fix test fails Signed-off-by: Arvind Sudarsanam --- clang/lib/Driver/Driver.cpp | 4 +++- clang/test/Driver/sycl-no-rdc-errors.cpp | 2 +- clang/test/Driver/sycl-target-mismatch.cpp | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index c96db6dcf80c7..5ae1ed8b251a4 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -116,6 +116,8 @@ using namespace clang; using namespace llvm::opt; static std::string standardizedTriple(std::string OrigTriple) { + if (OrigTriple.back() == '-') // Already standardized + return OrigTriple; llvm::Triple t = llvm::Triple(OrigTriple); return llvm::Triple(t.getArchName(), t.getVendorName(), t.getOSName(), t.getEnvironmentName()) @@ -5973,7 +5975,7 @@ class OffloadingActionBuilder final { Arch = C.getDriver().MakeSYCLDeviceTriple("spir64_fpga").str(); if (std::find(UniqueSections.begin(), UniqueSections.end(), Arch) == UniqueSections.end()) - UniqueSections.push_back(Arch); + UniqueSections.push_back(standardizedTriple(Arch)); } } diff --git a/clang/test/Driver/sycl-no-rdc-errors.cpp b/clang/test/Driver/sycl-no-rdc-errors.cpp index c10b3229c897b..10bae53ace443 100644 --- a/clang/test/Driver/sycl-no-rdc-errors.cpp +++ b/clang/test/Driver/sycl-no-rdc-errors.cpp @@ -5,7 +5,7 @@ // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,sycl-spir64_gen-unknown-unknown -input=%t -input=%t.o -output=%t.fat.o // RUN: not %clang -### -fsycl -fno-sycl-rdc %t.fat.o 2>&1 | FileCheck -check-prefix=CHECK-ARCH %s -// CHECK-ARCH: error: linked binaries do not contain expected 'spir64-unknown-unknown' target; found targets: 'spir64_gen-unknown-unknown--', this is not supported with '-fno-sycl-rdc' +// CHECK-ARCH: error: linked binaries do not contain expected 'spir64-unknown-unknown--' target; found targets: 'spir64_gen-unknown-unknown--', this is not supported with '-fno-sycl-rdc' // Some code so that we can create a binary out of this file. void test_func(void) { diff --git a/clang/test/Driver/sycl-target-mismatch.cpp b/clang/test/Driver/sycl-target-mismatch.cpp index 8b22ee45e6a89..ce22e45a81ade 100644 --- a/clang/test/Driver/sycl-target-mismatch.cpp +++ b/clang/test/Driver/sycl-target-mismatch.cpp @@ -8,7 +8,7 @@ // RUN: %clangxx -fsycl -fsycl-targets=spir64_gen %S/Inputs/SYCL/objlin64.o \ // RUN: -### %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=SPIR64_GEN_DIAG -// SPIR64_GEN_DIAG: linked binaries do not contain expected 'spir64_gen-unknown-unknown' target; found targets: 'spir64-unknown-unknown{{.*}}, spir64-unknown-unknown{{.*}}' [-Wsycl-target] +// SPIR64_GEN_DIAG: linked binaries do not contain expected 'spir64_gen-unknown-unknown--' target; found targets: 'spir64-unknown-unknown{{.*}}, spir64-unknown-unknown{{.*}}' [-Wsycl-target] // RUN: %clangxx -fsycl -fsycl-targets=spir64 %S/Inputs/SYCL/liblin64.a \ // RUN: -### %s 2>&1 \ @@ -33,7 +33,7 @@ // RUN: %clangxx -fsycl -fsycl-targets=nvptx64-nvidia-cuda -Xsycl-target-backend --cuda-gpu-arch=sm_60 \ // RUN: %S/Inputs/SYCL/objnvptx64-sm_50.o -### %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=NVPTX64_DIAG -// NVPTX64_DIAG: linked binaries do not contain expected 'nvptx64-nvidia-cuda-sm_60' target; found targets: 'nvptx64-nvidia-cuda-sm_50' [-Wsycl-target] +// NVPTX64_DIAG: linked binaries do not contain expected 'nvptx64-nvidia-cuda-sm_60-' target; found targets: 'nvptx64-nvidia-cuda-sm_50-' [-Wsycl-target] // RUN: %clangxx -fsycl -fsycl-targets=nvptx64-nvidia-cuda -Xsycl-target-backend --cuda-gpu-arch=sm_50 \ // RUN: %S/Inputs/SYCL/libnvptx64-sm_50.a -### %s 2>&1 \ @@ -61,7 +61,7 @@ // RUN: %clangxx -fsycl -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend --offload-arch=gfx906 \ // RUN: %S/Inputs/SYCL/objamdgcn-gfx908.o -### %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=AMDGCN_DIAG -// AMDGCN_DIAG: linked binaries do not contain expected 'amdgcn-amd-amdhsa-gfx906' target; found targets: 'amdgcn-amd-amdhsa-gfx908' [-Wsycl-target] +// AMDGCN_DIAG: linked binaries do not contain expected 'amdgcn-amd-amdhsa-gfx906-' target; found targets: 'amdgcn-amd-amdhsa-gfx908-' [-Wsycl-target] // RUN: %clangxx -fsycl -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend --offload-arch=gfx908 \ // RUN: %S/Inputs/SYCL/libamdgcn-gfx908.a -### %s 2>&1 \ From 19be7ab78079fac5224c09758f347a59d8e4e5fe Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Sun, 28 May 2023 08:55:16 -0700 Subject: [PATCH 06/10] Fix windows test fail Signed-off-by: Arvind Sudarsanam --- ...clang-offload-bundler-old-bundle-with-new-bundler.c | 10 ++++++++++ clang/test/Driver/clang-offload-bundler.c | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 clang/test/Driver/clang-offload-bundler-old-bundle-with-new-bundler.c diff --git a/clang/test/Driver/clang-offload-bundler-old-bundle-with-new-bundler.c b/clang/test/Driver/clang-offload-bundler-old-bundle-with-new-bundler.c new file mode 100644 index 0000000000000..69ad5cc5c8b5e --- /dev/null +++ b/clang/test/Driver/clang-offload-bundler-old-bundle-with-new-bundler.c @@ -0,0 +1,10 @@ +// REQUIRES: x86-registered-target +// UNSUPPORTED: target={{.*}}-darwin{{.*}}, target={{.*}}-aix{{.*}}, system-windows + +// Check working of bundler before and after standardization +// RUN: clang-offload-bundler -type=o -targets=host-x86_64-unknown-linux-gnu,sycl-spir64-unknown-unknown -input=%S/Inputs/bundles/bundle_bef_standardization_of_target_triple.o -output=test-host-x86_64-unknown-linux-gnu.o -output=test-sycl-spir64-unknown-unknown.o -unbundle 2>&1 | FileCheck %s -check-prefix=CHECK-STD-OLD --allow-empty +// CHECK-STD-OLD-NOT: error: Can't find bundles for +// RUN: clang-offload-bundler -type=o -targets=host-x86_64-unknown-linux-gnu,sycl-spir64-unknown-unknown -input=%S/Inputs/bundles/bundle_aft_standardization_of_target_triple.o -output=test-host-x86_64-unknown-linux-gnu.o -output=test-sycl-spir64-unknown-unknown.o -unbundle 2>&1 | FileCheck %s -check-prefix=CHECK-STD-NEW --allow-empty +// CHECK-STD-NEW-NOT: error: Can't find bundles for + + diff --git a/clang/test/Driver/clang-offload-bundler.c b/clang/test/Driver/clang-offload-bundler.c index f0cfd0233db7b..f7ac36883df73 100644 --- a/clang/test/Driver/clang-offload-bundler.c +++ b/clang/test/Driver/clang-offload-bundler.c @@ -573,12 +573,6 @@ // RUN: llvm-ar t %T/hip-openmp_906.a | FileCheck -check-prefix=OPENMPHIPCOMPAT %s // OPENMPHIPCOMPAT: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 -// Check working of bundler before and after standardization -// RUN: clang-offload-bundler -type=o -targets=host-x86_64-unknown-linux-gnu,sycl-spir64-unknown-unknown -input=%S/Inputs/bundles/bundle_bef_standardization_of_target_triple.o -output=test-host-x86_64-unknown-linux-gnu.o -output=test-sycl-spir64-unknown-unknown.o -unbundle 2>&1 | FileCheck %s -check-prefix=CHECK-STD-OLD --allow-empty -// CHECK-STD-OLD-NOT: error: Can't find bundles for -// RUN: clang-offload-bundler -type=o -targets=host-x86_64-unknown-linux-gnu,sycl-spir64-unknown-unknown -input=%S/Inputs/bundles/bundle_aft_standardization_of_target_triple.o -output=test-host-x86_64-unknown-linux-gnu.o -output=test-sycl-spir64-unknown-unknown.o -unbundle 2>&1 | FileCheck %s -check-prefix=CHECK-STD-NEW --allow-empty -// CHECK-STD-NEW-NOT: error: Can't find bundles for - // Some code so that we can create a binary out of this file. int A = 0; void test_func(void) { From 184c9e824cf024338e8ce93cf7dacf41722d4b0c Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Thu, 8 Jun 2023 16:33:27 -0700 Subject: [PATCH 07/10] Fix clang-offload-deps Signed-off-by: Arvind Sudarsanam --- .../clang-offload-deps/ClangOffloadDeps.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp b/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp index 835027f8db560..efe211315e6a8 100644 --- a/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp +++ b/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp @@ -74,6 +74,19 @@ static void reportError(Error E) { logAllUnhandledErrors(std::move(E), WithColor::error(errs(), ToolPath)); } +static std::string standardizedTarget(std::string OrigTarget) { + if (OrigTarget.back() == '-') // Already standardized + return OrigTarget; + StringRef Target(OrigTarget); + auto KindTriple = Target.split('-'); + llvm::Triple t = llvm::Triple(KindTriple.second); + return std::string(KindTriple.first) + "-" + + std::string(llvm::Triple(t.getArchName(), t.getVendorName(), + t.getOSName(), t.getEnvironmentName()) + .str()) + + "-"; +} + int main(int argc, const char **argv) { sys::PrintStackTraceOnErrorSignal(argv[0]); ToolPath = argv[0]; @@ -168,11 +181,10 @@ int main(int argc, const char **argv) { // offload targets and insert them into the map. 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'. for (const std::string &Target : Targets) { - std::string Prefix = Target + "."; + std::string Prefix = standardizedTarget(Target) + "."; if (Symbol.startswith(Prefix)) Target2Symbols[Target].insert( Symbol.substr(Prefix.size(), Len - Prefix.size())); From 02b0933eb97a81504ec8d5c65e79815b4a55f653 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Thu, 8 Jun 2023 16:58:50 -0700 Subject: [PATCH 08/10] Add a comment Signed-off-by: Arvind Sudarsanam --- clang/tools/clang-offload-deps/ClangOffloadDeps.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp b/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp index efe211315e6a8..86da5aa983ab6 100644 --- a/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp +++ b/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp @@ -74,6 +74,11 @@ static void reportError(Error E) { logAllUnhandledErrors(std::move(E), WithColor::error(errs(), ToolPath)); } +// clang-offload-bundler is currently generating a 'standardized' target triple. +// This is of the following form - Kind-Triple-TargetID. +// Triple's format - Architecture-Vendor-OS-Environment +// This routine transforms the target triple specified by user as input to +// clang-offload-deps to this 'standardized' format. static std::string standardizedTarget(std::string OrigTarget) { if (OrigTarget.back() == '-') // Already standardized return OrigTarget; From 04a6d5e316201332fe2991130c051bb0788ceb8c Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Fri, 9 Jun 2023 07:19:46 -0700 Subject: [PATCH 09/10] turning off test for windows temporarily Signed-off-by: Arvind Sudarsanam --- clang/test/Driver/clang-offload-bundler.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/Driver/clang-offload-bundler.c b/clang/test/Driver/clang-offload-bundler.c index f7ac36883df73..1d4f24db11b4b 100644 --- a/clang/test/Driver/clang-offload-bundler.c +++ b/clang/test/Driver/clang-offload-bundler.c @@ -1,5 +1,7 @@ // REQUIRES: x86-registered-target -// UNSUPPORTED: target={{.*}}-darwin{{.*}}, target={{.*}}-aix{{.*}} + +// TODO: Windows-related issue with temporary file creation - Fix and enable +// UNSUPPORTED: target={{.*}}-darwin{{.*}}, target={{.*}}-aix{{.*}}, system-windows // // Generate all the types of files we can bundle. From d44e71a53a2e51a265104c6cf387faaee2dd9c25 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Mon, 19 Jun 2023 12:35:57 -0700 Subject: [PATCH 10/10] Updated comments Signed-off-by: Arvind Sudarsanam --- clang/lib/Driver/Driver.cpp | 5 +++++ clang/tools/clang-offload-deps/ClangOffloadDeps.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index e59af4744e5ed..585dfd1a5d611 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -115,6 +115,11 @@ using namespace clang::driver; using namespace clang; using namespace llvm::opt; +// clang-offload-bundler is currently generating a 'standardized' target triple. +// Triple's format - Architecture-Vendor-OS-Environment. +// Bundle sections created by clang-offload-bundler contain the 'standardized' +// triple. This routine transforms the triple specified by user as input to this +// 'standardized' format to facilitate checks. static std::string standardizedTriple(std::string OrigTriple) { if (OrigTriple.back() == '-') // Already standardized return OrigTriple; diff --git a/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp b/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp index 86da5aa983ab6..979462a91ecd5 100644 --- a/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp +++ b/clang/tools/clang-offload-deps/ClangOffloadDeps.cpp @@ -74,10 +74,10 @@ static void reportError(Error E) { logAllUnhandledErrors(std::move(E), WithColor::error(errs(), ToolPath)); } -// clang-offload-bundler is currently generating a 'standardized' target triple. -// This is of the following form - Kind-Triple-TargetID. -// Triple's format - Architecture-Vendor-OS-Environment -// This routine transforms the target triple specified by user as input to +// clang-offload-bundler is currently generating a 'standardized' target header. +// This is of the following form - Kind-Triple-TargetID where triple's format is +// Architecture-Vendor-OS-Environment +// This routine transforms the target header specified by user as input to // clang-offload-deps to this 'standardized' format. static std::string standardizedTarget(std::string OrigTarget) { if (OrigTarget.back() == '-') // Already standardized