"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<
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",
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") {
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
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);
// 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");
});
}
+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()); };
AddBCLib(getCorrectlyRoundedSqrtPath(CorrectSqrt));
AddBCLib(getWavefrontSize64Path(Wave64));
AddBCLib(LibDeviceFile);
+ auto ABIVerPath = getABIVersionPath(ABIVer);
+ if (!ABIVerPath.empty())
+ AddBCLib(ABIVerPath);
return BCLibs;
}
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
return RocmInstallation.getCommonBitcodeLibs(
DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
- FastRelaxedMath, CorrectSqrt);
+ FastRelaxedMath, CorrectSqrt, ABIVer, isOpenMP);
}
// 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
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))
namespace clang {
namespace driver {
+/// ABI version of device library.
+struct DeviceLibABIVersion {
+ unsigned ABIVersion = 0;
+ DeviceLibABIVersion(unsigned V) : ABIVersion(V) {}
+ static DeviceLibABIVersion fromCodeObjectVersion(unsigned CodeObjectVersion) {
+ if (CodeObjectVersion < 4)
+ CodeObjectVersion = 4;
+ return DeviceLibABIVersion(CodeObjectVersion * 100);
+ }
+ /// Whether ABI version bc file is requested.
+ /// ABIVersion is code object version multiplied by 100. Code object v4
+ /// and below works with ROCm 5.0 and below which does not have
+ /// abi_version_*.bc. Code object v5 requires abi_version_500.bc.
+ bool requiresLibrary() { return ABIVersion >= 500; }
+ std::string toString() {
+ assert(ABIVersion % 100 == 0 && "Not supported");
+ return Twine(ABIVersion / 100).str();
+ }
+};
+
/// A class to find a viable ROCM installation
/// TODO: Generalize to handle libclc.
class RocmInstallationDetector {
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;
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; }
return CorrectlyRoundedSqrt.get(Enabled);
}
+ StringRef getABIVersionPath(DeviceLibABIVersion ABIVer) const {
+ auto Loc = ABIVersionMap.find(ABIVer.ABIVersion);
+ 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);
// 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 \
// 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"
// 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