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-exception
6 //
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/CodeGenOptions.h"
16 #include "clang/Basic/LangOptions.h"
17 #include "clang/Basic/MacroBuilder.h"
18 #include "clang/Basic/TargetBuiltins.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/Frontend/OpenMP/OMPGridValues.h"
21 #include "llvm/IR/DataLayout.h"
22 
23 using namespace clang;
24 using namespace clang::targets;
25 
26 namespace clang {
27 namespace targets {
28 
29 // If you edit the description strings, make sure you update
30 // getPointerWidthV().
31 
32 static const char *const DataLayoutStringR600 =
33     "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
34     "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1";
35 
36 static const char *const DataLayoutStringAMDGCN =
37     "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
38     "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
39     "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1"
40     "-ni:7";
41 
42 const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
43     Generic,  // Default
44     Global,   // opencl_global
45     Local,    // opencl_local
46     Constant, // opencl_constant
47     Private,  // opencl_private
48     Generic,  // opencl_generic
49     Global,   // opencl_global_device
50     Global,   // opencl_global_host
51     Global,   // cuda_device
52     Constant, // cuda_constant
53     Local,    // cuda_shared
54     Generic,  // ptr32_sptr
55     Generic,  // ptr32_uptr
56     Generic   // ptr64
57 };
58 
59 const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
60     Private,  // Default
61     Global,   // opencl_global
62     Local,    // opencl_local
63     Constant, // opencl_constant
64     Private,  // opencl_private
65     Generic,  // opencl_generic
66     Global,   // opencl_global_device
67     Global,   // opencl_global_host
68     Global,   // cuda_device
69     Constant, // cuda_constant
70     Local,    // cuda_shared
71     Generic,  // ptr32_sptr
72     Generic,  // ptr32_uptr
73     Generic   // ptr64
74 
75 };
76 } // namespace targets
77 } // namespace clang
78 
79 const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = {
80 #define BUILTIN(ID, TYPE, ATTRS)                                               \
81   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
82 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
83   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
84 #include "clang/Basic/BuiltinsAMDGPU.def"
85 };
86 
87 const char *const AMDGPUTargetInfo::GCCRegNames[] = {
88   "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",
89   "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17",
90   "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26",
91   "v27", "v28", "v29", "v30", "v31", "v32", "v33", "v34", "v35",
92   "v36", "v37", "v38", "v39", "v40", "v41", "v42", "v43", "v44",
93   "v45", "v46", "v47", "v48", "v49", "v50", "v51", "v52", "v53",
94   "v54", "v55", "v56", "v57", "v58", "v59", "v60", "v61", "v62",
95   "v63", "v64", "v65", "v66", "v67", "v68", "v69", "v70", "v71",
96   "v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79", "v80",
97   "v81", "v82", "v83", "v84", "v85", "v86", "v87", "v88", "v89",
98   "v90", "v91", "v92", "v93", "v94", "v95", "v96", "v97", "v98",
99   "v99", "v100", "v101", "v102", "v103", "v104", "v105", "v106", "v107",
100   "v108", "v109", "v110", "v111", "v112", "v113", "v114", "v115", "v116",
101   "v117", "v118", "v119", "v120", "v121", "v122", "v123", "v124", "v125",
102   "v126", "v127", "v128", "v129", "v130", "v131", "v132", "v133", "v134",
103   "v135", "v136", "v137", "v138", "v139", "v140", "v141", "v142", "v143",
104   "v144", "v145", "v146", "v147", "v148", "v149", "v150", "v151", "v152",
105   "v153", "v154", "v155", "v156", "v157", "v158", "v159", "v160", "v161",
106   "v162", "v163", "v164", "v165", "v166", "v167", "v168", "v169", "v170",
107   "v171", "v172", "v173", "v174", "v175", "v176", "v177", "v178", "v179",
108   "v180", "v181", "v182", "v183", "v184", "v185", "v186", "v187", "v188",
109   "v189", "v190", "v191", "v192", "v193", "v194", "v195", "v196", "v197",
110   "v198", "v199", "v200", "v201", "v202", "v203", "v204", "v205", "v206",
111   "v207", "v208", "v209", "v210", "v211", "v212", "v213", "v214", "v215",
112   "v216", "v217", "v218", "v219", "v220", "v221", "v222", "v223", "v224",
113   "v225", "v226", "v227", "v228", "v229", "v230", "v231", "v232", "v233",
114   "v234", "v235", "v236", "v237", "v238", "v239", "v240", "v241", "v242",
115   "v243", "v244", "v245", "v246", "v247", "v248", "v249", "v250", "v251",
116   "v252", "v253", "v254", "v255", "s0", "s1", "s2", "s3", "s4",
117   "s5", "s6", "s7", "s8", "s9", "s10", "s11", "s12", "s13",
118   "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
119   "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
120   "s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39", "s40",
121   "s41", "s42", "s43", "s44", "s45", "s46", "s47", "s48", "s49",
122   "s50", "s51", "s52", "s53", "s54", "s55", "s56", "s57", "s58",
123   "s59", "s60", "s61", "s62", "s63", "s64", "s65", "s66", "s67",
124   "s68", "s69", "s70", "s71", "s72", "s73", "s74", "s75", "s76",
125   "s77", "s78", "s79", "s80", "s81", "s82", "s83", "s84", "s85",
126   "s86", "s87", "s88", "s89", "s90", "s91", "s92", "s93", "s94",
127   "s95", "s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103",
128   "s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112",
129   "s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121",
130   "s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc",
131   "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi",
132   "flat_scratch_lo", "flat_scratch_hi",
133   "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8",
134   "a9", "a10", "a11", "a12", "a13", "a14", "a15", "a16", "a17",
135   "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26",
136   "a27", "a28", "a29", "a30", "a31", "a32", "a33", "a34", "a35",
137   "a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44",
138   "a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53",
139   "a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62",
140   "a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71",
141   "a72", "a73", "a74", "a75", "a76", "a77", "a78", "a79", "a80",
142   "a81", "a82", "a83", "a84", "a85", "a86", "a87", "a88", "a89",
143   "a90", "a91", "a92", "a93", "a94", "a95", "a96", "a97", "a98",
144   "a99", "a100", "a101", "a102", "a103", "a104", "a105", "a106", "a107",
145   "a108", "a109", "a110", "a111", "a112", "a113", "a114", "a115", "a116",
146   "a117", "a118", "a119", "a120", "a121", "a122", "a123", "a124", "a125",
147   "a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134",
148   "a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143",
149   "a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152",
150   "a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161",
151   "a162", "a163", "a164", "a165", "a166", "a167", "a168", "a169", "a170",
152   "a171", "a172", "a173", "a174", "a175", "a176", "a177", "a178", "a179",
153   "a180", "a181", "a182", "a183", "a184", "a185", "a186", "a187", "a188",
154   "a189", "a190", "a191", "a192", "a193", "a194", "a195", "a196", "a197",
155   "a198", "a199", "a200", "a201", "a202", "a203", "a204", "a205", "a206",
156   "a207", "a208", "a209", "a210", "a211", "a212", "a213", "a214", "a215",
157   "a216", "a217", "a218", "a219", "a220", "a221", "a222", "a223", "a224",
158   "a225", "a226", "a227", "a228", "a229", "a230", "a231", "a232", "a233",
159   "a234", "a235", "a236", "a237", "a238", "a239", "a240", "a241", "a242",
160   "a243", "a244", "a245", "a246", "a247", "a248", "a249", "a250", "a251",
161   "a252", "a253", "a254", "a255"
162 };
163 
164 ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const {
165   return llvm::makeArrayRef(GCCRegNames);
166 }
167 
168 bool AMDGPUTargetInfo::initFeatureMap(
169     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
170     const std::vector<std::string> &FeatureVec) const {
171 
172   using namespace llvm::AMDGPU;
173 
174   // XXX - What does the member GPU mean if device name string passed here?
175   if (isAMDGCN(getTriple())) {
176     switch (llvm::AMDGPU::parseArchAMDGCN(CPU)) {
177     case GK_GFX1033:
178     case GK_GFX1032:
179     case GK_GFX1031:
180     case GK_GFX1030:
181       Features["ci-insts"] = true;
182       Features["dot1-insts"] = true;
183       Features["dot2-insts"] = true;
184       Features["dot5-insts"] = true;
185       Features["dot6-insts"] = true;
186       Features["dl-insts"] = true;
187       Features["flat-address-space"] = true;
188       Features["16-bit-insts"] = true;
189       Features["dpp"] = true;
190       Features["gfx8-insts"] = true;
191       Features["gfx9-insts"] = true;
192       Features["gfx10-insts"] = true;
193       Features["gfx10-3-insts"] = true;
194       Features["s-memrealtime"] = true;
195       break;
196     case GK_GFX1012:
197     case GK_GFX1011:
198       Features["dot1-insts"] = true;
199       Features["dot2-insts"] = true;
200       Features["dot5-insts"] = true;
201       Features["dot6-insts"] = true;
202       LLVM_FALLTHROUGH;
203     case GK_GFX1010:
204       Features["dl-insts"] = true;
205       Features["ci-insts"] = true;
206       Features["flat-address-space"] = true;
207       Features["16-bit-insts"] = true;
208       Features["dpp"] = true;
209       Features["gfx8-insts"] = true;
210       Features["gfx9-insts"] = true;
211       Features["gfx10-insts"] = true;
212       Features["s-memrealtime"] = true;
213       break;
214     case GK_GFX908:
215       Features["dot3-insts"] = true;
216       Features["dot4-insts"] = true;
217       Features["dot5-insts"] = true;
218       Features["dot6-insts"] = true;
219       Features["mai-insts"] = true;
220       LLVM_FALLTHROUGH;
221     case GK_GFX906:
222       Features["dl-insts"] = true;
223       Features["dot1-insts"] = true;
224       Features["dot2-insts"] = true;
225       LLVM_FALLTHROUGH;
226     case GK_GFX90C:
227     case GK_GFX909:
228     case GK_GFX904:
229     case GK_GFX902:
230     case GK_GFX900:
231       Features["gfx9-insts"] = true;
232       LLVM_FALLTHROUGH;
233     case GK_GFX810:
234     case GK_GFX805:
235     case GK_GFX803:
236     case GK_GFX802:
237     case GK_GFX801:
238       Features["gfx8-insts"] = true;
239       Features["16-bit-insts"] = true;
240       Features["dpp"] = true;
241       Features["s-memrealtime"] = true;
242       LLVM_FALLTHROUGH;
243     case GK_GFX705:
244     case GK_GFX704:
245     case GK_GFX703:
246     case GK_GFX702:
247     case GK_GFX701:
248     case GK_GFX700:
249       Features["ci-insts"] = true;
250       Features["flat-address-space"] = true;
251       LLVM_FALLTHROUGH;
252     case GK_GFX602:
253     case GK_GFX601:
254     case GK_GFX600:
255       break;
256     case GK_NONE:
257       break;
258     default:
259       llvm_unreachable("Unhandled GPU!");
260     }
261   } else {
262     if (CPU.empty())
263       CPU = "r600";
264 
265     switch (llvm::AMDGPU::parseArchR600(CPU)) {
266     case GK_CAYMAN:
267     case GK_CYPRESS:
268     case GK_RV770:
269     case GK_RV670:
270       // TODO: Add fp64 when implemented.
271       break;
272     case GK_TURKS:
273     case GK_CAICOS:
274     case GK_BARTS:
275     case GK_SUMO:
276     case GK_REDWOOD:
277     case GK_JUNIPER:
278     case GK_CEDAR:
279     case GK_RV730:
280     case GK_RV710:
281     case GK_RS880:
282     case GK_R630:
283     case GK_R600:
284       break;
285     default:
286       llvm_unreachable("Unhandled GPU!");
287     }
288   }
289 
290   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec);
291 }
292 
293 void AMDGPUTargetInfo::fillValidCPUList(
294     SmallVectorImpl<StringRef> &Values) const {
295   if (isAMDGCN(getTriple()))
296     llvm::AMDGPU::fillValidArchListAMDGCN(Values);
297   else
298     llvm::AMDGPU::fillValidArchListR600(Values);
299 }
300 
301 void AMDGPUTargetInfo::setAddressSpaceMap(bool DefaultIsPrivate) {
302   AddrSpaceMap = DefaultIsPrivate ? &AMDGPUDefIsPrivMap : &AMDGPUDefIsGenMap;
303 }
304 
305 AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
306                                    const TargetOptions &Opts)
307     : TargetInfo(Triple),
308       GPUKind(isAMDGCN(Triple) ?
309               llvm::AMDGPU::parseArchAMDGCN(Opts.CPU) :
310               llvm::AMDGPU::parseArchR600(Opts.CPU)),
311       GPUFeatures(isAMDGCN(Triple) ?
312                   llvm::AMDGPU::getArchAttrAMDGCN(GPUKind) :
313                   llvm::AMDGPU::getArchAttrR600(GPUKind)) {
314   resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN
315                                         : DataLayoutStringR600);
316   assert(DataLayout->getAllocaAddrSpace() == Private);
317   GridValues = llvm::omp::AMDGPUGpuGridValues;
318 
319   setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D ||
320                      !isAMDGCN(Triple));
321   UseAddrSpaceMapMangling = true;
322 
323   HasLegalHalfType = true;
324   HasFloat16 = true;
325   WavefrontSize = GPUFeatures & llvm::AMDGPU::FEATURE_WAVE32 ? 32 : 64;
326   AllowAMDGPUUnsafeFPAtomics = Opts.AllowAMDGPUUnsafeFPAtomics;
327 
328   // Set pointer width and alignment for target address space 0.
329   PointerWidth = PointerAlign = DataLayout->getPointerSizeInBits();
330   if (getMaxPointerWidth() == 64) {
331     LongWidth = LongAlign = 64;
332     SizeType = UnsignedLong;
333     PtrDiffType = SignedLong;
334     IntPtrType = SignedLong;
335   }
336 
337   MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
338 }
339 
340 void AMDGPUTargetInfo::adjust(LangOptions &Opts) {
341   TargetInfo::adjust(Opts);
342   // ToDo: There are still a few places using default address space as private
343   // address space in OpenCL, which needs to be cleaned up, then Opts.OpenCL
344   // can be removed from the following line.
345   setAddressSpaceMap(/*DefaultIsPrivate=*/Opts.OpenCL ||
346                      !isAMDGCN(getTriple()));
347 }
348 
349 ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const {
350   return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin -
351                                              Builtin::FirstTSBuiltin);
352 }
353 
354 void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
355                                         MacroBuilder &Builder) const {
356   Builder.defineMacro("__AMD__");
357   Builder.defineMacro("__AMDGPU__");
358 
359   if (isAMDGCN(getTriple()))
360     Builder.defineMacro("__AMDGCN__");
361   else
362     Builder.defineMacro("__R600__");
363 
364   if (GPUKind != llvm::AMDGPU::GK_NONE) {
365     StringRef CanonName = isAMDGCN(getTriple()) ?
366       getArchNameAMDGCN(GPUKind) : getArchNameR600(GPUKind);
367     Builder.defineMacro(Twine("__") + Twine(CanonName) + Twine("__"));
368     if (isAMDGCN(getTriple())) {
369       Builder.defineMacro("__amdgcn_processor__",
370                           Twine("\"") + Twine(CanonName) + Twine("\""));
371       Builder.defineMacro("__amdgcn_target_id__",
372                           Twine("\"") + Twine(getTargetID().getValue()) +
373                               Twine("\""));
374       for (auto F : getAllPossibleTargetIDFeatures(getTriple(), CanonName)) {
375         auto Loc = OffloadArchFeatures.find(F);
376         if (Loc != OffloadArchFeatures.end()) {
377           std::string NewF = F.str();
378           std::replace(NewF.begin(), NewF.end(), '-', '_');
379           Builder.defineMacro(Twine("__amdgcn_feature_") + Twine(NewF) +
380                                   Twine("__"),
381                               Loc->second ? "1" : "0");
382         }
383       }
384     }
385   }
386 
387   // TODO: __HAS_FMAF__, __HAS_LDEXPF__, __HAS_FP64__ are deprecated and will be
388   // removed in the near future.
389   if (hasFMAF())
390     Builder.defineMacro("__HAS_FMAF__");
391   if (hasFastFMAF())
392     Builder.defineMacro("FP_FAST_FMAF");
393   if (hasLDEXPF())
394     Builder.defineMacro("__HAS_LDEXPF__");
395   if (hasFP64())
396     Builder.defineMacro("__HAS_FP64__");
397   if (hasFastFMA())
398     Builder.defineMacro("FP_FAST_FMA");
399 
400   Builder.defineMacro("__AMDGCN_WAVEFRONT_SIZE", Twine(WavefrontSize));
401 }
402 
403 void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) {
404   assert(HalfFormat == Aux->HalfFormat);
405   assert(FloatFormat == Aux->FloatFormat);
406   assert(DoubleFormat == Aux->DoubleFormat);
407 
408   // On x86_64 long double is 80-bit extended precision format, which is
409   // not supported by AMDGPU. 128-bit floating point format is also not
410   // supported by AMDGPU. Therefore keep its own format for these two types.
411   auto SaveLongDoubleFormat = LongDoubleFormat;
412   auto SaveFloat128Format = Float128Format;
413   copyAuxTarget(Aux);
414   LongDoubleFormat = SaveLongDoubleFormat;
415   Float128Format = SaveFloat128Format;
416   // For certain builtin types support on the host target, claim they are
417   // support to pass the compilation of the host code during the device-side
418   // compilation.
419   // FIXME: As the side effect, we also accept `__float128` uses in the device
420   // code. To rejct these builtin types supported in the host target but not in
421   // the device target, one approach would support `device_builtin` attribute
422   // so that we could tell the device builtin types from the host ones. The
423   // also solves the different representations of the same builtin type, such
424   // as `size_t` in the MSVC environment.
425   if (Aux->hasFloat128Type()) {
426     HasFloat128 = true;
427     Float128Format = DoubleFormat;
428   }
429 }
430