| 1 | //===-- AMDGPUTargetParser - Parser for AMDGPU features ---------*- C++ -*-===// |
| 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 a target parser to recognise AMDGPU hardware features. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #include "llvm/TargetParser/AMDGPUTargetParser.h" |
| 14 | #include "llvm/ADT/SmallVector.h" |
| 15 | #include "llvm/ADT/StringSwitch.h" |
| 16 | #include "llvm/ADT/Twine.h" |
| 17 | #include "llvm/Support/ErrorHandling.h" |
| 18 | #include "llvm/Support/raw_ostream.h" |
| 19 | #include "llvm/TargetParser/Triple.h" |
| 20 | |
| 21 | using namespace llvm; |
| 22 | using namespace AMDGPU; |
| 23 | |
| 24 | StringRef llvm::AMDGPU::getArchFamilyNameAMDGCN(GPUKind AK) { |
| 25 | StringRef ArchName = getArchNameAMDGCN(AK); |
| 26 | assert((AK >= GK_AMDGCN_GENERIC_FIRST && AK <= GK_AMDGCN_GENERIC_LAST) == |
| 27 | ArchName.ends_with("-generic" ) && |
| 28 | "Generic AMDGCN arch not classified correctly!" ); |
| 29 | if (AK >= GK_AMDGCN_GENERIC_FIRST && AK <= GK_AMDGCN_GENERIC_LAST) { |
| 30 | // Return the part before the first '-', e.g. "gfx9-4-generic" -> "gfx9". |
| 31 | return ArchName.take_front(N: ArchName.find(C: '-')); |
| 32 | } |
| 33 | return ArchName.empty() ? "" : ArchName.drop_back(N: 2); |
| 34 | } |
| 35 | |
| 36 | Triple::SubArchType llvm::AMDGPU::getSubArch(GPUKind AK) { |
| 37 | switch (AK) { |
| 38 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) \ |
| 39 | case ENUM: \ |
| 40 | return SUBARCH; |
| 41 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 42 | default: |
| 43 | return Triple::SubArchType::NoSubArch; |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | AMDGPU::GPUKind |
| 48 | llvm::AMDGPU::getGPUKindFromSubArch(Triple::SubArchType SubArch) { |
| 49 | switch (SubArch) { |
| 50 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) \ |
| 51 | case SUBARCH: \ |
| 52 | return ENUM; |
| 53 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 54 | default: |
| 55 | return GK_NONE; |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | static const Triple::SubArchType |
| 60 | AMDGPUMajorFamilies[Triple::LastAMDGPUSubArch - Triple::FirstAMDGPUSubArch + |
| 61 | 1] = { |
| 62 | Triple::AMDGPUSubArch6, Triple::AMDGPUSubArch6, |
| 63 | Triple::AMDGPUSubArch6, Triple::AMDGPUSubArch6, |
| 64 | |
| 65 | Triple::AMDGPUSubArch7, Triple::AMDGPUSubArch7, |
| 66 | Triple::AMDGPUSubArch7, Triple::AMDGPUSubArch7, |
| 67 | Triple::AMDGPUSubArch7, Triple::AMDGPUSubArch7, |
| 68 | Triple::AMDGPUSubArch7, |
| 69 | |
| 70 | Triple::AMDGPUSubArch8, Triple::AMDGPUSubArch8, |
| 71 | Triple::AMDGPUSubArch8, Triple::AMDGPUSubArch8, |
| 72 | Triple::AMDGPUSubArch8, |
| 73 | |
| 74 | Triple::AMDGPUSubArch810, |
| 75 | |
| 76 | Triple::AMDGPUSubArch9, Triple::AMDGPUSubArch9, |
| 77 | Triple::AMDGPUSubArch9, Triple::AMDGPUSubArch9, |
| 78 | Triple::AMDGPUSubArch9, Triple::AMDGPUSubArch9, |
| 79 | Triple::AMDGPUSubArch9, |
| 80 | |
| 81 | Triple::AMDGPUSubArch908, Triple::AMDGPUSubArch90A, |
| 82 | |
| 83 | Triple::AMDGPUSubArch9_4, Triple::AMDGPUSubArch9_4, |
| 84 | Triple::AMDGPUSubArch9_4, |
| 85 | |
| 86 | Triple::AMDGPUSubArch10_1, Triple::AMDGPUSubArch10_1, |
| 87 | Triple::AMDGPUSubArch10_1, Triple::AMDGPUSubArch10_1, |
| 88 | Triple::AMDGPUSubArch10_1, |
| 89 | |
| 90 | Triple::AMDGPUSubArch10_3, Triple::AMDGPUSubArch10_3, |
| 91 | Triple::AMDGPUSubArch10_3, Triple::AMDGPUSubArch10_3, |
| 92 | Triple::AMDGPUSubArch10_3, Triple::AMDGPUSubArch10_3, |
| 93 | Triple::AMDGPUSubArch10_3, Triple::AMDGPUSubArch10_3, |
| 94 | |
| 95 | Triple::AMDGPUSubArch11, Triple::AMDGPUSubArch11, |
| 96 | Triple::AMDGPUSubArch11, Triple::AMDGPUSubArch11, |
| 97 | Triple::AMDGPUSubArch11, Triple::AMDGPUSubArch11, |
| 98 | Triple::AMDGPUSubArch11, Triple::AMDGPUSubArch11, |
| 99 | Triple::AMDGPUSubArch11, Triple::AMDGPUSubArch11, |
| 100 | |
| 101 | Triple::AMDGPUSubArch11_7, Triple::AMDGPUSubArch11_7, |
| 102 | Triple::AMDGPUSubArch11_7, Triple::AMDGPUSubArch11_7, |
| 103 | |
| 104 | Triple::AMDGPUSubArch12, Triple::AMDGPUSubArch12, |
| 105 | Triple::AMDGPUSubArch12, |
| 106 | |
| 107 | Triple::AMDGPUSubArch12_5, Triple::AMDGPUSubArch12_5, |
| 108 | Triple::AMDGPUSubArch12_5, |
| 109 | |
| 110 | Triple::AMDGPUSubArch13, Triple::AMDGPUSubArch13}; |
| 111 | |
| 112 | Triple::SubArchType AMDGPU::getMajorSubArch(Triple::SubArchType X) { |
| 113 | if (X < Triple::FirstAMDGPUSubArch || X > Triple::LastAMDGPUSubArch) |
| 114 | return Triple::NoSubArch; |
| 115 | return AMDGPUMajorFamilies[X - Triple::FirstAMDGPUSubArch]; |
| 116 | } |
| 117 | |
| 118 | bool AMDGPU::isSubArchCompatible(Triple::SubArchType A, Triple::SubArchType B) { |
| 119 | if (A == B || A == Triple::NoSubArch || B == Triple::NoSubArch) |
| 120 | return true; |
| 121 | |
| 122 | Triple::SubArchType MajorA = AMDGPU::getMajorSubArch(X: A); |
| 123 | Triple::SubArchType MajorB = AMDGPU::getMajorSubArch(X: B); |
| 124 | |
| 125 | // One side is the major-family subarch covering the other's family. |
| 126 | if (A == MajorA) |
| 127 | return MajorA == MajorB; |
| 128 | if (B == MajorB) |
| 129 | return MajorA == MajorB; |
| 130 | |
| 131 | return false; |
| 132 | } |
| 133 | |
| 134 | bool AMDGPU::isCPUValidForSubArch(Triple::SubArchType SubArch, GPUKind AK) { |
| 135 | // An unrecognized GPU is never valid. |
| 136 | if (AK == GK_NONE) |
| 137 | return false; |
| 138 | // A legacy triple without a subarch accepts any known GPU. |
| 139 | if (SubArch == Triple::NoSubArch) |
| 140 | return true; |
| 141 | return isSubArchCompatible(A: getSubArch(AK), B: SubArch); |
| 142 | } |
| 143 | |
| 144 | bool AMDGPU::isCPUValidForSubArch(Triple::SubArchType SubArch, StringRef CPU) { |
| 145 | return isCPUValidForSubArch(SubArch, AK: parseArchAMDGCN(CPU)); |
| 146 | } |
| 147 | |
| 148 | bool AMDGPU::isSubArchCompatible(const Triple &A, const Triple &B) { |
| 149 | // Tolerate subarch mismatch if one entry is none. This is a hack for bitcode |
| 150 | // libraries. |
| 151 | // There's a missing enum entry for an unknown subarch. Make sure the |
| 152 | // subarch is really empty. |
| 153 | if (A.getSubArch() == Triple::NoSubArch) |
| 154 | return A.getArchName().size() == 6; |
| 155 | |
| 156 | if (B.getSubArch() == Triple::NoSubArch) |
| 157 | return B.getArchName().size() == 6; |
| 158 | |
| 159 | return isSubArchCompatible(A: A.getSubArch(), B: B.getSubArch()); |
| 160 | } |
| 161 | |
| 162 | std::string AMDGPU::mergeSubArch(const Triple &A, const Triple &B) { |
| 163 | if (A.getSubArch() == Triple::NoSubArch) |
| 164 | return B.str(); |
| 165 | if (B.getSubArch() == Triple::NoSubArch) |
| 166 | return A.str(); |
| 167 | |
| 168 | Triple::SubArchType MajorA = AMDGPU::getMajorSubArch(X: A.getSubArch()); |
| 169 | Triple::SubArchType MajorB = AMDGPU::getMajorSubArch(X: B.getSubArch()); |
| 170 | |
| 171 | // With a compatible major arch, return the specific subarch. |
| 172 | if (A.getSubArch() == MajorA) { |
| 173 | if (MajorA == MajorB) |
| 174 | return B.str(); |
| 175 | } |
| 176 | |
| 177 | if (B.getSubArch() == MajorB) { |
| 178 | if (MajorA == MajorB) |
| 179 | return A.str(); |
| 180 | } |
| 181 | |
| 182 | // Invalid case. |
| 183 | return B.str(); |
| 184 | } |
| 185 | |
| 186 | StringRef llvm::AMDGPU::getArchNameAMDGCN(GPUKind AK) { |
| 187 | switch (AK) { |
| 188 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) \ |
| 189 | case ENUM: \ |
| 190 | return NAME; |
| 191 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 192 | default: |
| 193 | return "" ; |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | // Canonical GPU name for each AMDGPU subarch, indexed by SubArch - |
| 198 | // Triple::FirstAMDGPUSubArch. |
| 199 | static const StringLiteral AMDGPUSubArchNames[Triple::LastAMDGPUSubArch - |
| 200 | Triple::FirstAMDGPUSubArch + 1] = |
| 201 | {"gfx600" , // AMDGPUSubArch6 (no generic target) |
| 202 | "gfx600" , "gfx601" , "gfx602" , |
| 203 | |
| 204 | "gfx700" , // AMDGPUSubArch7 (no generic target) |
| 205 | "gfx700" , "gfx701" , "gfx702" , "gfx703" , "gfx704" , |
| 206 | "gfx705" , |
| 207 | |
| 208 | "gfx801" , // AMDGPUSubArch8 (no generic target) |
| 209 | "gfx801" , "gfx802" , "gfx803" , "gfx805" , |
| 210 | |
| 211 | "gfx810" , |
| 212 | |
| 213 | "gfx9-generic" , "gfx900" , "gfx902" , "gfx904" , "gfx906" , |
| 214 | "gfx909" , "gfx90c" , |
| 215 | |
| 216 | "gfx908" , "gfx90a" , |
| 217 | |
| 218 | "gfx9-4-generic" , "gfx942" , "gfx950" , |
| 219 | |
| 220 | "gfx10-1-generic" , "gfx1010" , "gfx1011" , "gfx1012" , "gfx1013" , |
| 221 | |
| 222 | "gfx10-3-generic" , "gfx1030" , "gfx1031" , "gfx1032" , "gfx1033" , |
| 223 | "gfx1034" , "gfx1035" , "gfx1036" , |
| 224 | |
| 225 | "gfx11-generic" , "gfx1100" , "gfx1101" , "gfx1102" , "gfx1103" , |
| 226 | "gfx1150" , "gfx1151" , "gfx1152" , "gfx1153" , "gfx1154" , |
| 227 | |
| 228 | "gfx11-7-generic" , "gfx1170" , "gfx1171" , "gfx1172" , |
| 229 | |
| 230 | "gfx12-generic" , "gfx1200" , "gfx1201" , "gfx12-5-generic" , "gfx1250" , |
| 231 | "gfx1251" , |
| 232 | |
| 233 | "gfx13-generic" , "gfx1310" }; |
| 234 | |
| 235 | StringRef llvm::AMDGPU::getArchNameFromSubArch(Triple::SubArchType SubArch) { |
| 236 | if (SubArch < Triple::FirstAMDGPUSubArch || |
| 237 | SubArch > Triple::LastAMDGPUSubArch) |
| 238 | return "" ; |
| 239 | return AMDGPUSubArchNames[SubArch - Triple::FirstAMDGPUSubArch]; |
| 240 | } |
| 241 | |
| 242 | StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) { |
| 243 | switch (AK) { |
| 244 | #define R600_GPU(NAME, ENUM, FEATURES) \ |
| 245 | case ENUM: \ |
| 246 | return NAME; |
| 247 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 248 | default: |
| 249 | return "" ; |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) { |
| 254 | return StringSwitch<AMDGPU::GPUKind>(CPU) |
| 255 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) .Case(NAME, ENUM) |
| 256 | #define AMDGCN_GPU_ALIAS(NAME, ENUM) .Case(NAME, ENUM) |
| 257 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 258 | .Case(S: "generic" , Value: AMDGPU::GPUKind::GK_GFX600) |
| 259 | .Case(S: "generic-hsa" , Value: AMDGPU::GPUKind::GK_GFX700) |
| 260 | .Default(Value: AMDGPU::GPUKind::GK_NONE); |
| 261 | } |
| 262 | |
| 263 | AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef CPU) { |
| 264 | return StringSwitch<AMDGPU::GPUKind>(CPU) |
| 265 | #define R600_GPU(NAME, ENUM, FEATURES) .Case(NAME, ENUM) |
| 266 | #define R600_GPU_ALIAS(NAME, ENUM) .Case(NAME, ENUM) |
| 267 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 268 | .Default(Value: AMDGPU::GPUKind::GK_NONE); |
| 269 | } |
| 270 | |
| 271 | unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK) { |
| 272 | switch (AK) { |
| 273 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) \ |
| 274 | case ENUM: \ |
| 275 | return FEATURES; |
| 276 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 277 | default: |
| 278 | return FEATURE_NONE; |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | unsigned AMDGPU::getArchAttrAMDGCN(Triple::SubArchType SubArch) { |
| 283 | switch (SubArch) { |
| 284 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) \ |
| 285 | case SUBARCH: \ |
| 286 | return FEATURES; |
| 287 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 288 | default: |
| 289 | return FEATURE_NONE; |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | unsigned AMDGPU::getArchAttrR600(GPUKind AK) { |
| 294 | switch (AK) { |
| 295 | #define R600_GPU(NAME, ENUM, FEATURES) \ |
| 296 | case ENUM: \ |
| 297 | return FEATURES; |
| 298 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 299 | default: |
| 300 | return FEATURE_NONE; |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | void AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl<StringRef> &Values, |
| 305 | Triple::SubArchType SubArch) { |
| 306 | // XXX: Should this only report unique canonical names? |
| 307 | // An alias shares its GPU's GPUKind, so it is filtered alongside it. |
| 308 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) \ |
| 309 | if (isCPUValidForSubArch(SubArch, ENUM)) \ |
| 310 | Values.push_back(NAME); |
| 311 | #define AMDGCN_GPU_ALIAS(NAME, ENUM) \ |
| 312 | if (isCPUValidForSubArch(SubArch, ENUM)) \ |
| 313 | Values.push_back(NAME); |
| 314 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 315 | } |
| 316 | |
| 317 | void AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) { |
| 318 | Values.append(IL: { |
| 319 | #define R600_GPU(NAME, ENUM, FEATURES) NAME, |
| 320 | #define R600_GPU_ALIAS(NAME, ENUM) NAME, |
| 321 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 322 | }); |
| 323 | } |
| 324 | |
| 325 | AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) { |
| 326 | AMDGPU::GPUKind AK = parseArchAMDGCN(CPU: GPU); |
| 327 | if (AK == AMDGPU::GPUKind::GK_NONE) { |
| 328 | if (GPU == "generic-hsa" ) |
| 329 | return {.Major: 7, .Minor: 0, .Stepping: 0}; |
| 330 | if (GPU == "generic" ) |
| 331 | return {.Major: 6, .Minor: 0, .Stepping: 0}; |
| 332 | return {.Major: 0, .Minor: 0, .Stepping: 0}; |
| 333 | } |
| 334 | |
| 335 | switch (AK) { |
| 336 | #define MAKE_ISAVERSION(A, B, C) {A, B, C} |
| 337 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) \ |
| 338 | case ENUM: \ |
| 339 | return MAKE_ISAVERSION ISAVERSION; |
| 340 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 341 | #undef MAKE_ISAVERSION |
| 342 | default: |
| 343 | return {.Major: 0, .Minor: 0, .Stepping: 0}; |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | AMDGPU::IsaVersion AMDGPU::getIsaVersion(Triple::SubArchType SubArch) { |
| 348 | switch (SubArch) { |
| 349 | #define MAKE_ISAVERSION(A, B, C) {A, B, C} |
| 350 | #define AMDGCN_GPU(NAME, ENUM, SUBARCH, ISAVERSION, FEATURES) \ |
| 351 | case SUBARCH: \ |
| 352 | return MAKE_ISAVERSION ISAVERSION; |
| 353 | #include "llvm/TargetParser/AMDGPUTargetParser.def" |
| 354 | #undef MAKE_ISAVERSION |
| 355 | default: |
| 356 | return {.Major: 0, .Minor: 0, .Stepping: 0}; |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | StringRef AMDGPU::getCanonicalArchName(const Triple &T, StringRef Arch) { |
| 361 | assert(T.isAMDGPU()); |
| 362 | auto ProcKind = T.isAMDGCN() ? parseArchAMDGCN(CPU: Arch) : parseArchR600(CPU: Arch); |
| 363 | if (ProcKind == GK_NONE) |
| 364 | return StringRef(); |
| 365 | |
| 366 | return T.isAMDGCN() ? getArchNameAMDGCN(AK: ProcKind) : getArchNameR600(AK: ProcKind); |
| 367 | } |
| 368 | |
| 369 | static std::pair<FeatureError, StringRef> |
| 370 | insertWaveSizeFeature(StringRef GPU, const Triple &T, |
| 371 | const StringMap<bool> &DefaultFeatures, |
| 372 | StringMap<bool> &Features) { |
| 373 | const bool IsNullGPU = GPU.empty(); |
| 374 | const bool TargetHasWave32 = DefaultFeatures.count(Key: "wavefrontsize32" ); |
| 375 | const bool TargetHasWave64 = DefaultFeatures.count(Key: "wavefrontsize64" ); |
| 376 | |
| 377 | auto Wave32Itr = Features.find(Key: "wavefrontsize32" ); |
| 378 | auto Wave64Itr = Features.find(Key: "wavefrontsize64" ); |
| 379 | const bool EnableWave32 = |
| 380 | Wave32Itr != Features.end() && Wave32Itr->getValue(); |
| 381 | const bool EnableWave64 = |
| 382 | Wave64Itr != Features.end() && Wave64Itr->getValue(); |
| 383 | const bool DisableWave32 = |
| 384 | Wave32Itr != Features.end() && !Wave32Itr->getValue(); |
| 385 | const bool DisableWave64 = |
| 386 | Wave64Itr != Features.end() && !Wave64Itr->getValue(); |
| 387 | |
| 388 | if (EnableWave32 && EnableWave64) |
| 389 | return {AMDGPU::INVALID_FEATURE_COMBINATION, |
| 390 | "'+wavefrontsize32' and '+wavefrontsize64' are mutually exclusive" }; |
| 391 | if (DisableWave32 && DisableWave64) |
| 392 | return {AMDGPU::INVALID_FEATURE_COMBINATION, |
| 393 | "'-wavefrontsize32' and '-wavefrontsize64' are mutually exclusive" }; |
| 394 | |
| 395 | if (!IsNullGPU) { |
| 396 | if (TargetHasWave64) { |
| 397 | if (EnableWave32) |
| 398 | return {AMDGPU::UNSUPPORTED_TARGET_FEATURE, "+wavefrontsize32" }; |
| 399 | if (DisableWave64) |
| 400 | return {AMDGPU::UNSUPPORTED_TARGET_FEATURE, "-wavefrontsize64" }; |
| 401 | } |
| 402 | |
| 403 | if (TargetHasWave32) { |
| 404 | if (EnableWave64) |
| 405 | return {AMDGPU::UNSUPPORTED_TARGET_FEATURE, "+wavefrontsize64" }; |
| 406 | if (DisableWave32) |
| 407 | return {AMDGPU::UNSUPPORTED_TARGET_FEATURE, "-wavefrontsize32" }; |
| 408 | } |
| 409 | } |
| 410 | |
| 411 | // Don't assume any wavesize with an unknown subtarget. |
| 412 | // Default to wave32 if target supports both. |
| 413 | if (!IsNullGPU && !EnableWave32 && !EnableWave64 && !TargetHasWave32 && |
| 414 | !TargetHasWave64) |
| 415 | Features.insert(KV: std::make_pair(x: "wavefrontsize32" , y: true)); |
| 416 | |
| 417 | for (const auto &Entry : DefaultFeatures) { |
| 418 | if (!Features.count(Key: Entry.getKey())) |
| 419 | Features[Entry.getKey()] = Entry.getValue(); |
| 420 | } |
| 421 | |
| 422 | return {NO_ERROR, StringRef()}; |
| 423 | } |
| 424 | |
| 425 | /// Fills Features map with default values for given target GPU. |
| 426 | /// \p Features contains overriding target features and this function returns |
| 427 | /// default target features with entries overridden by \p Features. |
| 428 | static void fillAMDGCNFeatureMap(StringRef GPU, const Triple &T, |
| 429 | StringMap<bool> &Features) { |
| 430 | AMDGPU::GPUKind Kind = parseArchAMDGCN(CPU: GPU); |
| 431 | switch (Kind) { |
| 432 | case GK_GFX1310: |
| 433 | case GK_GFX13_GENERIC: |
| 434 | Features["ci-insts" ] = true; |
| 435 | Features["dot7-insts" ] = true; |
| 436 | Features["dot8-insts" ] = true; |
| 437 | Features["dl-insts" ] = true; |
| 438 | Features["16-bit-insts" ] = true; |
| 439 | Features["dpp" ] = true; |
| 440 | Features["gfx8-insts" ] = true; |
| 441 | Features["gfx9-insts" ] = true; |
| 442 | Features["gfx10-insts" ] = true; |
| 443 | Features["gfx10-3-insts" ] = true; |
| 444 | Features["gfx11-insts" ] = true; |
| 445 | Features["gfx12-insts" ] = true; |
| 446 | Features["gfx1250-insts" ] = true; |
| 447 | Features["gfx13-insts" ] = true; |
| 448 | Features["bitop3-insts" ] = true; |
| 449 | Features["prng-inst" ] = true; |
| 450 | Features["tanh-insts" ] = true; |
| 451 | Features["tensor-cvt-lut-insts" ] = true; |
| 452 | Features["bf16-trans-insts" ] = true; |
| 453 | Features["bf16-cvt-insts" ] = true; |
| 454 | Features["bf16-pk-insts" ] = true; |
| 455 | Features["fp8-conversion-insts" ] = true; |
| 456 | Features["permlane16-swap" ] = true; |
| 457 | Features["ashr-pk-insts" ] = true; |
| 458 | Features["atomic-buffer-pk-add-bf16-inst" ] = true; |
| 459 | Features["atomic-fadd-rtn-insts" ] = true; |
| 460 | Features["atomic-buffer-global-pk-add-f16-insts" ] = true; |
| 461 | Features["atomic-flat-pk-add-16-insts" ] = true; |
| 462 | Features["atomic-global-pk-add-bf16-inst" ] = true; |
| 463 | Features["atomic-ds-pk-add-16-insts" ] = true; |
| 464 | Features["s-wakeup-barrier-inst" ] = true; |
| 465 | Features["f16bf16-to-fp6bf6-cvt-scale-insts" ] = true; |
| 466 | Features["clusters" ] = true; |
| 467 | Features["cube-insts" ] = true; |
| 468 | Features["lerp-inst" ] = true; |
| 469 | Features["sad-insts" ] = true; |
| 470 | Features["qsad-insts" ] = true; |
| 471 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 472 | Features["cvt-pknorm-vop3-insts" ] = true; |
| 473 | Features["image-insts" ] = true; |
| 474 | break; |
| 475 | case GK_GFX1251: |
| 476 | Features["gfx1251-gemm-insts" ] = true; |
| 477 | [[fallthrough]]; |
| 478 | case GK_GFX1250: |
| 479 | Features["swmmac-gfx1200-insts" ] = true; |
| 480 | Features["swmmac-gfx1250-insts" ] = true; |
| 481 | Features["cube-insts" ] = true; |
| 482 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 483 | Features["lerp-inst" ] = true; |
| 484 | Features["qsad-insts" ] = true; |
| 485 | Features["sad-insts" ] = true; |
| 486 | Features["msad-insts" ] = true; |
| 487 | Features["mqsad-pk-insts" ] = true; |
| 488 | Features["mqsad-insts" ] = true; |
| 489 | [[fallthrough]]; |
| 490 | case GK_GFX12_5_GENERIC: |
| 491 | Features["ci-insts" ] = true; |
| 492 | Features["dot7-insts" ] = true; |
| 493 | Features["dot8-insts" ] = true; |
| 494 | Features["dl-insts" ] = true; |
| 495 | Features["16-bit-insts" ] = true; |
| 496 | Features["dpp" ] = true; |
| 497 | Features["gfx8-insts" ] = true; |
| 498 | Features["gfx9-insts" ] = true; |
| 499 | Features["flat-global-insts" ] = true; |
| 500 | Features["gfx10-insts" ] = true; |
| 501 | Features["gfx10-3-insts" ] = true; |
| 502 | Features["gfx11-insts" ] = true; |
| 503 | Features["gfx12-insts" ] = true; |
| 504 | Features["gfx1250-insts" ] = true; |
| 505 | Features["bitop3-insts" ] = true; |
| 506 | Features["prng-inst" ] = true; |
| 507 | Features["tanh-insts" ] = true; |
| 508 | Features["tensor-cvt-lut-insts" ] = true; |
| 509 | Features["transpose-load-f4f6-insts" ] = true; |
| 510 | Features["bf16-trans-insts" ] = true; |
| 511 | Features["bf16-cvt-insts" ] = true; |
| 512 | Features["bf16-pk-insts" ] = true; |
| 513 | Features["fp8-conversion-insts" ] = true; |
| 514 | Features["fp8e5m3-insts" ] = true; |
| 515 | Features["permlane16-swap" ] = true; |
| 516 | Features["ashr-pk-insts" ] = true; |
| 517 | Features["add-min-max-insts" ] = true; |
| 518 | Features["pk-add-min-max-insts" ] = true; |
| 519 | Features["atomic-buffer-pk-add-bf16-inst" ] = true; |
| 520 | Features["vmem-pref-insts" ] = true; |
| 521 | Features["atomic-fadd-rtn-insts" ] = true; |
| 522 | Features["atomic-buffer-global-pk-add-f16-insts" ] = true; |
| 523 | Features["atomic-flat-pk-add-16-insts" ] = true; |
| 524 | Features["atomic-global-pk-add-bf16-inst" ] = true; |
| 525 | Features["atomic-ds-pk-add-16-insts" ] = true; |
| 526 | Features["setprio-inc-wg-inst" ] = true; |
| 527 | Features["s-wakeup-barrier-inst" ] = true; |
| 528 | Features["atomic-fmin-fmax-global-f32" ] = true; |
| 529 | Features["atomic-fmin-fmax-global-f64" ] = true; |
| 530 | Features["wavefrontsize32" ] = true; |
| 531 | Features["clusters" ] = true; |
| 532 | Features["mcast-load-insts" ] = true; |
| 533 | Features["asynccnt" ] = true; |
| 534 | break; |
| 535 | case GK_GFX1201: |
| 536 | case GK_GFX1200: |
| 537 | case GK_GFX12_GENERIC: |
| 538 | Features["ci-insts" ] = true; |
| 539 | Features["dot7-insts" ] = true; |
| 540 | Features["dot8-insts" ] = true; |
| 541 | Features["dot9-insts" ] = true; |
| 542 | Features["dot10-insts" ] = true; |
| 543 | Features["dot11-insts" ] = true; |
| 544 | Features["dot12-insts" ] = true; |
| 545 | Features["dl-insts" ] = true; |
| 546 | Features["atomic-ds-pk-add-16-insts" ] = true; |
| 547 | Features["atomic-flat-pk-add-16-insts" ] = true; |
| 548 | Features["atomic-buffer-global-pk-add-f16-insts" ] = true; |
| 549 | Features["atomic-buffer-pk-add-bf16-inst" ] = true; |
| 550 | Features["atomic-global-pk-add-bf16-inst" ] = true; |
| 551 | Features["16-bit-insts" ] = true; |
| 552 | Features["dpp" ] = true; |
| 553 | Features["gfx8-insts" ] = true; |
| 554 | Features["gfx9-insts" ] = true; |
| 555 | Features["flat-global-insts" ] = true; |
| 556 | Features["gfx10-insts" ] = true; |
| 557 | Features["gfx10-3-insts" ] = true; |
| 558 | Features["gfx11-insts" ] = true; |
| 559 | Features["gfx12-insts" ] = true; |
| 560 | Features["atomic-fadd-rtn-insts" ] = true; |
| 561 | Features["image-insts" ] = true; |
| 562 | Features["bvh-ray-tracing-insts" ] = true; |
| 563 | Features["cube-insts" ] = true; |
| 564 | Features["lerp-inst" ] = true; |
| 565 | Features["sad-insts" ] = true; |
| 566 | Features["qsad-insts" ] = true; |
| 567 | Features["msad-insts" ] = true; |
| 568 | Features["mqsad-pk-insts" ] = true; |
| 569 | Features["mqsad-insts" ] = true; |
| 570 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 571 | Features["fp8-conversion-insts" ] = true; |
| 572 | Features["wmma-128b-insts" ] = true; |
| 573 | Features["swmmac-gfx1200-insts" ] = true; |
| 574 | Features["atomic-fmin-fmax-global-f32" ] = true; |
| 575 | break; |
| 576 | case GK_GFX1170: |
| 577 | case GK_GFX1171: |
| 578 | case GK_GFX1172: |
| 579 | case GK_GFX11_7_GENERIC: |
| 580 | Features["ci-insts" ] = true; |
| 581 | Features["dot7-insts" ] = true; |
| 582 | Features["dot8-insts" ] = true; |
| 583 | Features["dot9-insts" ] = true; |
| 584 | Features["dot10-insts" ] = true; |
| 585 | Features["dot12-insts" ] = true; |
| 586 | Features["dl-insts" ] = true; |
| 587 | Features["16-bit-insts" ] = true; |
| 588 | Features["dpp" ] = true; |
| 589 | Features["gfx8-insts" ] = true; |
| 590 | Features["gfx9-insts" ] = true; |
| 591 | Features["flat-global-insts" ] = true; |
| 592 | Features["gfx10-insts" ] = true; |
| 593 | Features["gfx10-3-insts" ] = true; |
| 594 | Features["gfx11-insts" ] = true; |
| 595 | Features["atomic-fadd-rtn-insts" ] = true; |
| 596 | Features["image-insts" ] = true; |
| 597 | Features["bvh-ray-tracing-insts" ] = true; |
| 598 | Features["cube-insts" ] = true; |
| 599 | Features["lerp-inst" ] = true; |
| 600 | Features["sad-insts" ] = true; |
| 601 | Features["qsad-insts" ] = true; |
| 602 | Features["msad-insts" ] = true; |
| 603 | Features["mqsad-pk-insts" ] = true; |
| 604 | Features["mqsad-insts" ] = true; |
| 605 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 606 | Features["gws" ] = true; |
| 607 | Features["dot11-insts" ] = true; |
| 608 | Features["fp8-conversion-insts" ] = true; |
| 609 | Features["wmma-128b-insts" ] = true; |
| 610 | Features["swmmac-gfx1200-insts" ] = true; |
| 611 | Features["atomic-fmin-fmax-global-f32" ] = true; |
| 612 | break; |
| 613 | case GK_GFX1154: |
| 614 | case GK_GFX1153: |
| 615 | case GK_GFX1152: |
| 616 | case GK_GFX1151: |
| 617 | case GK_GFX1150: |
| 618 | case GK_GFX1103: |
| 619 | case GK_GFX1102: |
| 620 | case GK_GFX1101: |
| 621 | case GK_GFX1100: |
| 622 | case GK_GFX11_GENERIC: |
| 623 | Features["ci-insts" ] = true; |
| 624 | Features["dot5-insts" ] = true; |
| 625 | Features["dot7-insts" ] = true; |
| 626 | Features["dot8-insts" ] = true; |
| 627 | Features["dot9-insts" ] = true; |
| 628 | Features["dot10-insts" ] = true; |
| 629 | Features["dot12-insts" ] = true; |
| 630 | Features["dl-insts" ] = true; |
| 631 | Features["16-bit-insts" ] = true; |
| 632 | Features["dpp" ] = true; |
| 633 | Features["gfx8-insts" ] = true; |
| 634 | Features["gfx9-insts" ] = true; |
| 635 | Features["flat-global-insts" ] = true; |
| 636 | Features["gfx10-insts" ] = true; |
| 637 | Features["gfx10-3-insts" ] = true; |
| 638 | Features["gfx11-insts" ] = true; |
| 639 | Features["atomic-fadd-rtn-insts" ] = true; |
| 640 | Features["image-insts" ] = true; |
| 641 | Features["bvh-ray-tracing-insts" ] = true; |
| 642 | Features["cube-insts" ] = true; |
| 643 | Features["lerp-inst" ] = true; |
| 644 | Features["sad-insts" ] = true; |
| 645 | Features["qsad-insts" ] = true; |
| 646 | Features["msad-insts" ] = true; |
| 647 | Features["mqsad-pk-insts" ] = true; |
| 648 | Features["mqsad-insts" ] = true; |
| 649 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 650 | Features["gws" ] = true; |
| 651 | Features["wmma-256b-insts" ] = true; |
| 652 | Features["atomic-fmin-fmax-global-f32" ] = true; |
| 653 | break; |
| 654 | case GK_GFX1036: |
| 655 | case GK_GFX1035: |
| 656 | case GK_GFX1034: |
| 657 | case GK_GFX1033: |
| 658 | case GK_GFX1032: |
| 659 | case GK_GFX1031: |
| 660 | case GK_GFX1030: |
| 661 | case GK_GFX10_3_GENERIC: |
| 662 | Features["ci-insts" ] = true; |
| 663 | Features["dot1-insts" ] = true; |
| 664 | Features["dot2-insts" ] = true; |
| 665 | Features["dot5-insts" ] = true; |
| 666 | Features["dot6-insts" ] = true; |
| 667 | Features["dot7-insts" ] = true; |
| 668 | Features["dot10-insts" ] = true; |
| 669 | Features["dl-insts" ] = true; |
| 670 | Features["16-bit-insts" ] = true; |
| 671 | Features["dpp" ] = true; |
| 672 | Features["gfx8-insts" ] = true; |
| 673 | Features["gfx9-insts" ] = true; |
| 674 | Features["flat-global-insts" ] = true; |
| 675 | Features["gfx10-insts" ] = true; |
| 676 | Features["gfx10-3-insts" ] = true; |
| 677 | Features["image-insts" ] = true; |
| 678 | Features["bvh-ray-tracing-insts" ] = true; |
| 679 | Features["s-memrealtime" ] = true; |
| 680 | Features["s-memtime-inst" ] = true; |
| 681 | Features["gws" ] = true; |
| 682 | Features["vmem-to-lds-load-insts" ] = true; |
| 683 | Features["atomic-fmin-fmax-global-f32" ] = true; |
| 684 | Features["atomic-fmin-fmax-global-f64" ] = true; |
| 685 | Features["cube-insts" ] = true; |
| 686 | Features["lerp-inst" ] = true; |
| 687 | Features["sad-insts" ] = true; |
| 688 | Features["qsad-insts" ] = true; |
| 689 | Features["msad-insts" ] = true; |
| 690 | Features["mqsad-pk-insts" ] = true; |
| 691 | Features["mqsad-insts" ] = true; |
| 692 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 693 | break; |
| 694 | case GK_GFX1012: |
| 695 | case GK_GFX1011: |
| 696 | Features["dot1-insts" ] = true; |
| 697 | Features["dot2-insts" ] = true; |
| 698 | Features["dot5-insts" ] = true; |
| 699 | Features["dot6-insts" ] = true; |
| 700 | Features["dot7-insts" ] = true; |
| 701 | Features["dot10-insts" ] = true; |
| 702 | [[fallthrough]]; |
| 703 | case GK_GFX1013: |
| 704 | case GK_GFX1010: |
| 705 | case GK_GFX10_1_GENERIC: |
| 706 | if (Kind == GK_GFX1013) |
| 707 | Features["bvh-ray-tracing-insts" ] = true; |
| 708 | Features["dl-insts" ] = true; |
| 709 | Features["ci-insts" ] = true; |
| 710 | Features["16-bit-insts" ] = true; |
| 711 | Features["dpp" ] = true; |
| 712 | Features["gfx8-insts" ] = true; |
| 713 | Features["gfx9-insts" ] = true; |
| 714 | Features["flat-global-insts" ] = true; |
| 715 | Features["gfx10-insts" ] = true; |
| 716 | Features["image-insts" ] = true; |
| 717 | Features["s-memrealtime" ] = true; |
| 718 | Features["s-memtime-inst" ] = true; |
| 719 | Features["gws" ] = true; |
| 720 | Features["vmem-to-lds-load-insts" ] = true; |
| 721 | Features["atomic-fmin-fmax-global-f32" ] = true; |
| 722 | Features["atomic-fmin-fmax-global-f64" ] = true; |
| 723 | Features["cube-insts" ] = true; |
| 724 | Features["lerp-inst" ] = true; |
| 725 | Features["sad-insts" ] = true; |
| 726 | Features["qsad-insts" ] = true; |
| 727 | Features["msad-insts" ] = true; |
| 728 | Features["mqsad-pk-insts" ] = true; |
| 729 | Features["mqsad-insts" ] = true; |
| 730 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 731 | break; |
| 732 | case GK_GFX950: |
| 733 | Features["bitop3-insts" ] = true; |
| 734 | Features["fp6bf6-cvt-scale-insts" ] = true; |
| 735 | Features["fp4-cvt-scale-insts" ] = true; |
| 736 | Features["bf8-cvt-scale-insts" ] = true; |
| 737 | Features["fp8-cvt-scale-insts" ] = true; |
| 738 | Features["f16bf16-to-fp6bf6-cvt-scale-insts" ] = true; |
| 739 | Features["f32-to-f16bf16-cvt-sr-insts" ] = true; |
| 740 | Features["prng-inst" ] = true; |
| 741 | Features["permlane16-swap" ] = true; |
| 742 | Features["permlane32-swap" ] = true; |
| 743 | Features["ashr-pk-insts" ] = true; |
| 744 | Features["dot12-insts" ] = true; |
| 745 | Features["dot13-insts" ] = true; |
| 746 | Features["atomic-buffer-pk-add-bf16-inst" ] = true; |
| 747 | Features["gfx950-insts" ] = true; |
| 748 | [[fallthrough]]; |
| 749 | case GK_GFX942: |
| 750 | Features["fp8-insts" ] = true; |
| 751 | Features["fp8-conversion-insts" ] = true; |
| 752 | if (Kind != GK_GFX950) |
| 753 | Features["xf32-insts" ] = true; |
| 754 | [[fallthrough]]; |
| 755 | case GK_GFX9_4_GENERIC: |
| 756 | Features["gfx940-insts" ] = true; |
| 757 | Features["atomic-ds-pk-add-16-insts" ] = true; |
| 758 | Features["atomic-flat-pk-add-16-insts" ] = true; |
| 759 | Features["atomic-global-pk-add-bf16-inst" ] = true; |
| 760 | Features["gfx90a-insts" ] = true; |
| 761 | Features["atomic-buffer-global-pk-add-f16-insts" ] = true; |
| 762 | Features["atomic-fadd-rtn-insts" ] = true; |
| 763 | Features["dot3-insts" ] = true; |
| 764 | Features["dot4-insts" ] = true; |
| 765 | Features["dot5-insts" ] = true; |
| 766 | Features["dot6-insts" ] = true; |
| 767 | Features["mai-insts" ] = true; |
| 768 | Features["dl-insts" ] = true; |
| 769 | Features["dot1-insts" ] = true; |
| 770 | Features["dot2-insts" ] = true; |
| 771 | Features["dot7-insts" ] = true; |
| 772 | Features["dot10-insts" ] = true; |
| 773 | Features["gfx9-insts" ] = true; |
| 774 | Features["flat-global-insts" ] = true; |
| 775 | Features["gfx8-insts" ] = true; |
| 776 | Features["16-bit-insts" ] = true; |
| 777 | Features["dpp" ] = true; |
| 778 | Features["s-memrealtime" ] = true; |
| 779 | Features["ci-insts" ] = true; |
| 780 | Features["s-memtime-inst" ] = true; |
| 781 | Features["gws" ] = true; |
| 782 | Features["vmem-to-lds-load-insts" ] = true; |
| 783 | Features["atomic-fmin-fmax-global-f64" ] = true; |
| 784 | Features["wavefrontsize64" ] = true; |
| 785 | Features["cube-insts" ] = true; |
| 786 | Features["lerp-inst" ] = true; |
| 787 | Features["sad-insts" ] = true; |
| 788 | Features["qsad-insts" ] = true; |
| 789 | Features["msad-insts" ] = true; |
| 790 | Features["mqsad-pk-insts" ] = true; |
| 791 | Features["mqsad-insts" ] = true; |
| 792 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 793 | break; |
| 794 | case GK_GFX90A: |
| 795 | Features["gfx90a-insts" ] = true; |
| 796 | Features["atomic-buffer-global-pk-add-f16-insts" ] = true; |
| 797 | Features["atomic-fadd-rtn-insts" ] = true; |
| 798 | Features["atomic-fmin-fmax-global-f64" ] = true; |
| 799 | [[fallthrough]]; |
| 800 | case GK_GFX908: |
| 801 | Features["dot3-insts" ] = true; |
| 802 | Features["dot4-insts" ] = true; |
| 803 | Features["dot5-insts" ] = true; |
| 804 | Features["dot6-insts" ] = true; |
| 805 | Features["mai-insts" ] = true; |
| 806 | [[fallthrough]]; |
| 807 | case GK_GFX906: |
| 808 | Features["dl-insts" ] = true; |
| 809 | Features["dot1-insts" ] = true; |
| 810 | Features["dot2-insts" ] = true; |
| 811 | Features["dot7-insts" ] = true; |
| 812 | Features["dot10-insts" ] = true; |
| 813 | [[fallthrough]]; |
| 814 | case GK_GFX90C: |
| 815 | case GK_GFX909: |
| 816 | case GK_GFX904: |
| 817 | case GK_GFX902: |
| 818 | case GK_GFX900: |
| 819 | case GK_GFX9_GENERIC: |
| 820 | Features["gfx9-insts" ] = true; |
| 821 | Features["flat-global-insts" ] = true; |
| 822 | Features["vmem-to-lds-load-insts" ] = true; |
| 823 | [[fallthrough]]; |
| 824 | case GK_GFX810: |
| 825 | case GK_GFX805: |
| 826 | case GK_GFX803: |
| 827 | case GK_GFX802: |
| 828 | case GK_GFX801: |
| 829 | Features["gfx8-insts" ] = true; |
| 830 | Features["16-bit-insts" ] = true; |
| 831 | Features["dpp" ] = true; |
| 832 | Features["s-memrealtime" ] = true; |
| 833 | Features["ci-insts" ] = true; |
| 834 | Features["image-insts" ] = true; |
| 835 | Features["s-memtime-inst" ] = true; |
| 836 | Features["gws" ] = true; |
| 837 | Features["wavefrontsize64" ] = true; |
| 838 | Features["cube-insts" ] = true; |
| 839 | Features["lerp-inst" ] = true; |
| 840 | Features["sad-insts" ] = true; |
| 841 | Features["qsad-insts" ] = true; |
| 842 | Features["msad-insts" ] = true; |
| 843 | Features["mqsad-pk-insts" ] = true; |
| 844 | Features["mqsad-insts" ] = true; |
| 845 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 846 | break; |
| 847 | case GK_GFX705: |
| 848 | case GK_GFX704: |
| 849 | case GK_GFX703: |
| 850 | case GK_GFX702: |
| 851 | case GK_GFX701: |
| 852 | case GK_GFX700: |
| 853 | Features["ci-insts" ] = true; |
| 854 | Features["cube-insts" ] = true; |
| 855 | Features["lerp-inst" ] = true; |
| 856 | Features["sad-insts" ] = true; |
| 857 | Features["qsad-insts" ] = true; |
| 858 | Features["msad-insts" ] = true; |
| 859 | Features["mqsad-pk-insts" ] = true; |
| 860 | Features["mqsad-insts" ] = true; |
| 861 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 862 | Features["image-insts" ] = true; |
| 863 | Features["s-memtime-inst" ] = true; |
| 864 | Features["gws" ] = true; |
| 865 | Features["atomic-fmin-fmax-global-f32" ] = true; |
| 866 | Features["atomic-fmin-fmax-global-f64" ] = true; |
| 867 | Features["wavefrontsize64" ] = true; |
| 868 | break; |
| 869 | case GK_GFX602: |
| 870 | case GK_GFX601: |
| 871 | case GK_GFX600: |
| 872 | Features["image-insts" ] = true; |
| 873 | Features["s-memtime-inst" ] = true; |
| 874 | Features["gws" ] = true; |
| 875 | Features["atomic-fmin-fmax-global-f32" ] = true; |
| 876 | Features["atomic-fmin-fmax-global-f64" ] = true; |
| 877 | Features["wavefrontsize64" ] = true; |
| 878 | Features["cube-insts" ] = true; |
| 879 | Features["lerp-inst" ] = true; |
| 880 | Features["sad-insts" ] = true; |
| 881 | Features["msad-insts" ] = true; |
| 882 | Features["mqsad-pk-insts" ] = true; |
| 883 | Features["cvt-pknorm-vop2-insts" ] = true; |
| 884 | break; |
| 885 | case GK_NONE: |
| 886 | break; |
| 887 | default: |
| 888 | llvm_unreachable("Unhandled GPU!" ); |
| 889 | } |
| 890 | } |
| 891 | |
| 892 | /// Fills Features map with default values for given target GPU. |
| 893 | /// \p Features contains overriding target features and this function returns |
| 894 | /// default target features with entries overridden by \p Features. |
| 895 | std::pair<FeatureError, StringRef> |
| 896 | AMDGPU::fillAMDGPUFeatureMap(StringRef GPU, const Triple &T, |
| 897 | StringMap<bool> &Features) { |
| 898 | // XXX - What does the member GPU mean if device name string passed here? |
| 899 | if (T.isSPIRV() && T.getOS() == Triple::OSType::AMDHSA) { |
| 900 | // AMDGCN SPIRV must support the union of all AMDGCN features. |
| 901 | SmallVector<StringRef> GPUs; |
| 902 | fillValidArchListAMDGCN(Values&: GPUs); |
| 903 | |
| 904 | static const Triple AMDGCN("amdgcn-amd-amdhsa" ); |
| 905 | StringMap<bool> Tmp; |
| 906 | for (auto &&GPU : GPUs) { |
| 907 | fillAMDGCNFeatureMap(GPU, T: AMDGCN, Features&: Tmp); |
| 908 | for (auto &&[F, B] : Tmp) |
| 909 | Features[F] = B; |
| 910 | } |
| 911 | Features["wavefrontsize32" ] = true; |
| 912 | Features["wavefrontsize64" ] = true; |
| 913 | } else if (T.isAMDGCN()) { |
| 914 | StringMap<bool> DefaultFeatures; |
| 915 | fillAMDGCNFeatureMap(GPU, T, Features&: DefaultFeatures); |
| 916 | return insertWaveSizeFeature(GPU, T, DefaultFeatures, Features); |
| 917 | } else { |
| 918 | if (GPU.empty()) |
| 919 | GPU = "r600" ; |
| 920 | |
| 921 | switch (llvm::AMDGPU::parseArchR600(CPU: GPU)) { |
| 922 | case GK_CAYMAN: |
| 923 | case GK_CYPRESS: |
| 924 | case GK_RV770: |
| 925 | case GK_RV670: |
| 926 | // TODO: Add fp64 when implemented. |
| 927 | break; |
| 928 | case GK_TURKS: |
| 929 | case GK_CAICOS: |
| 930 | case GK_BARTS: |
| 931 | case GK_SUMO: |
| 932 | case GK_REDWOOD: |
| 933 | case GK_JUNIPER: |
| 934 | case GK_CEDAR: |
| 935 | case GK_RV730: |
| 936 | case GK_RV710: |
| 937 | case GK_RS880: |
| 938 | case GK_R630: |
| 939 | case GK_R600: |
| 940 | break; |
| 941 | default: |
| 942 | llvm_unreachable("Unhandled GPU!" ); |
| 943 | } |
| 944 | } |
| 945 | return {NO_ERROR, StringRef()}; |
| 946 | } |
| 947 | |
| 948 | TargetID::TargetID(GPUKind Arch, const Triple &TT, TargetIDSetting XnackSetting, |
| 949 | TargetIDSetting SramEccSetting) |
| 950 | : Arch(Arch), |
| 951 | TargetTripleString(TT.normalize(Form: Triple::CanonicalForm::FOUR_IDENT)), |
| 952 | XnackSetting(XnackSetting), SramEccSetting(SramEccSetting), |
| 953 | IsAMDHSA(TT.getOS() == Triple::AMDHSA) {} |
| 954 | |
| 955 | static TargetIDSetting |
| 956 | getTargetIDSettingFromFeatureString(StringRef FeatureString) { |
| 957 | if (FeatureString.ends_with(Suffix: "-" )) |
| 958 | return TargetIDSetting::Off; |
| 959 | if (FeatureString.ends_with(Suffix: "+" )) |
| 960 | return TargetIDSetting::On; |
| 961 | |
| 962 | llvm_unreachable("Malformed feature string" ); |
| 963 | } |
| 964 | |
| 965 | // Derive the architecture from the processor name in \p TargetIDStr. "generic" |
| 966 | // and the empty processor name act as a wildcard. |
| 967 | static GPUKind getGPUKindFromTargetID(const Triple &TT, StringRef TargetIDStr) { |
| 968 | StringRef CPUName = TargetIDStr.split(Separator: ':').first; |
| 969 | return (CPUName.empty() || CPUName == "generic" ) |
| 970 | ? getGPUKindFromSubArch(SubArch: TT.getSubArch()) |
| 971 | : parseArchAMDGCN(CPU: CPUName); |
| 972 | } |
| 973 | |
| 974 | TargetID::TargetID(const Triple &TT, StringRef TargetIDStr) |
| 975 | : TargetID(getGPUKindFromTargetID(TT, TargetIDStr), TT, |
| 976 | TargetIDSetting::Unsupported, TargetIDSetting::Unsupported) { |
| 977 | // Default xnack/sramecc to the "Any" wildcard when the architecture supports |
| 978 | // them, then apply any explicit feature overrides from the target-id string. |
| 979 | unsigned ArchAttr = getArchAttrAMDGCN(AK: Arch); |
| 980 | if (ArchAttr & FEATURE_XNACK) |
| 981 | XnackSetting = TargetIDSetting::Any; |
| 982 | if (ArchAttr & FEATURE_SRAMECC) |
| 983 | SramEccSetting = TargetIDSetting::Any; |
| 984 | setTargetIDFromTargetIDStream(TargetIDStr); |
| 985 | } |
| 986 | |
| 987 | void TargetID::setTargetIDFromTargetIDStream(StringRef TargetID) { |
| 988 | SmallVector<StringRef, 3> TargetIDSplit; |
| 989 | TargetID.split(A&: TargetIDSplit, Separator: ':'); |
| 990 | |
| 991 | for (const auto &FeatureString : TargetIDSplit) { |
| 992 | if (FeatureString.starts_with(Prefix: "xnack" )) |
| 993 | XnackSetting = getTargetIDSettingFromFeatureString(FeatureString); |
| 994 | if (FeatureString.starts_with(Prefix: "sramecc" )) |
| 995 | SramEccSetting = getTargetIDSettingFromFeatureString(FeatureString); |
| 996 | } |
| 997 | } |
| 998 | |
| 999 | std::optional<TargetID> |
| 1000 | TargetID::parseTargetIDString(StringRef TargetIDDirective) { |
| 1001 | // Split on '-' to get arch-vendor-os-environment-processor:features |
| 1002 | // There is a single dash separator after the 4-component triple |
| 1003 | SmallVector<StringRef, 5> Parts; |
| 1004 | TargetIDDirective.split(A&: Parts, Separator: '-', /*MaxSplit=*/4); |
| 1005 | if (Parts.size() < 4) |
| 1006 | return std::nullopt; |
| 1007 | |
| 1008 | Triple TT(Parts[0], Parts[1], Parts[2], Parts[3]); |
| 1009 | if (!TT.isAMDGCN()) |
| 1010 | return std::nullopt; |
| 1011 | |
| 1012 | // The processor+features field must be present, even if empty (the ISA can |
| 1013 | // be encoded in the triple's subarch, e.g. |
| 1014 | // "amdgpu12.50-amd-amdhsa-unknown-"). |
| 1015 | return TargetID(TT, Parts[4]); |
| 1016 | } |
| 1017 | |
| 1018 | void TargetID::print(raw_ostream &StreamRep) const { |
| 1019 | StreamRep << TargetTripleString << '-' << getArchNameAMDGCN(AK: Arch); |
| 1020 | |
| 1021 | if (IsAMDHSA) { |
| 1022 | // sramecc. |
| 1023 | if (getSramEccSetting() == TargetIDSetting::Off) |
| 1024 | StreamRep << ":sramecc-" ; |
| 1025 | else if (getSramEccSetting() == TargetIDSetting::On) |
| 1026 | StreamRep << ":sramecc+" ; |
| 1027 | |
| 1028 | // xnack. |
| 1029 | if (getXnackSetting() == TargetIDSetting::Off) |
| 1030 | StreamRep << ":xnack-" ; |
| 1031 | else if (getXnackSetting() == TargetIDSetting::On) |
| 1032 | StreamRep << ":xnack+" ; |
| 1033 | } |
| 1034 | } |
| 1035 | |
| 1036 | std::string TargetID::toString() const { |
| 1037 | std::string Str; |
| 1038 | raw_string_ostream OS(Str); |
| 1039 | OS << *this; |
| 1040 | return Str; |
| 1041 | } |
| 1042 | |
| 1043 | bool TargetID::operator==(const TargetID &Other) const { |
| 1044 | return Arch == Other.Arch && XnackSetting == Other.XnackSetting && |
| 1045 | SramEccSetting == Other.SramEccSetting && IsAMDHSA == Other.IsAMDHSA && |
| 1046 | TargetTripleString == Other.TargetTripleString; |
| 1047 | } |
| 1048 | |
| 1049 | static bool featureProvidesFor(TargetIDSetting Provided, |
| 1050 | TargetIDSetting Requested) { |
| 1051 | return Provided == TargetIDSetting::Any || |
| 1052 | Provided == TargetIDSetting::Unsupported || Provided == Requested; |
| 1053 | } |
| 1054 | |
| 1055 | bool TargetID::isEquivalent(const TargetID &Other) const { |
| 1056 | // The processor and feature settings must match exactly |
| 1057 | if (Arch != Other.Arch || XnackSetting != Other.XnackSetting || |
| 1058 | SramEccSetting != Other.SramEccSetting) |
| 1059 | return false; |
| 1060 | |
| 1061 | return Triple(getTargetTripleString()) |
| 1062 | .isCompatibleWith(Other: Triple(Other.getTargetTripleString())); |
| 1063 | } |
| 1064 | |
| 1065 | bool TargetID::providesFor(const TargetID &Other) const { |
| 1066 | // A major-family/generic processor (e.g. amdgpu9) provides for a specific |
| 1067 | // member of its family (e.g. gfx900), but not the reverse. Otherwise the |
| 1068 | // processors must match. |
| 1069 | if (Arch != Other.Arch && Arch != GK_NONE && Other.Arch != GK_NONE) { |
| 1070 | Triple::SubArchType ThisSubArch = getSubArch(AK: Arch); |
| 1071 | if (ThisSubArch != getMajorSubArch(X: ThisSubArch) || |
| 1072 | ThisSubArch != getMajorSubArch(X: getSubArch(AK: Other.Arch))) |
| 1073 | return false; |
| 1074 | } |
| 1075 | |
| 1076 | if (!featureProvidesFor(Provided: XnackSetting, Requested: Other.XnackSetting) || |
| 1077 | !featureProvidesFor(Provided: SramEccSetting, Requested: Other.SramEccSetting)) |
| 1078 | return false; |
| 1079 | |
| 1080 | return Triple(getTargetTripleString()) |
| 1081 | .isCompatibleWith(Other: Triple(Other.getTargetTripleString())); |
| 1082 | } |
| 1083 | |