yaxunl created this revision.
yaxunl added reviewers: tra, b-sumner.
Herald added subscribers: dang, kerbowa, jvesely.
yaxunl requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added a subscriber: sstefan1.

New device library supporting v4 and v5 has abi_version_400.bc and 
abi_version_500.bc.

For v5, abi_version_500.bc is linked.

For v2-4, abi_version_400.bc is linked.

For old device library, for v2-4, none of the above is linked. For v5, error is 
emitted about unsupported ABI version.


https://reviews.llvm.org/D118949

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/AMDGPU.cpp
  clang/lib/Driver/ToolChains/AMDGPU.h
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/ROCm.h
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/asanrtl.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/hip.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/ockl.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_correctly_rounded_sqrt_off.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_correctly_rounded_sqrt_on.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_daz_opt_off.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_daz_opt_on.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_finite_only_off.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_finite_only_on.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_isa_version_1010.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_isa_version_1011.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_isa_version_1012.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_isa_version_803.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_isa_version_900.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_isa_version_908.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_unsafe_math_off.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_unsafe_math_on.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_wavefrontsize64_off.bc
  
clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/oclc_wavefrontsize64_on.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/ocml.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode-no-abi-ver/opencl.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode/abi_version_400.bc
  clang/test/Driver/Inputs/rocm/amdgcn/bitcode/abi_version_500.bc
  clang/test/Driver/hip-code-object-version.hip
  clang/test/Driver/hip-device-libs.hip

Index: clang/test/Driver/hip-device-libs.hip
===================================================================
--- clang/test/Driver/hip-device-libs.hip
+++ clang/test/Driver/hip-device-libs.hip
@@ -137,6 +137,49 @@
 // RUN:   --rocm-path=%S/Inputs/rocm %S/Inputs/hip_multiple_inputs/b.hip \
 // RUN: 2>&1 | FileCheck %s --check-prefixes=DIVSQRT
 
+// Test default code object version.
+// RUN: %clang -### -target x86_64-linux-gnu --offload-arch=gfx900 \
+// RUN:   --rocm-path=%S/Inputs/rocm %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=ABI4
+
+// Test default code object version with old device library without abi_version_400.bc
+// RUN: %clang -### -target x86_64-linux-gnu --offload-arch=gfx900 \
+// RUN:   --hip-device-lib-path=%S/Inputs/rocm/amdgcn/bitcode-no-abi-ver   \
+// RUN:   --rocm-path=%S/Inputs/rocm %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=NOABI4
+
+// Test -mcode-object-version=3
+// RUN: %clang -### -target x86_64-linux-gnu --offload-arch=gfx900 \
+// RUN:   -mcode-object-version=3 \
+// RUN:   --rocm-path=%S/Inputs/rocm %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=ABI4
+
+// Test -mcode-object-version=4
+// RUN: %clang -### -target x86_64-linux-gnu --offload-arch=gfx900 \
+// RUN:   -mcode-object-version=4 \
+// RUN:   --rocm-path=%S/Inputs/rocm %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=ABI4
+
+// Test -mcode-object-version=4 with old device library without abi_version_400.bc
+// RUN: %clang -### -target x86_64-linux-gnu --offload-arch=gfx900 \
+// RUN:   -mcode-object-version=4 \
+// RUN:   --hip-device-lib-path=%S/Inputs/rocm/amdgcn/bitcode-no-abi-ver   \
+// RUN:   --rocm-path=%S/Inputs/rocm %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=NOABI4
+
+// Test -mcode-object-version=5
+// RUN: %clang -### -target x86_64-linux-gnu --offload-arch=gfx900 \
+// RUN:   -mcode-object-version=5 \
+// RUN:   --rocm-path=%S/Inputs/rocm %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=ABI5
+
+// Test -mcode-object-version=5 with old device library without abi_version_400.bc
+// RUN: %clang -### -target x86_64-linux-gnu --offload-arch=gfx900 \
+// RUN:   -mcode-object-version=5 \
+// RUN:   --hip-device-lib-path=%S/Inputs/rocm/amdgcn/bitcode-no-abi-ver   \
+// RUN:   --rocm-path=%S/Inputs/rocm %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=NOABI5
+
 // ALL-NOT: error:
 // ALL: {{"[^"]*clang[^"]*"}}
 // ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}hip.bc"
