393 lines · cpp
1//===--- AMDGPU.cpp - Implement AMDGPU target feature support -------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements AMDGPU TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#include "AMDGPU.h"14#include "clang/Basic/Builtins.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;22 23namespace clang {24namespace targets {25 26// If you edit the description strings, make sure you update27// getPointerWidthV().28 29static const char *const DataLayoutStringR600 =30 "e-m: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";32 33static const char *const DataLayoutStringAMDGCN =34 "e-m: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:128:48-p9:192:256:256:32-i64:64-"36 "v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-"37 "v2048:2048-n32:64-S32-A5-G1-ni:7:8:9";38 39const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {40 llvm::AMDGPUAS::FLAT_ADDRESS, // Default41 llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global42 llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local43 llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant44 llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private45 llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic46 llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device47 llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host48 llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device49 llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant50 llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared51 llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global52 llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_device53 llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_host54 llvm::AMDGPUAS::LOCAL_ADDRESS, // sycl_local55 llvm::AMDGPUAS::PRIVATE_ADDRESS, // sycl_private56 llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr57 llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr58 llvm::AMDGPUAS::FLAT_ADDRESS, // ptr6459 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared60 llvm::AMDGPUAS::CONSTANT_ADDRESS, // hlsl_constant61 // FIXME(pr/122103): hlsl_private -> PRIVATE is wrong, but at least this62 // will break loudly.63 llvm::AMDGPUAS::PRIVATE_ADDRESS, // hlsl_private64 llvm::AMDGPUAS::GLOBAL_ADDRESS, // hlsl_device65 llvm::AMDGPUAS::PRIVATE_ADDRESS, // hlsl_input66};67 68const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {69 llvm::AMDGPUAS::PRIVATE_ADDRESS, // Default70 llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global71 llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local72 llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant73 llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private74 llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic75 llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device76 llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host77 llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device78 llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant79 llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared80 // SYCL address space values for this map are dummy81 llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global82 llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_device83 llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_host84 llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local85 llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private86 llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr87 llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr88 llvm::AMDGPUAS::FLAT_ADDRESS, // ptr6489 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared90 llvm::AMDGPUAS::CONSTANT_ADDRESS, // hlsl_constant91 llvm::AMDGPUAS::PRIVATE_ADDRESS, // hlsl_private92 llvm::AMDGPUAS::GLOBAL_ADDRESS, // hlsl_device93 llvm::AMDGPUAS::PRIVATE_ADDRESS, // hlsl_input94};95} // namespace targets96} // namespace clang97 98static constexpr int NumBuiltins =99 clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin;100 101static constexpr llvm::StringTable BuiltinStrings =102 CLANG_BUILTIN_STR_TABLE_START103#define BUILTIN CLANG_BUILTIN_STR_TABLE104#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE105#include "clang/Basic/BuiltinsAMDGPU.def"106 ;107 108static constexpr auto BuiltinInfos = Builtin::MakeInfos<NumBuiltins>({109#define BUILTIN CLANG_BUILTIN_ENTRY110#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY111#include "clang/Basic/BuiltinsAMDGPU.def"112});113 114const char *const AMDGPUTargetInfo::GCCRegNames[] = {115 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",116 "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17",117 "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26",118 "v27", "v28", "v29", "v30", "v31", "v32", "v33", "v34", "v35",119 "v36", "v37", "v38", "v39", "v40", "v41", "v42", "v43", "v44",120 "v45", "v46", "v47", "v48", "v49", "v50", "v51", "v52", "v53",121 "v54", "v55", "v56", "v57", "v58", "v59", "v60", "v61", "v62",122 "v63", "v64", "v65", "v66", "v67", "v68", "v69", "v70", "v71",123 "v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79", "v80",124 "v81", "v82", "v83", "v84", "v85", "v86", "v87", "v88", "v89",125 "v90", "v91", "v92", "v93", "v94", "v95", "v96", "v97", "v98",126 "v99", "v100", "v101", "v102", "v103", "v104", "v105", "v106", "v107",127 "v108", "v109", "v110", "v111", "v112", "v113", "v114", "v115", "v116",128 "v117", "v118", "v119", "v120", "v121", "v122", "v123", "v124", "v125",129 "v126", "v127", "v128", "v129", "v130", "v131", "v132", "v133", "v134",130 "v135", "v136", "v137", "v138", "v139", "v140", "v141", "v142", "v143",131 "v144", "v145", "v146", "v147", "v148", "v149", "v150", "v151", "v152",132 "v153", "v154", "v155", "v156", "v157", "v158", "v159", "v160", "v161",133 "v162", "v163", "v164", "v165", "v166", "v167", "v168", "v169", "v170",134 "v171", "v172", "v173", "v174", "v175", "v176", "v177", "v178", "v179",135 "v180", "v181", "v182", "v183", "v184", "v185", "v186", "v187", "v188",136 "v189", "v190", "v191", "v192", "v193", "v194", "v195", "v196", "v197",137 "v198", "v199", "v200", "v201", "v202", "v203", "v204", "v205", "v206",138 "v207", "v208", "v209", "v210", "v211", "v212", "v213", "v214", "v215",139 "v216", "v217", "v218", "v219", "v220", "v221", "v222", "v223", "v224",140 "v225", "v226", "v227", "v228", "v229", "v230", "v231", "v232", "v233",141 "v234", "v235", "v236", "v237", "v238", "v239", "v240", "v241", "v242",142 "v243", "v244", "v245", "v246", "v247", "v248", "v249", "v250", "v251",143 "v252", "v253", "v254", "v255", "s0", "s1", "s2", "s3", "s4",144 "s5", "s6", "s7", "s8", "s9", "s10", "s11", "s12", "s13",145 "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",146 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",147 "s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39", "s40",148 "s41", "s42", "s43", "s44", "s45", "s46", "s47", "s48", "s49",149 "s50", "s51", "s52", "s53", "s54", "s55", "s56", "s57", "s58",150 "s59", "s60", "s61", "s62", "s63", "s64", "s65", "s66", "s67",151 "s68", "s69", "s70", "s71", "s72", "s73", "s74", "s75", "s76",152 "s77", "s78", "s79", "s80", "s81", "s82", "s83", "s84", "s85",153 "s86", "s87", "s88", "s89", "s90", "s91", "s92", "s93", "s94",154 "s95", "s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103",155 "s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112",156 "s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121",157 "s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc",158 "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi",159 "flat_scratch_lo", "flat_scratch_hi",160 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8",161 "a9", "a10", "a11", "a12", "a13", "a14", "a15", "a16", "a17",162 "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26",163 "a27", "a28", "a29", "a30", "a31", "a32", "a33", "a34", "a35",164 "a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44",165 "a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53",166 "a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62",167 "a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71",168 "a72", "a73", "a74", "a75", "a76", "a77", "a78", "a79", "a80",169 "a81", "a82", "a83", "a84", "a85", "a86", "a87", "a88", "a89",170 "a90", "a91", "a92", "a93", "a94", "a95", "a96", "a97", "a98",171 "a99", "a100", "a101", "a102", "a103", "a104", "a105", "a106", "a107",172 "a108", "a109", "a110", "a111", "a112", "a113", "a114", "a115", "a116",173 "a117", "a118", "a119", "a120", "a121", "a122", "a123", "a124", "a125",174 "a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134",175 "a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143",176 "a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152",177 "a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161",178 "a162", "a163", "a164", "a165", "a166", "a167", "a168", "a169", "a170",179 "a171", "a172", "a173", "a174", "a175", "a176", "a177", "a178", "a179",180 "a180", "a181", "a182", "a183", "a184", "a185", "a186", "a187", "a188",181 "a189", "a190", "a191", "a192", "a193", "a194", "a195", "a196", "a197",182 "a198", "a199", "a200", "a201", "a202", "a203", "a204", "a205", "a206",183 "a207", "a208", "a209", "a210", "a211", "a212", "a213", "a214", "a215",184 "a216", "a217", "a218", "a219", "a220", "a221", "a222", "a223", "a224",185 "a225", "a226", "a227", "a228", "a229", "a230", "a231", "a232", "a233",186 "a234", "a235", "a236", "a237", "a238", "a239", "a240", "a241", "a242",187 "a243", "a244", "a245", "a246", "a247", "a248", "a249", "a250", "a251",188 "a252", "a253", "a254", "a255"189};190 191ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const {192 return llvm::ArrayRef(GCCRegNames);193}194 195bool AMDGPUTargetInfo::initFeatureMap(196 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,197 const std::vector<std::string> &FeatureVec) const {198 199 using namespace llvm::AMDGPU;200 201 if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec))202 return false;203 204 auto HasError = fillAMDGPUFeatureMap(CPU, getTriple(), Features);205 switch (HasError.first) {206 default:207 break;208 case llvm::AMDGPU::INVALID_FEATURE_COMBINATION:209 Diags.Report(diag::err_invalid_feature_combination) << HasError.second;210 return false;211 case llvm::AMDGPU::UNSUPPORTED_TARGET_FEATURE:212 Diags.Report(diag::err_opt_not_valid_on_target) << HasError.second;213 return false;214 }215 216 return true;217}218 219void AMDGPUTargetInfo::fillValidCPUList(220 SmallVectorImpl<StringRef> &Values) const {221 if (isAMDGCN(getTriple()))222 llvm::AMDGPU::fillValidArchListAMDGCN(Values);223 else224 llvm::AMDGPU::fillValidArchListR600(Values);225}226 227void AMDGPUTargetInfo::setAddressSpaceMap(bool DefaultIsPrivate) {228 AddrSpaceMap = DefaultIsPrivate ? &AMDGPUDefIsPrivMap : &AMDGPUDefIsGenMap;229}230 231AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,232 const TargetOptions &Opts)233 : TargetInfo(Triple),234 GPUKind(isAMDGCN(Triple) ?235 llvm::AMDGPU::parseArchAMDGCN(Opts.CPU) :236 llvm::AMDGPU::parseArchR600(Opts.CPU)),237 GPUFeatures(isAMDGCN(Triple) ?238 llvm::AMDGPU::getArchAttrAMDGCN(GPUKind) :239 llvm::AMDGPU::getArchAttrR600(GPUKind)) {240 resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN241 : DataLayoutStringR600);242 243 setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D ||244 !isAMDGCN(Triple));245 UseAddrSpaceMapMangling = true;246 247 if (isAMDGCN(Triple)) {248 // __bf16 is always available as a load/store only type on AMDGCN.249 BFloat16Width = BFloat16Align = 16;250 BFloat16Format = &llvm::APFloat::BFloat();251 }252 253 HasFastHalfType = true;254 HasFloat16 = true;255 WavefrontSize = (GPUFeatures & llvm::AMDGPU::FEATURE_WAVE32) ? 32 : 64;256 257 // Set pointer width and alignment for the generic address space.258 PointerWidth = PointerAlign = getPointerWidthV(LangAS::Default);259 if (getMaxPointerWidth() == 64) {260 LongWidth = LongAlign = 64;261 SizeType = UnsignedLong;262 PtrDiffType = SignedLong;263 IntPtrType = SignedLong;264 }265 266 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;267 CUMode = !(GPUFeatures & llvm::AMDGPU::FEATURE_WGP);268 269 for (auto F : {"image-insts", "gws", "vmem-to-lds-load-insts"}) {270 if (GPUKind != llvm::AMDGPU::GK_NONE)271 ReadOnlyFeatures.insert(F);272 }273 HalfArgsAndReturns = true;274}275 276void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts,277 const TargetInfo *Aux) {278 TargetInfo::adjust(Diags, Opts, Aux);279 // ToDo: There are still a few places using default address space as private280 // address space in OpenCL, which needs to be cleaned up, then the references281 // to OpenCL can be removed from the following line.282 setAddressSpaceMap((Opts.OpenCL && !Opts.OpenCLGenericAddressSpace) ||283 !isAMDGCN(getTriple()));284 285 AtomicOpts = AtomicOptions(Opts);286}287 288llvm::SmallVector<Builtin::InfosShard>289AMDGPUTargetInfo::getTargetBuiltins() const {290 return {{&BuiltinStrings, BuiltinInfos}};291}292 293void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,294 MacroBuilder &Builder) const {295 Builder.defineMacro("__AMD__");296 Builder.defineMacro("__AMDGPU__");297 298 if (isAMDGCN(getTriple()))299 Builder.defineMacro("__AMDGCN__");300 else301 Builder.defineMacro("__R600__");302 303 // Legacy HIP host code relies on these default attributes to be defined.304 bool IsHIPHost = Opts.HIP && !Opts.CUDAIsDevice;305 if (GPUKind == llvm::AMDGPU::GK_NONE && !IsHIPHost)306 return;307 308 llvm::SmallString<16> CanonName =309 (isAMDGCN(getTriple()) ? getArchNameAMDGCN(GPUKind)310 : getArchNameR600(GPUKind));311 312 // Sanitize the name of generic targets.313 // e.g. gfx10-1-generic -> gfx10_1_generic314 if (GPUKind >= llvm::AMDGPU::GK_AMDGCN_GENERIC_FIRST &&315 GPUKind <= llvm::AMDGPU::GK_AMDGCN_GENERIC_LAST) {316 llvm::replace(CanonName, '-', '_');317 }318 319 Builder.defineMacro(Twine("__") + Twine(CanonName) + Twine("__"));320 // Emit macros for gfx family e.g. gfx906 -> __GFX9__, gfx1030 -> __GFX10___321 if (isAMDGCN(getTriple()) && !IsHIPHost) {322 assert(StringRef(CanonName).starts_with("gfx") &&323 "Invalid amdgcn canonical name");324 StringRef CanonFamilyName = getArchFamilyNameAMDGCN(GPUKind);325 Builder.defineMacro(Twine("__") + Twine(CanonFamilyName.upper()) +326 Twine("__"));327 Builder.defineMacro("__amdgcn_processor__",328 Twine("\"") + Twine(CanonName) + Twine("\""));329 Builder.defineMacro("__amdgcn_target_id__",330 Twine("\"") + Twine(*getTargetID()) + Twine("\""));331 for (auto F : getAllPossibleTargetIDFeatures(getTriple(), CanonName)) {332 auto Loc = OffloadArchFeatures.find(F);333 if (Loc != OffloadArchFeatures.end()) {334 std::string NewF = F.str();335 llvm::replace(NewF, '-', '_');336 Builder.defineMacro(Twine("__amdgcn_feature_") + Twine(NewF) +337 Twine("__"),338 Loc->second ? "1" : "0");339 }340 }341 }342 343 if (Opts.AtomicIgnoreDenormalMode)344 Builder.defineMacro("__AMDGCN_UNSAFE_FP_ATOMICS__");345 346 // TODO: __HAS_FMAF__, __HAS_LDEXPF__, __HAS_FP64__ are deprecated and will be347 // removed in the near future.348 if (hasFMAF())349 Builder.defineMacro("__HAS_FMAF__");350 if (hasFastFMAF())351 Builder.defineMacro("FP_FAST_FMAF");352 if (hasLDEXPF())353 Builder.defineMacro("__HAS_LDEXPF__");354 if (hasFP64())355 Builder.defineMacro("__HAS_FP64__");356 if (hasFastFMA())357 Builder.defineMacro("FP_FAST_FMA");358 359 Builder.defineMacro("__AMDGCN_CUMODE__", Twine(CUMode));360}361 362void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) {363 assert(HalfFormat == Aux->HalfFormat);364 assert(FloatFormat == Aux->FloatFormat);365 assert(DoubleFormat == Aux->DoubleFormat);366 367 // On x86_64 long double is 80-bit extended precision format, which is368 // not supported by AMDGPU. 128-bit floating point format is also not369 // supported by AMDGPU. Therefore keep its own format for these two types.370 auto SaveLongDoubleFormat = LongDoubleFormat;371 auto SaveFloat128Format = Float128Format;372 auto SaveLongDoubleWidth = LongDoubleWidth;373 auto SaveLongDoubleAlign = LongDoubleAlign;374 copyAuxTarget(Aux);375 LongDoubleFormat = SaveLongDoubleFormat;376 Float128Format = SaveFloat128Format;377 LongDoubleWidth = SaveLongDoubleWidth;378 LongDoubleAlign = SaveLongDoubleAlign;379 // For certain builtin types support on the host target, claim they are380 // support to pass the compilation of the host code during the device-side381 // compilation.382 // FIXME: As the side effect, we also accept `__float128` uses in the device383 // code. To rejct these builtin types supported in the host target but not in384 // the device target, one approach would support `device_builtin` attribute385 // so that we could tell the device builtin types from the host ones. The386 // also solves the different representations of the same builtin type, such387 // as `size_t` in the MSVC environment.388 if (Aux->hasFloat128Type()) {389 HasFloat128 = true;390 Float128Format = DoubleFormat;391 }392}393