Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp
35266 views
//===--- AMDGPU.cpp - Implement AMDGPU target feature support -------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements AMDGPU TargetInfo objects.9//10//===----------------------------------------------------------------------===//1112#include "AMDGPU.h"13#include "clang/Basic/Builtins.h"14#include "clang/Basic/CodeGenOptions.h"15#include "clang/Basic/Diagnostic.h"16#include "clang/Basic/LangOptions.h"17#include "clang/Basic/MacroBuilder.h"18#include "clang/Basic/TargetBuiltins.h"19#include "llvm/ADT/SmallString.h"20using namespace clang;21using namespace clang::targets;2223namespace clang {24namespace targets {2526// If you edit the description strings, make sure you update27// getPointerWidthV().2829static const char *const DataLayoutStringR600 =30"e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"31"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1";3233static const char *const DataLayoutStringAMDGCN =34"e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"35"-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:"36"32-v48:64-v96:128"37"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1"38"-ni:7:8:9";3940const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {41llvm::AMDGPUAS::FLAT_ADDRESS, // Default42llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global43llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local44llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant45llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private46llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic47llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device48llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host49llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device50llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant51llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared52llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global53llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_device54llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_host55llvm::AMDGPUAS::LOCAL_ADDRESS, // sycl_local56llvm::AMDGPUAS::PRIVATE_ADDRESS, // sycl_private57llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr58llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr59llvm::AMDGPUAS::FLAT_ADDRESS, // ptr6460llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared61};6263const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {64llvm::AMDGPUAS::PRIVATE_ADDRESS, // Default65llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global66llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local67llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant68llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private69llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic70llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device71llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host72llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device73llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant74llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared75// SYCL address space values for this map are dummy76llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global77llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_device78llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_host79llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local80llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private81llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr82llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr83llvm::AMDGPUAS::FLAT_ADDRESS, // ptr6484llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared8586};87} // namespace targets88} // namespace clang8990static constexpr Builtin::Info BuiltinInfo[] = {91#define BUILTIN(ID, TYPE, ATTRS) \92{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},93#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \94{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},95#include "clang/Basic/BuiltinsAMDGPU.def"96};9798const char *const AMDGPUTargetInfo::GCCRegNames[] = {99"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",100"v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17",101"v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26",102"v27", "v28", "v29", "v30", "v31", "v32", "v33", "v34", "v35",103"v36", "v37", "v38", "v39", "v40", "v41", "v42", "v43", "v44",104"v45", "v46", "v47", "v48", "v49", "v50", "v51", "v52", "v53",105"v54", "v55", "v56", "v57", "v58", "v59", "v60", "v61", "v62",106"v63", "v64", "v65", "v66", "v67", "v68", "v69", "v70", "v71",107"v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79", "v80",108"v81", "v82", "v83", "v84", "v85", "v86", "v87", "v88", "v89",109"v90", "v91", "v92", "v93", "v94", "v95", "v96", "v97", "v98",110"v99", "v100", "v101", "v102", "v103", "v104", "v105", "v106", "v107",111"v108", "v109", "v110", "v111", "v112", "v113", "v114", "v115", "v116",112"v117", "v118", "v119", "v120", "v121", "v122", "v123", "v124", "v125",113"v126", "v127", "v128", "v129", "v130", "v131", "v132", "v133", "v134",114"v135", "v136", "v137", "v138", "v139", "v140", "v141", "v142", "v143",115"v144", "v145", "v146", "v147", "v148", "v149", "v150", "v151", "v152",116"v153", "v154", "v155", "v156", "v157", "v158", "v159", "v160", "v161",117"v162", "v163", "v164", "v165", "v166", "v167", "v168", "v169", "v170",118"v171", "v172", "v173", "v174", "v175", "v176", "v177", "v178", "v179",119"v180", "v181", "v182", "v183", "v184", "v185", "v186", "v187", "v188",120"v189", "v190", "v191", "v192", "v193", "v194", "v195", "v196", "v197",121"v198", "v199", "v200", "v201", "v202", "v203", "v204", "v205", "v206",122"v207", "v208", "v209", "v210", "v211", "v212", "v213", "v214", "v215",123"v216", "v217", "v218", "v219", "v220", "v221", "v222", "v223", "v224",124"v225", "v226", "v227", "v228", "v229", "v230", "v231", "v232", "v233",125"v234", "v235", "v236", "v237", "v238", "v239", "v240", "v241", "v242",126"v243", "v244", "v245", "v246", "v247", "v248", "v249", "v250", "v251",127"v252", "v253", "v254", "v255", "s0", "s1", "s2", "s3", "s4",128"s5", "s6", "s7", "s8", "s9", "s10", "s11", "s12", "s13",129"s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",130"s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",131"s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39", "s40",132"s41", "s42", "s43", "s44", "s45", "s46", "s47", "s48", "s49",133"s50", "s51", "s52", "s53", "s54", "s55", "s56", "s57", "s58",134"s59", "s60", "s61", "s62", "s63", "s64", "s65", "s66", "s67",135"s68", "s69", "s70", "s71", "s72", "s73", "s74", "s75", "s76",136"s77", "s78", "s79", "s80", "s81", "s82", "s83", "s84", "s85",137"s86", "s87", "s88", "s89", "s90", "s91", "s92", "s93", "s94",138"s95", "s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103",139"s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112",140"s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121",141"s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc",142"m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi",143"flat_scratch_lo", "flat_scratch_hi",144"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8",145"a9", "a10", "a11", "a12", "a13", "a14", "a15", "a16", "a17",146"a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26",147"a27", "a28", "a29", "a30", "a31", "a32", "a33", "a34", "a35",148"a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44",149"a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53",150"a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62",151"a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71",152"a72", "a73", "a74", "a75", "a76", "a77", "a78", "a79", "a80",153"a81", "a82", "a83", "a84", "a85", "a86", "a87", "a88", "a89",154"a90", "a91", "a92", "a93", "a94", "a95", "a96", "a97", "a98",155"a99", "a100", "a101", "a102", "a103", "a104", "a105", "a106", "a107",156"a108", "a109", "a110", "a111", "a112", "a113", "a114", "a115", "a116",157"a117", "a118", "a119", "a120", "a121", "a122", "a123", "a124", "a125",158"a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134",159"a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143",160"a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152",161"a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161",162"a162", "a163", "a164", "a165", "a166", "a167", "a168", "a169", "a170",163"a171", "a172", "a173", "a174", "a175", "a176", "a177", "a178", "a179",164"a180", "a181", "a182", "a183", "a184", "a185", "a186", "a187", "a188",165"a189", "a190", "a191", "a192", "a193", "a194", "a195", "a196", "a197",166"a198", "a199", "a200", "a201", "a202", "a203", "a204", "a205", "a206",167"a207", "a208", "a209", "a210", "a211", "a212", "a213", "a214", "a215",168"a216", "a217", "a218", "a219", "a220", "a221", "a222", "a223", "a224",169"a225", "a226", "a227", "a228", "a229", "a230", "a231", "a232", "a233",170"a234", "a235", "a236", "a237", "a238", "a239", "a240", "a241", "a242",171"a243", "a244", "a245", "a246", "a247", "a248", "a249", "a250", "a251",172"a252", "a253", "a254", "a255"173};174175ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const {176return llvm::ArrayRef(GCCRegNames);177}178179bool AMDGPUTargetInfo::initFeatureMap(180llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,181const std::vector<std::string> &FeatureVec) const {182183using namespace llvm::AMDGPU;184fillAMDGPUFeatureMap(CPU, getTriple(), Features);185if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec))186return false;187188// TODO: Should move this logic into TargetParser189auto HasError = insertWaveSizeFeature(CPU, getTriple(), Features);190switch (HasError.first) {191default:192break;193case llvm::AMDGPU::INVALID_FEATURE_COMBINATION:194Diags.Report(diag::err_invalid_feature_combination) << HasError.second;195return false;196case llvm::AMDGPU::UNSUPPORTED_TARGET_FEATURE:197Diags.Report(diag::err_opt_not_valid_on_target) << HasError.second;198return false;199}200201return true;202}203204void AMDGPUTargetInfo::fillValidCPUList(205SmallVectorImpl<StringRef> &Values) const {206if (isAMDGCN(getTriple()))207llvm::AMDGPU::fillValidArchListAMDGCN(Values);208else209llvm::AMDGPU::fillValidArchListR600(Values);210}211212void AMDGPUTargetInfo::setAddressSpaceMap(bool DefaultIsPrivate) {213AddrSpaceMap = DefaultIsPrivate ? &AMDGPUDefIsPrivMap : &AMDGPUDefIsGenMap;214}215216AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,217const TargetOptions &Opts)218: TargetInfo(Triple),219GPUKind(isAMDGCN(Triple) ?220llvm::AMDGPU::parseArchAMDGCN(Opts.CPU) :221llvm::AMDGPU::parseArchR600(Opts.CPU)),222GPUFeatures(isAMDGCN(Triple) ?223llvm::AMDGPU::getArchAttrAMDGCN(GPUKind) :224llvm::AMDGPU::getArchAttrR600(GPUKind)) {225resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN226: DataLayoutStringR600);227228setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D ||229!isAMDGCN(Triple));230UseAddrSpaceMapMangling = true;231232if (isAMDGCN(Triple)) {233// __bf16 is always available as a load/store only type on AMDGCN.234BFloat16Width = BFloat16Align = 16;235BFloat16Format = &llvm::APFloat::BFloat();236}237238HasLegalHalfType = true;239HasFloat16 = true;240WavefrontSize = (GPUFeatures & llvm::AMDGPU::FEATURE_WAVE32) ? 32 : 64;241AllowAMDGPUUnsafeFPAtomics = Opts.AllowAMDGPUUnsafeFPAtomics;242243// Set pointer width and alignment for the generic address space.244PointerWidth = PointerAlign = getPointerWidthV(LangAS::Default);245if (getMaxPointerWidth() == 64) {246LongWidth = LongAlign = 64;247SizeType = UnsignedLong;248PtrDiffType = SignedLong;249IntPtrType = SignedLong;250}251252MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;253CUMode = !(GPUFeatures & llvm::AMDGPU::FEATURE_WGP);254for (auto F : {"image-insts", "gws"})255ReadOnlyFeatures.insert(F);256HalfArgsAndReturns = true;257}258259void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {260TargetInfo::adjust(Diags, Opts);261// ToDo: There are still a few places using default address space as private262// address space in OpenCL, which needs to be cleaned up, then Opts.OpenCL263// can be removed from the following line.264setAddressSpaceMap(/*DefaultIsPrivate=*/Opts.OpenCL ||265!isAMDGCN(getTriple()));266}267268ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const {269return llvm::ArrayRef(BuiltinInfo,270clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin);271}272273void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,274MacroBuilder &Builder) const {275Builder.defineMacro("__AMD__");276Builder.defineMacro("__AMDGPU__");277278if (isAMDGCN(getTriple()))279Builder.defineMacro("__AMDGCN__");280else281Builder.defineMacro("__R600__");282283// Legacy HIP host code relies on these default attributes to be defined.284bool IsHIPHost = Opts.HIP && !Opts.CUDAIsDevice;285if (GPUKind == llvm::AMDGPU::GK_NONE && !IsHIPHost)286return;287288llvm::SmallString<16> CanonName =289(isAMDGCN(getTriple()) ? getArchNameAMDGCN(GPUKind)290: getArchNameR600(GPUKind));291292// Sanitize the name of generic targets.293// e.g. gfx10-1-generic -> gfx10_1_generic294if (GPUKind >= llvm::AMDGPU::GK_AMDGCN_GENERIC_FIRST &&295GPUKind <= llvm::AMDGPU::GK_AMDGCN_GENERIC_LAST) {296std::replace(CanonName.begin(), CanonName.end(), '-', '_');297}298299Builder.defineMacro(Twine("__") + Twine(CanonName) + Twine("__"));300// Emit macros for gfx family e.g. gfx906 -> __GFX9__, gfx1030 -> __GFX10___301if (isAMDGCN(getTriple()) && !IsHIPHost) {302assert(StringRef(CanonName).starts_with("gfx") &&303"Invalid amdgcn canonical name");304StringRef CanonFamilyName = getArchFamilyNameAMDGCN(GPUKind);305Builder.defineMacro(Twine("__") + Twine(CanonFamilyName.upper()) +306Twine("__"));307Builder.defineMacro("__amdgcn_processor__",308Twine("\"") + Twine(CanonName) + Twine("\""));309Builder.defineMacro("__amdgcn_target_id__",310Twine("\"") + Twine(*getTargetID()) + Twine("\""));311for (auto F : getAllPossibleTargetIDFeatures(getTriple(), CanonName)) {312auto Loc = OffloadArchFeatures.find(F);313if (Loc != OffloadArchFeatures.end()) {314std::string NewF = F.str();315std::replace(NewF.begin(), NewF.end(), '-', '_');316Builder.defineMacro(Twine("__amdgcn_feature_") + Twine(NewF) +317Twine("__"),318Loc->second ? "1" : "0");319}320}321}322323if (AllowAMDGPUUnsafeFPAtomics)324Builder.defineMacro("__AMDGCN_UNSAFE_FP_ATOMICS__");325326// TODO: __HAS_FMAF__, __HAS_LDEXPF__, __HAS_FP64__ are deprecated and will be327// removed in the near future.328if (hasFMAF())329Builder.defineMacro("__HAS_FMAF__");330if (hasFastFMAF())331Builder.defineMacro("FP_FAST_FMAF");332if (hasLDEXPF())333Builder.defineMacro("__HAS_LDEXPF__");334if (hasFP64())335Builder.defineMacro("__HAS_FP64__");336if (hasFastFMA())337Builder.defineMacro("FP_FAST_FMA");338339Builder.defineMacro("__AMDGCN_WAVEFRONT_SIZE__", Twine(WavefrontSize));340// ToDo: deprecate this macro for naming consistency.341Builder.defineMacro("__AMDGCN_WAVEFRONT_SIZE", Twine(WavefrontSize));342Builder.defineMacro("__AMDGCN_CUMODE__", Twine(CUMode));343}344345void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) {346assert(HalfFormat == Aux->HalfFormat);347assert(FloatFormat == Aux->FloatFormat);348assert(DoubleFormat == Aux->DoubleFormat);349350// On x86_64 long double is 80-bit extended precision format, which is351// not supported by AMDGPU. 128-bit floating point format is also not352// supported by AMDGPU. Therefore keep its own format for these two types.353auto SaveLongDoubleFormat = LongDoubleFormat;354auto SaveFloat128Format = Float128Format;355auto SaveLongDoubleWidth = LongDoubleWidth;356auto SaveLongDoubleAlign = LongDoubleAlign;357copyAuxTarget(Aux);358LongDoubleFormat = SaveLongDoubleFormat;359Float128Format = SaveFloat128Format;360LongDoubleWidth = SaveLongDoubleWidth;361LongDoubleAlign = SaveLongDoubleAlign;362// For certain builtin types support on the host target, claim they are363// support to pass the compilation of the host code during the device-side364// compilation.365// FIXME: As the side effect, we also accept `__float128` uses in the device366// code. To rejct these builtin types supported in the host target but not in367// the device target, one approach would support `device_builtin` attribute368// so that we could tell the device builtin types from the host ones. The369// also solves the different representations of the same builtin type, such370// as `size_t` in the MSVC environment.371if (Aux->hasFloat128Type()) {372HasFloat128 = true;373Float128Format = DoubleFormat;374}375}376377378