@@ -172,3 +215,12 @@
 // DIVSQRT-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_unsafe_math_off.bc"
 // DIVSQRT-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_finite_only_off.bc"
 // DIVSQRT-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_correctly_rounded_sqrt_off.bc"
+
+// ABI4-NOT: error:
+// ABI4: "-mlink-builtin-bitcode" "{{.*}}abi_version_400.bc"
+// ABI5-NOT: error:
+// ABI5: "-mlink-builtin-bitcode" "{{.*}}abi_version_500.bc"
+// NOABI4-NOT: error:
+// NOABI4-NOT: "-mlink-builtin-bitcode" "{{.*}}abi_version_400.bc"
+// NOABI4-NOT: "-mlink-builtin-bitcode" "{{.*}}abi_version_500.bc"
+// NOABI5: error: cannot find ROCm device libraryfor ABI version 5; provide its path via '--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build without ROCm device library
Index: clang/test/Driver/hip-code-object-version.hip
===================================================================
--- clang/test/Driver/hip-code-object-version.hip
+++ clang/test/Driver/hip-code-object-version.hip
@@ -47,6 +47,16 @@
 // V4: "-mllvm" "--amdhsa-code-object-version=4"
 // V4: "-targets=host-x86_64-unknown-linux,hipv4-amdgcn-amd-amdhsa--gfx906"
 
+// Check bundle ID for code object version 5.
+
+// RUN: %clang -### -target x86_64-linux-gnu \
+// RUN:   -mcode-object-version=5 \
+// RUN:   --offload-arch=gfx906 -nogpulib \
+// RUN:   %s 2>&1 | FileCheck -check-prefix=V5 %s
+
+// V5: "-mllvm" "--amdhsa-code-object-version=5"
+// V5: "-targets=host-x86_64-unknown-linux,hipv4-amdgcn-amd-amdhsa--gfx906"
+
 // Check bundle ID for code object version default
 
 // RUN: %clang -### -target x86_64-linux-gnu \
Index: clang/lib/Driver/ToolChains/ROCm.h
===================================================================
--- clang/lib/Driver/ToolChains/ROCm.h
+++ clang/lib/Driver/ToolChains/ROCm.h
@@ -22,6 +22,23 @@
 namespace clang {
 namespace driver {
 
+/// ABI version of device library.
+struct DeviceLibABIVersion {
+  unsigned Value = 0;
+  DeviceLibABIVersion(unsigned V) : Value(V) {}
+  static DeviceLibABIVersion fromCodeObjectVersion(unsigned V) {
+    if (V < 4)
+      V = 4;
+    return DeviceLibABIVersion(V * 100);
+  }
+  /// Whether ABI version bc file is requested.
+  bool requiresLibrary() { return Value >= 500; }
+  std::string toString() {
+    assert(Value % 100 == 0 && "Not supported");
+    return Twine(Value / 100).str();
+  }
+};
+
 /// A class to find a viable ROCM installation
 /// TODO: Generalize to handle libclc.
 class RocmInstallationDetector {
@@ -107,6 +124,10 @@
   ConditionalLibrary DenormalsAreZero;
   ConditionalLibrary CorrectlyRoundedSqrt;
 
+  // Maps ABI version to library path. The version number is in the format of
+  // three digits as used in the ABI version library name.
+  std::map<unsigned, std::string> ABIVersionMap;
+
   // Cache ROCm installation search paths.
   SmallVector<Candidate, 4> ROCmSearchDirs;
   bool PrintROCmSearchDirs;
@@ -142,7 +163,12 @@
   getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs,
                        StringRef LibDeviceFile, bool Wave64, bool DAZ,
                        bool FiniteOnly, bool UnsafeMathOpt,
-                       bool FastRelaxedMath, bool CorrectSqrt) const;
+                       bool FastRelaxedMath, bool CorrectSqrt,
+                       DeviceLibABIVersion ABIVer, bool isOpenMP) const;
+  /// Check file paths of default bitcode libraries common to AMDGPU based
+  /// toolchains. \returns false if there are invalid or missing files.
+  bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile,
+                              DeviceLibABIVersion ABIVer) const;
 
   /// Check whether we detected a valid HIP runtime.
   bool hasHIPRuntime() const { return HasHIPRuntime; }
