diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1777,6 +1777,12 @@ std::string AdditionalArgs("-allow-missing-bundles"); UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs)); + // Add this flag to treat hip and hipv4 offload kinds as compatible with + // openmp offload kind while extracting code objects from a heterogenous + // archive library. Vice versa is also considered compatible. + std::string HipCompatibleArgs("-hip-openmp-compatible"); + UBArgs.push_back(C.getArgs().MakeArgString(HipCompatibleArgs)); + C.addCommand(std::make_unique( JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs, InputInfo(&JA, C.getArgs().MakeArgString(OutputLib)))); diff --git a/clang/test/Driver/clang-offload-bundler-asserts-on.c b/clang/test/Driver/clang-offload-bundler-asserts-on.c --- a/clang/test/Driver/clang-offload-bundler-asserts-on.c +++ b/clang/test/Driver/clang-offload-bundler-asserts-on.c @@ -24,6 +24,10 @@ // 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 -inputs=%t.input-archive.a -outputs=%t-hip-archive-gfx906-simple.a,%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] + // 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/clang-offload-bundler.c b/clang/test/Driver/clang-offload-bundler.c --- a/clang/test/Driver/clang-offload-bundler.c +++ b/clang/test/Driver/clang-offload-bundler.c @@ -406,6 +406,7 @@ // Create few code object bundles and archive them to create an input archive // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-amdgcn-amd-amdhsa-gfx906,openmp-amdgcn-amd-amdhsa--gfx908 -inputs=%t.o,%t.tgt1,%t.tgt2 -outputs=%t.simple.bundle // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-amdgcn-amd-amdhsa--gfx903 -inputs=%t.o,%t.tgt1 -outputs=%t.simple1.bundle +// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,hip-amdgcn-amd-amdhsa--gfx906 -inputs=%t.o,%t.tgt1 -outputs=%t.simple1.bundle // RUN: llvm-ar cr %t.input-archive.a %t.simple.bundle %t.simple1.bundle // RUN: clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa-gfx906,openmp-amdgcn-amd-amdhsa-gfx908 -inputs=%t.input-archive.a -outputs=%t-archive-gfx906-simple.a,%t-archive-gfx908-simple.a @@ -423,6 +424,19 @@ // RUN: cat %t-archive-gfx803-empty.a | FileCheck %s -check-prefix=EMPTYARCHIVE // EMPTYARCHIVE: ! +// 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 -inputs=%t.input-archive.a -outputs=%t-hip-archive-gfx906-simple.a,%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 +// RUN: llvm-ar t %t-hipv4-archive-gfx908-simple.a | FileCheck %s -check-prefix=HIPv4OPENMPCOMPAT +// HIPv4OPENMPCOMPAT: simple-openmp-amdgcn-amd-amdhsa--gfx908 + +// Check compatibility of HIP code objects found in the heterogeneous archive library with OpenMP code objects of the target +// RUN: clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa--gfx906 \ +// RUN: -outputs=%T/hip-openmp_906.a -inputs=%T/hip_archive.a -hip-openmp-compatible +// RUN: llvm-ar t %T/hip-openmp_906.a | FileCheck -check-prefix=OPENMPHIPCOMPAT %s +// OPENMPHIPCOMPAT: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 + // Some code so that we can create a binary out of this file. int A = 0; void test_func(void) { diff --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp --- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp +++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp @@ -117,6 +117,12 @@ cl::desc("Alignment of bundle for binary files"), cl::init(1), cl::cat(ClangOffloadBundlerCategory)); +static cl::opt HipOpenmpCompatible( + "hip-openmp-compatible", + cl::desc("Treat hip and hipv4 offload kinds as " + "compatible with openmp kind, and vice versa.\n"), + cl::init(false), cl::cat(ClangOffloadBundlerCategory)); + /// Magic string that marks the existence of offloading data. #define OFFLOAD_BUNDLER_MAGIC_STR "__CLANG_OFFLOAD_BUNDLE__" @@ -166,6 +172,21 @@ OffloadKind == "hip" || OffloadKind == "hipv4"; } + bool isOffloadKindCompatible(const StringRef TargetOffloadKind) const { + if (OffloadKind == TargetOffloadKind) + return true; + if (HipOpenmpCompatible) { + bool HIPCompatibleWithOpenMP = + OffloadKind.startswith_insensitive("hip") && + TargetOffloadKind == "openmp"; + bool OpenMPCompatibleWithHIP = + OffloadKind == "openmp" && + TargetOffloadKind.startswith_insensitive("hip"); + return HIPCompatibleWithOpenMP || OpenMPCompatibleWithHIP; + } + return false; + } + bool isTripleValid() const { return !Triple.str().empty() && Triple.getArch() != Triple::UnknownArch; } @@ -1097,7 +1118,7 @@ } // Incompatible if Kinds or Triples mismatch. - if (CodeObjectInfo.OffloadKind != TargetInfo.OffloadKind || + if (!CodeObjectInfo.isOffloadKindCompatible(TargetInfo.OffloadKind) || !CodeObjectInfo.Triple.isCompatibleWith(TargetInfo.Triple)) { DEBUG_WITH_TYPE( "CodeObjectCompatibility",