@@ -214,6 +240,13 @@
     return CorrectlyRoundedSqrt.get(Enabled);
   }
 
+  StringRef getABIVersionPath(DeviceLibABIVersion ABIVer) const {
+    auto Loc = ABIVersionMap.find(ABIVer.Value);
+    if (Loc == ABIVersionMap.end())
+      return StringRef();
+    return Loc->second;
+  }
+
   /// Get libdevice file for given architecture
   std::string getLibDeviceFile(StringRef Gpu) const {
     return LibDeviceMap.lookup(Gpu);
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1910,7 +1910,7 @@
 void tools::checkAMDGPUCodeObjectVersion(const Driver &D,
                                          const llvm::opt::ArgList &Args) {
   const unsigned MinCodeObjVer = 2;
-  const unsigned MaxCodeObjVer = 4;
+  const unsigned MaxCodeObjVer = 5;
 
   // Emit warnings for legacy options even if they are overridden.
   if (Args.hasArg(options::OPT_mno_code_object_v3_legacy))
Index: clang/lib/Driver/ToolChains/AMDGPU.h
===================================================================
--- clang/lib/Driver/ToolChains/AMDGPU.h
+++ clang/lib/Driver/ToolChains/AMDGPU.h
@@ -142,7 +142,8 @@
   // Returns a list of device library names shared by different languages
   llvm::SmallVector<std::string, 12>
   getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
-                          const std::string &GPUArch) const;
+                          const std::string &GPUArch,
+                          bool isOpenMP = false) const;
 };
 
 } // end namespace toolchains
Index: clang/lib/Driver/ToolChains/AMDGPU.cpp
===================================================================
--- clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -91,6 +91,7 @@
     else if (FileName.endswith(Suffix))
       BaseName = FileName.drop_back(Suffix.size());
 
+    const StringRef ABIVersionPrefix = "abi_version_";
     if (BaseName == "ocml") {
       OCML = FilePath;
     } else if (BaseName == "ockl") {
@@ -121,6 +122,12 @@
       WavefrontSize64.On = FilePath;
     } else if (BaseName == "oclc_wavefrontsize64_off") {
       WavefrontSize64.Off = FilePath;
+    } else if (BaseName.startswith(ABIVersionPrefix)) {
+      unsigned ABIVersionNumber;
+      if (BaseName.drop_front(ABIVersionPrefix.size())
+              .getAsInteger(/*Redex=*/0, ABIVersionNumber))
+        continue;
+      ABIVersionMap[ABIVersionNumber] = FilePath.str();
     } else {
       // Process all bitcode filenames that look like
       // ocl_isa_version_XXX.amdgcn.bc
@@ -822,20 +829,16 @@
   if (DriverArgs.hasArg(options::OPT_nogpulib))
     return;
 
-  if (!RocmInstallation.hasDeviceLibrary()) {
-    getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
-    return;
-  }
-
   // Get the device name and canonicalize it
   const StringRef GpuArch = getGPUArch(DriverArgs);
   auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch);
   const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
   std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
-  if (LibDeviceFile.empty()) {
-    getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GpuArch;
+  auto ABIVer = DeviceLibABIVersion::fromCodeObjectVersion(
+      getAMDGPUCodeObjectVersion(getDriver(), DriverArgs));
+  if (!RocmInstallation.checkCommonBitcodeLibs(CanonArch, LibDeviceFile,
+                                               ABIVer))
     return;
-  }
 
   bool Wave64 = isWave64(DriverArgs, Kind);
 
@@ -858,7 +861,7 @@
   // Add the generic set of libraries.
   BCLibs.append(RocmInstallation.getCommonBitcodeLibs(
       DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
-      FastRelaxedMath, CorrectSqrt));
+      FastRelaxedMath, CorrectSqrt, ABIVer, false));
 
   llvm::for_each(BCLibs, [&](StringRef BCFile) {
     CC1Args.push_back("-mlink-builtin-bitcode");
@@ -866,12 +869,29 @@
   });
 }
 
+bool RocmInstallationDetector::checkCommonBitcodeLibs(
+    StringRef GPUArch, StringRef LibDeviceFile,
+    DeviceLibABIVersion ABIVer) const {
+  if (!hasDeviceLibrary()) {
+    D.Diag(diag::err_drv_no_rocm_device_lib) << 0;
+    return false;
+  }
+  if (LibDeviceFile.empty()) {
+    D.Diag(diag::err_drv_no_rocm_device_lib) << 1 << GPUArch;
+    return false;
+  }
+  if (ABIVer.requiresLibrary() && getABIVersionPath(ABIVer).empty()) {
+    D.Diag(diag::err_drv_no_rocm_device_lib) << 2 << ABIVer.toString();
+    return false;
+  }
+  return true;
+}
+
 llvm::SmallVector<std::string, 12>
 RocmInstallationDetector::getCommonBitcodeLibs(
     const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, bool Wave64,
     bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath,
-    bool CorrectSqrt) const {
-
+    bool CorrectSqrt, DeviceLibABIVersion ABIVer, bool isOpenMP = false) const {
   llvm::SmallVector<std::string, 12> BCLibs;
 
   auto AddBCLib = [&](StringRef BCFile) { BCLibs.push_back(BCFile.str()); };
@@ -884,6 +904,9 @@
   AddBCLib(getCorrectlyRoundedSqrtPath(CorrectSqrt));
   AddBCLib(getWavefrontSize64Path(Wave64));
   AddBCLib(LibDeviceFile);
+  auto ABIVerPath = getABIVersionPath(ABIVer);
+  if (!ABIVerPath.empty())
+    AddBCLib(ABIVerPath);
 
   return BCLibs;
 }
@@ -897,15 +920,17 @@
 
 llvm::SmallVector<std::string, 12>
 ROCMToolChain::getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
-                                       const std::string &GPUArch) const {
+                                       const std::string &GPUArch,
+                                       bool isOpenMP) const {
   auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch);
   const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
 
   std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
-  if (LibDeviceFile.empty()) {
-    getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GPUArch;
+  auto ABIVer = DeviceLibABIVersion::fromCodeObjectVersion(
+      getAMDGPUCodeObjectVersion(getDriver(), DriverArgs));
+  if (!RocmInstallation.checkCommonBitcodeLibs(CanonArch, LibDeviceFile,
+                                               ABIVer))
     return {};
-  }
 
   // If --hip-device-lib is not set, add the default bitcode libraries.
   // TODO: There are way too many flags that change this. Do we need to check
@@ -927,5 +952,5 @@
 
   return RocmInstallation.getCommonBitcodeLibs(
       DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
-      FastRelaxedMath, CorrectSqrt);
+      FastRelaxedMath, CorrectSqrt, ABIVer, isOpenMP);
 }
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -3440,8 +3440,8 @@
   NegFlag<SetFalse, [CC1Option]>>, Group<m_Group>;
 
 def mcode_object_version_EQ : Joined<["-"], "mcode-object-version=">, Group<m_Group>,
-  HelpText<"Specify code object ABI version. Defaults to 3. (AMDGPU only)">,
-  MetaVarName<"<version>">, Values<"2,3,4">;
+  HelpText<"Specify code object ABI version. Defaults to 4. (AMDGPU only)">,
+  MetaVarName<"<version>">, Values<"2,3,4,5">;
 
 defm code_object_v3_legacy : SimpleMFlag<"code-object-v3",
   "Legacy option to specify code object ABI V3",
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -67,7 +67,7 @@
   "libdevice">;
 
 def err_drv_no_rocm_device_lib : Error<
-  "cannot find ROCm device library%select{| for %1}0; provide its path via "
+  "cannot find ROCm device library%select{| for %1|for ABI version %1}0; provide its path via "
   "'--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build "
   "without ROCm device library">;
 def err_drv_no_hip_runtime : Error<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to