20#include "llvm/IR/IntrinsicsSPIRV.h" 
   25#define DEBUG_TYPE "spirv-builtins" 
   29#define GET_BuiltinGroup_DECL 
   30#include "SPIRVGenTables.inc" 
   34  InstructionSet::InstructionSet 
Set;
 
 
   40#define GET_DemangledBuiltins_DECL 
   41#define GET_DemangledBuiltins_IMPL 
   63  InstructionSet::InstructionSet 
Set;
 
 
   67#define GET_NativeBuiltins_DECL 
   68#define GET_NativeBuiltins_IMPL 
   86#define GET_GroupBuiltins_DECL 
   87#define GET_GroupBuiltins_IMPL 
   97#define GET_IntelSubgroupsBuiltins_DECL 
   98#define GET_IntelSubgroupsBuiltins_IMPL 
  105#define GET_AtomicFloatingBuiltins_DECL 
  106#define GET_AtomicFloatingBuiltins_IMPL 
  113#define GET_GroupUniformBuiltins_DECL 
  114#define GET_GroupUniformBuiltins_IMPL 
  118  InstructionSet::InstructionSet 
Set;
 
 
  123#define GET_GetBuiltins_DECL 
  124#define GET_GetBuiltins_IMPL 
  128  InstructionSet::InstructionSet 
Set;
 
 
  132#define GET_ImageQueryBuiltins_DECL 
  133#define GET_ImageQueryBuiltins_IMPL 
  141#define GET_IntegerDotProductBuiltins_DECL 
  142#define GET_IntegerDotProductBuiltins_IMPL 
  146  InstructionSet::InstructionSet 
Set;
 
 
  157  InstructionSet::InstructionSet 
Set;
 
 
  165#define GET_ConvertBuiltins_DECL 
  166#define GET_ConvertBuiltins_IMPL 
  168using namespace InstructionSet;
 
  169#define GET_VectorLoadStoreBuiltins_DECL 
  170#define GET_VectorLoadStoreBuiltins_IMPL 
  172#define GET_CLMemoryScope_DECL 
  173#define GET_CLSamplerAddressingMode_DECL 
  174#define GET_CLMemoryFenceFlags_DECL 
  175#define GET_ExtendedBuiltins_DECL 
  176#include "SPIRVGenTables.inc" 
  188  StringRef PassPrefix = 
"(anonymous namespace)::";
 
  189  std::string BuiltinName;
 
  192    BuiltinName = DemangledCall.
substr(PassPrefix.
size());
 
  194    BuiltinName = DemangledCall;
 
  197  BuiltinName = BuiltinName.
substr(0, BuiltinName.find(
'('));
 
  200  if (BuiltinName.rfind(
"__spirv_ocl_", 0) == 0)
 
  201    BuiltinName = BuiltinName.
substr(12);
 
  206  std::size_t Pos1 = BuiltinName.
rfind(
'<');
 
  207  if (Pos1 != std::string::npos && BuiltinName.back() == 
'>') {
 
  208    std::size_t Pos2 = BuiltinName.rfind(
' ', Pos1);
 
  209    if (Pos2 == std::string::npos)
 
  213    BuiltinName = BuiltinName.substr(Pos2, Pos1 - Pos2);
 
  214    BuiltinName = BuiltinName.substr(BuiltinName.find_last_of(
' ') + 1);
 
  241  static const std::regex SpvWithR(
 
  242      "(__spirv_(ImageSampleExplicitLod|ImageRead|ImageWrite|ImageQuerySizeLod|" 
  244      "SDotKHR|SUDotKHR|SDotAccSatKHR|UDotAccSatKHR|SUDotAccSatKHR|" 
  245      "ReadClockKHR|SubgroupBlockReadINTEL|SubgroupImageBlockReadINTEL|" 
  246      "SubgroupImageMediaBlockReadINTEL|SubgroupImageMediaBlockWriteINTEL|" 
  248      "UConvert|SConvert|FConvert|SatConvert)[^_]*)(_R[^_]*_?(\\w+)?.*)?");
 
  250  if (std::regex_match(BuiltinName, Match, SpvWithR) && Match.size() > 1) {
 
  251    std::ssub_match SubMatch;
 
  252    if (DecorationId && Match.size() > 3) {
 
  257    BuiltinName = SubMatch.str();
 
 
  274static std::unique_ptr<const SPIRV::IncomingCall>
 
  276              SPIRV::InstructionSet::InstructionSet Set,
 
  283      DemangledCall.
slice(DemangledCall.
find(
'(') + 1, DemangledCall.
find(
')'));
 
  284  BuiltinArgs.
split(BuiltinArgumentTypes, 
',', -1, 
false);
 
  289  if ((Builtin = SPIRV::lookupBuiltin(BuiltinName, Set)))
 
  290    return std::make_unique<SPIRV::IncomingCall>(
 
  291        BuiltinName, Builtin, ReturnRegister, ReturnType, 
Arguments);
 
  296  if (BuiltinArgumentTypes.
size() >= 1) {
 
  297    char FirstArgumentType = BuiltinArgumentTypes[0][0];
 
  302    switch (FirstArgumentType) {
 
  305      if (Set == SPIRV::InstructionSet::OpenCL_std)
 
  307      else if (Set == SPIRV::InstructionSet::GLSL_std_450)
 
  315      if (Set == SPIRV::InstructionSet::OpenCL_std)
 
  317      else if (Set == SPIRV::InstructionSet::GLSL_std_450)
 
  324      if (Set == SPIRV::InstructionSet::OpenCL_std ||
 
  325          Set == SPIRV::InstructionSet::GLSL_std_450)
 
  331    if (!Prefix.empty() &&
 
  332        (Builtin = SPIRV::lookupBuiltin(Prefix + BuiltinName, Set)))
 
  333      return std::make_unique<SPIRV::IncomingCall>(
 
  334          BuiltinName, Builtin, ReturnRegister, ReturnType, 
Arguments);
 
  341    switch (FirstArgumentType) {
 
  362    if (!Suffix.empty() &&
 
  363        (Builtin = SPIRV::lookupBuiltin(BuiltinName + Suffix, Set)))
 
  364      return std::make_unique<SPIRV::IncomingCall>(
 
  365          BuiltinName, Builtin, ReturnRegister, ReturnType, 
Arguments);
 
 
  380  assert(
MI->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST &&
 
  381         MI->getOperand(1).isReg());
 
  382  Register BitcastReg = 
MI->getOperand(1).getReg();
 
 
  396  assert(
DefMI->getOpcode() == TargetOpcode::G_CONSTANT &&
 
  397         DefMI->getOperand(1).isCImm());
 
  398  return DefMI->getOperand(1).getCImm()->getValue().getZExtValue();
 
 
  410  Register ValueReg = 
MI->getOperand(0).getReg();
 
  416  assert(Ty && 
"Type is expected");
 
 
  428  if (
MI->getOpcode() == TargetOpcode::G_GLOBAL_VALUE)
 
  429    return MI->getOperand(1).getGlobal()->getType();
 
  431         "Blocks in OpenCL C must be traceable to allocation site");
 
 
  443static std::tuple<Register, SPIRVType *>
 
  449  if (ResultType->
getOpcode() == SPIRV::OpTypeVector) {
 
  464  return std::make_tuple(ResultRegister, BoolType);
 
 
  475  if (ReturnType->getOpcode() == SPIRV::OpTypeVector) {
 
  486  return MIRBuilder.
buildSelect(ReturnRegister, SourceRegister, TrueConst,
 
 
  496  if (!DestinationReg.isValid())
 
  501  MIRBuilder.
buildLoad(DestinationReg, PtrRegister, PtrInfo, 
Align());
 
  502  return DestinationReg;
 
 
  511    const std::optional<SPIRV::LinkageType::LinkageType> &LinkageTy = {
 
  512        SPIRV::LinkageType::Import}) {
 
  520      VariableType, MIRBuilder, SPIRV::StorageClass::Input);
 
  526      SPIRV::StorageClass::Input, 
nullptr,  isConst, LinkageTy,
 
  533  return LoadedRegister;
 
 
  546static SPIRV::MemorySemantics::MemorySemantics
 
  549  case std::memory_order_relaxed:
 
  550    return SPIRV::MemorySemantics::None;
 
  551  case std::memory_order_acquire:
 
  552    return SPIRV::MemorySemantics::Acquire;
 
  553  case std::memory_order_release:
 
  554    return SPIRV::MemorySemantics::Release;
 
  555  case std::memory_order_acq_rel:
 
  556    return SPIRV::MemorySemantics::AcquireRelease;
 
  557  case std::memory_order_seq_cst:
 
  558    return SPIRV::MemorySemantics::SequentiallyConsistent;
 
 
  566  case SPIRV::CLMemoryScope::memory_scope_work_item:
 
  567    return SPIRV::Scope::Invocation;
 
  568  case SPIRV::CLMemoryScope::memory_scope_work_group:
 
  569    return SPIRV::Scope::Workgroup;
 
  570  case SPIRV::CLMemoryScope::memory_scope_device:
 
  571    return SPIRV::Scope::Device;
 
  572  case SPIRV::CLMemoryScope::memory_scope_all_svm_devices:
 
  573    return SPIRV::Scope::CrossDevice;
 
  574  case SPIRV::CLMemoryScope::memory_scope_sub_group:
 
  575    return SPIRV::Scope::Subgroup;
 
 
  588                              SPIRV::Scope::Scope Scope,
 
  592  if (CLScopeRegister.
isValid()) {
 
  597    if (CLScope == 
static_cast<unsigned>(Scope)) {
 
  598      MRI->setRegClass(CLScopeRegister, &SPIRV::iIDRegClass);
 
  599      return CLScopeRegister;
 
 
  607  if (
MRI->getRegClassOrNull(
Reg))
 
  611                   SpvType ? GR->
getRegClass(SpvType) : &SPIRV::iIDRegClass);
 
 
  615                                     Register PtrRegister, 
unsigned &Semantics,
 
  618  if (SemanticsRegister.
isValid()) {
 
  620    std::memory_order Order =
 
  625    if (
static_cast<unsigned>(Order) == Semantics) {
 
  626      MRI->setRegClass(SemanticsRegister, &SPIRV::iIDRegClass);
 
  627      return SemanticsRegister;
 
 
  640  unsigned Sz = 
Call->Arguments.size() - ImmArgs.size();
 
  641  for (
unsigned i = 0; i < Sz; ++i)
 
  642    MIB.addUse(
Call->Arguments[i]);
 
 
  651  if (
Call->isSpirvOp())
 
  655         "Need 2 arguments for atomic init translation");
 
 
  667  if (
Call->isSpirvOp())
 
  675      Call->Arguments.size() > 1
 
  679  if (
Call->Arguments.size() > 2) {
 
  681    MemSemanticsReg = 
Call->Arguments[2];
 
  684        SPIRV::MemorySemantics::SequentiallyConsistent |
 
 
  702  if (
Call->isSpirvOp())
 
  710      SPIRV::MemorySemantics::SequentiallyConsistent |
 
 
  725  if (
Call->isSpirvOp())
 
  729  bool IsCmpxchg = 
Call->Builtin->Name.contains(
"cmpxchg");
 
  736  LLT DesiredLLT = 
MRI->getType(Desired);
 
  739         SPIRV::OpTypePointer);
 
  742  assert(IsCmpxchg ? ExpectedType == SPIRV::OpTypeInt
 
  743                   : ExpectedType == SPIRV::OpTypePointer);
 
  748  auto StorageClass = 
static_cast<SPIRV::StorageClass::StorageClass
>(
 
  756          ? SPIRV::MemorySemantics::None
 
  757          : SPIRV::MemorySemantics::SequentiallyConsistent | MemSemStorage;
 
  760          ? SPIRV::MemorySemantics::None
 
  761          : SPIRV::MemorySemantics::SequentiallyConsistent | MemSemStorage;
 
  762  if (
Call->Arguments.size() >= 4) {
 
  764           "Need 5+ args for explicit atomic cmpxchg");
 
  771    if (
static_cast<unsigned>(MemOrdEq) == MemSemEqual)
 
  772      MemSemEqualReg = 
Call->Arguments[3];
 
  773    if (
static_cast<unsigned>(MemOrdNeq) == MemSemEqual)
 
  774      MemSemUnequalReg = 
Call->Arguments[4];
 
  778  if (!MemSemUnequalReg.
isValid())
 
  782  auto Scope = IsCmpxchg ? SPIRV::Scope::Workgroup : SPIRV::Scope::Device;
 
  783  if (
Call->Arguments.size() >= 6) {
 
  785           "Extra args for explicit atomic cmpxchg");
 
  786    auto ClScope = 
static_cast<SPIRV::CLMemoryScope
>(
 
  789    if (ClScope == 
static_cast<unsigned>(Scope))
 
  790      ScopeReg = 
Call->Arguments[5];
 
  800  Register Tmp = !IsCmpxchg ? 
MRI->createGenericVirtualRegister(DesiredLLT)
 
  801                            : 
Call->ReturnRegister;
 
  802  if (!
MRI->getRegClassOrNull(Tmp))
 
 
  826  if (
Call->isSpirvOp())
 
  835         "Too many args for explicit atomic RMW");
 
  836  ScopeRegister = 
buildScopeReg(ScopeRegister, SPIRV::Scope::Workgroup,
 
  837                                MIRBuilder, GR, 
MRI);
 
  840  unsigned Semantics = SPIRV::MemorySemantics::None;
 
  844                                         Semantics, MIRBuilder, GR);
 
  848  if (
Call->ReturnType->getOpcode() == SPIRV::OpTypeFloat) {
 
  849    if (Opcode == SPIRV::OpAtomicIAdd) {
 
  850      Opcode = SPIRV::OpAtomicFAddEXT;
 
  851    } 
else if (Opcode == SPIRV::OpAtomicISub) {
 
  854      Opcode = SPIRV::OpAtomicFAddEXT;
 
  856          MRI->createGenericVirtualRegister(
MRI->getType(ValueReg));
 
  865      ValueReg = NegValueReg;
 
 
  884         "Wrong number of atomic floating-type builtin");
 
 
  904  bool IsSet = Opcode == SPIRV::OpAtomicFlagTestAndSet;
 
  906  if (
Call->isSpirvOp())
 
  912  unsigned Semantics = SPIRV::MemorySemantics::SequentiallyConsistent;
 
  916                                         Semantics, MIRBuilder, GR);
 
  918  assert((Opcode != SPIRV::OpAtomicFlagClear ||
 
  919          (Semantics != SPIRV::MemorySemantics::Acquire &&
 
  920           Semantics != SPIRV::MemorySemantics::AcquireRelease)) &&
 
  921         "Invalid memory order argument!");
 
 
  944  if ((Opcode == SPIRV::OpControlBarrierArriveINTEL ||
 
  945       Opcode == SPIRV::OpControlBarrierWaitINTEL) &&
 
  946      !ST->canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
 
  947    std::string DiagMsg = std::string(Builtin->
Name) +
 
  948                          ": the builtin requires the following SPIR-V " 
  949                          "extension: SPV_INTEL_split_barrier";
 
  953  if (
Call->isSpirvOp())
 
  958  unsigned MemSemantics = SPIRV::MemorySemantics::None;
 
  960  if (MemFlags & SPIRV::CLK_LOCAL_MEM_FENCE)
 
  961    MemSemantics |= SPIRV::MemorySemantics::WorkgroupMemory;
 
  963  if (MemFlags & SPIRV::CLK_GLOBAL_MEM_FENCE)
 
  964    MemSemantics |= SPIRV::MemorySemantics::CrossWorkgroupMemory;
 
  966  if (MemFlags & SPIRV::CLK_IMAGE_MEM_FENCE)
 
  967    MemSemantics |= SPIRV::MemorySemantics::ImageMemory;
 
  969  if (Opcode == SPIRV::OpMemoryBarrier)
 
  973  else if (Opcode == SPIRV::OpControlBarrierArriveINTEL)
 
  974    MemSemantics |= SPIRV::MemorySemantics::Release;
 
  975  else if (Opcode == SPIRV::OpControlBarrierWaitINTEL)
 
  976    MemSemantics |= SPIRV::MemorySemantics::Acquire;
 
  978    MemSemantics |= SPIRV::MemorySemantics::SequentiallyConsistent;
 
  981      MemFlags == MemSemantics
 
  985  SPIRV::Scope::Scope Scope = SPIRV::Scope::Workgroup;
 
  986  SPIRV::Scope::Scope MemScope = Scope;
 
  987  if (
Call->Arguments.size() >= 2) {
 
  989        ((Opcode != SPIRV::OpMemoryBarrier && 
Call->Arguments.size() == 2) ||
 
  990         (Opcode == SPIRV::OpMemoryBarrier && 
Call->Arguments.size() == 3)) &&
 
  991        "Extra args for explicitly scoped barrier");
 
  992    Register ScopeArg = (Opcode == SPIRV::OpMemoryBarrier) ? 
Call->Arguments[2]
 
  993                                                           : 
Call->Arguments[1];
 
  994    SPIRV::CLMemoryScope CLScope =
 
  997    if (!(MemFlags & SPIRV::CLK_LOCAL_MEM_FENCE) ||
 
  998        (Opcode == SPIRV::OpMemoryBarrier))
 
 1000    if (CLScope == 
static_cast<unsigned>(Scope))
 
 1001      ScopeReg = 
Call->Arguments[1];
 
 1008  if (Opcode != SPIRV::OpMemoryBarrier)
 
 1010  MIB.
addUse(MemSemanticsReg);
 
 
 1022  if ((Opcode == SPIRV::OpBitFieldInsert ||
 
 1023       Opcode == SPIRV::OpBitFieldSExtract ||
 
 1024       Opcode == SPIRV::OpBitFieldUExtract || Opcode == SPIRV::OpBitReverse) &&
 
 1025      !ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
 
 1026    std::string DiagMsg = std::string(Builtin->
Name) +
 
 1027                          ": the builtin requires the following SPIR-V " 
 1028                          "extension: SPV_KHR_bit_instructions";
 
 1033  if (
Call->isSpirvOp())
 
 1040  for (
unsigned i = 0; i < 
Call->Arguments.size(); ++i)
 
 
 1052  if (
Call->isSpirvOp())
 
 
 1069  if (
Call->isSpirvOp())
 
 1076  for (
unsigned i = 0; i < 
Call->Arguments.size(); ++i)
 
 
 1088  if (
Call->isSpirvOp())
 
 1094  for (
unsigned i = 0; i < 
Call->Arguments.size(); ++i)
 
 
 1104  case SPIRV::OpCommitReadPipe:
 
 1105  case SPIRV::OpCommitWritePipe:
 
 1107  case SPIRV::OpGroupCommitReadPipe:
 
 1108  case SPIRV::OpGroupCommitWritePipe:
 
 1109  case SPIRV::OpGroupReserveReadPipePackets:
 
 1110  case SPIRV::OpGroupReserveWritePipePackets: {
 
 1114    MRI->setRegClass(ScopeConstReg, &SPIRV::iIDRegClass);
 
 1118    if (Opcode == SPIRV::OpGroupReserveReadPipePackets ||
 
 1119        Opcode == SPIRV::OpGroupReserveWritePipePackets)
 
 1123    MIB.
addUse(ScopeConstReg);
 
 1124    for (
unsigned int i = 0; i < 
Call->Arguments.size(); ++i)
 
 
 1137  case SPIRV::Dim::DIM_1D:
 
 1138  case SPIRV::Dim::DIM_Buffer:
 
 1140  case SPIRV::Dim::DIM_2D:
 
 1141  case SPIRV::Dim::DIM_Cube:
 
 1142  case SPIRV::Dim::DIM_Rect:
 
 1144  case SPIRV::Dim::DIM_3D:
 
 
 1157  return arrayed ? numComps + 1 : numComps;
 
 
 1170      SPIRV::lookupExtendedBuiltin(Builtin->
Name, Builtin->
Set)->Number;
 
 1177  if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2) &&
 
 1178      (
Number == SPIRV::OpenCLExtInst::fmin_common ||
 
 1179       Number == SPIRV::OpenCLExtInst::fmax_common)) {
 
 1181                 ? SPIRV::OpenCLExtInst::fmin
 
 1182                 : SPIRV::OpenCLExtInst::fmax;
 
 1190          .
addImm(
static_cast<uint32_t>(SPIRV::InstructionSet::OpenCL_std))
 
 1196  if (OrigNumber == SPIRV::OpenCLExtInst::fmin_common ||
 
 1197      OrigNumber == SPIRV::OpenCLExtInst::fmax_common) {
 
 
 1211      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 1215  std::tie(CompareRegister, RelationType) =
 
 1228                         Call->ReturnType, GR);
 
 
 1236      SPIRV::lookupGroupBuiltin(Builtin->
Name);
 
 1239  if (
Call->isSpirvOp()) {
 
 1242      if (GroupBuiltin->
Opcode ==
 
 1243              SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL &&
 
 1244          Call->Arguments.size() > 4)
 
 1253    if (!
MI || 
MI->getOpcode() != TargetOpcode::G_CONSTANT)
 
 1255          "Group Operation parameter must be an integer constant");
 
 1256    uint64_t GrpOp = 
MI->getOperand(1).getCImm()->getValue().getZExtValue();
 
 1263    for (
unsigned i = 2; i < 
Call->Arguments.size(); ++i)
 
 1276    if (ArgInstruction->
getOpcode() == TargetOpcode::G_CONSTANT) {
 
 1277      if (BoolRegType->
getOpcode() != SPIRV::OpTypeBool)
 
 1281      if (BoolRegType->
getOpcode() == SPIRV::OpTypeInt) {
 
 1283        MRI->setRegClass(Arg0, &SPIRV::iIDRegClass);
 
 1290      } 
else if (BoolRegType->
getOpcode() != SPIRV::OpTypeBool) {
 
 1302  const bool HasBoolReturnTy =
 
 1307  if (HasBoolReturnTy)
 
 1308    std::tie(GroupResultRegister, GroupResultType) =
 
 1311  auto Scope = Builtin->
Name.
starts_with(
"sub_group") ? SPIRV::Scope::Subgroup
 
 1312                                                      : SPIRV::Scope::Workgroup;
 
 1316  if (GroupBuiltin->
Opcode == SPIRV::OpGroupBroadcast &&
 
 1317      Call->Arguments.size() > 2) {
 
 1325    if (!ElemType || ElemType->
getOpcode() != SPIRV::OpTypeInt)
 
 1327    unsigned VecLen = 
Call->Arguments.size() - 1;
 
 1328    VecReg = 
MRI->createGenericVirtualRegister(
 
 1330    MRI->setRegClass(VecReg, &SPIRV::vIDRegClass);
 
 1336    for (
unsigned i = 1; i < 
Call->Arguments.size(); i++) {
 
 1337      MIB.addUse(
Call->Arguments[i]);
 
 1346                 .
addDef(GroupResultRegister)
 
 1352  if (
Call->Arguments.size() > 0) {
 
 1353    MIB.addUse(Arg0.
isValid() ? Arg0 : 
Call->Arguments[0]);
 
 1358      for (
unsigned i = 1; i < 
Call->Arguments.size(); i++)
 
 1359        MIB.addUse(
Call->Arguments[i]);
 
 1363  if (HasBoolReturnTy)
 
 1365                    Call->ReturnType, GR);
 
 
 1376      SPIRV::lookupIntelSubgroupsBuiltin(Builtin->
Name);
 
 1378  if (IntelSubgroups->
IsMedia &&
 
 1379      !ST->canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
 
 1380    std::string DiagMsg = std::string(Builtin->
Name) +
 
 1381                          ": the builtin requires the following SPIR-V " 
 1382                          "extension: SPV_INTEL_media_block_io";
 
 1384  } 
else if (!IntelSubgroups->
IsMedia &&
 
 1385             !ST->canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
 
 1386    std::string DiagMsg = std::string(Builtin->
Name) +
 
 1387                          ": the builtin requires the following SPIR-V " 
 1388                          "extension: SPV_INTEL_subgroups";
 
 1393  if (
Call->isSpirvOp()) {
 
 1394    bool IsSet = OpCode != SPIRV::OpSubgroupBlockWriteINTEL &&
 
 1395                 OpCode != SPIRV::OpSubgroupImageBlockWriteINTEL &&
 
 1396                 OpCode != SPIRV::OpSubgroupImageMediaBlockWriteINTEL;
 
 1402  if (IntelSubgroups->
IsBlock) {
 
 1405      if (Arg0Type->getOpcode() == SPIRV::OpTypeImage) {
 
 1411        case SPIRV::OpSubgroupBlockReadINTEL:
 
 1412          OpCode = SPIRV::OpSubgroupImageBlockReadINTEL;
 
 1414        case SPIRV::OpSubgroupBlockWriteINTEL:
 
 1415          OpCode = SPIRV::OpSubgroupImageBlockWriteINTEL;
 
 1438  for (
size_t i = 0; i < 
Call->Arguments.size(); ++i)
 
 
 1449  if (!ST->canUseExtension(
 
 1450          SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
 
 1451    std::string DiagMsg = std::string(Builtin->
Name) +
 
 1452                          ": the builtin requires the following SPIR-V " 
 1453                          "extension: SPV_KHR_uniform_group_instructions";
 
 1457      SPIRV::lookupGroupUniformBuiltin(Builtin->
Name);
 
 1467  if (!Const || Const->getOpcode() != TargetOpcode::G_CONSTANT)
 
 1469        "expect a constant group operation for a uniform group instruction",
 
 1472  if (!ConstOperand.
isCImm())
 
 1482  MIB.addUse(ValueReg);
 
 
 1493  if (!ST->canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock)) {
 
 1494    std::string DiagMsg = std::string(Builtin->
Name) +
 
 1495                          ": the builtin requires the following SPIR-V " 
 1496                          "extension: SPV_KHR_shader_clock";
 
 1502  if (Builtin->
Name == 
"__spirv_ReadClockKHR") {
 
 1509    SPIRV::Scope::Scope ScopeArg =
 
 1511            .
EndsWith(
"device", SPIRV::Scope::Scope::Device)
 
 1512            .
EndsWith(
"work_group", SPIRV::Scope::Scope::Workgroup)
 
 1513            .
EndsWith(
"sub_group", SPIRV::Scope::Scope::Subgroup);
 
 
 1554                              SPIRV::BuiltIn::BuiltIn BuiltinValue,
 
 1557  const unsigned ResultWidth = 
Call->ReturnType->getOperand(1).getImm();
 
 1568  bool IsConstantIndex =
 
 1569      IndexInstruction->getOpcode() == TargetOpcode::G_CONSTANT;
 
 1575    if (PointerSize != ResultWidth) {
 
 1576      DefaultReg = 
MRI->createGenericVirtualRegister(
LLT::scalar(PointerSize));
 
 1577      MRI->setRegClass(DefaultReg, &SPIRV::iIDRegClass);
 
 1579                                MIRBuilder.
getMF());
 
 1580      ToTruncate = DefaultReg;
 
 1584    MIRBuilder.
buildCopy(DefaultReg, NewRegister);
 
 1593    if (!IsConstantIndex || PointerSize != ResultWidth) {
 
 1594      Extracted = 
MRI->createGenericVirtualRegister(
LLT::scalar(PointerSize));
 
 1595      MRI->setRegClass(Extracted, &SPIRV::iIDRegClass);
 
 1602    ExtractInst.
addUse(LoadedVector).
addUse(IndexRegister);
 
 1605    if (!IsConstantIndex) {
 
 1614      MRI->setRegClass(CompareRegister, &SPIRV::iIDRegClass);
 
 1629      if (PointerSize != ResultWidth) {
 
 1632        MRI->setRegClass(SelectionResult, &SPIRV::iIDRegClass);
 
 1634                                  MIRBuilder.
getMF());
 
 1637      MIRBuilder.
buildSelect(SelectionResult, CompareRegister, Extracted,
 
 1639      ToTruncate = SelectionResult;
 
 1641      ToTruncate = Extracted;
 
 1645  if (PointerSize != ResultWidth)
 
 
 1655  SPIRV::BuiltIn::BuiltIn 
Value =
 
 1656      SPIRV::lookupGetBuiltin(Builtin->
Name, Builtin->
Set)->
Value;
 
 1658  if (
Value == SPIRV::BuiltIn::GlobalInvocationId)
 
 1664  if (
Call->ReturnType->getOpcode() == SPIRV::OpTypeVector)
 
 1671                                  LLType, 
Call->ReturnRegister);
 
 
 1680      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 1683  case SPIRV::OpStore:
 
 1685  case SPIRV::OpAtomicLoad:
 
 1687  case SPIRV::OpAtomicStore:
 
 1689  case SPIRV::OpAtomicCompareExchange:
 
 1690  case SPIRV::OpAtomicCompareExchangeWeak:
 
 1693  case SPIRV::OpAtomicIAdd:
 
 1694  case SPIRV::OpAtomicISub:
 
 1695  case SPIRV::OpAtomicOr:
 
 1696  case SPIRV::OpAtomicXor:
 
 1697  case SPIRV::OpAtomicAnd:
 
 1698  case SPIRV::OpAtomicExchange:
 
 1700  case SPIRV::OpMemoryBarrier:
 
 1702  case SPIRV::OpAtomicFlagTestAndSet:
 
 1703  case SPIRV::OpAtomicFlagClear:
 
 1706    if (
Call->isSpirvOp())
 
 
 1718  unsigned Opcode = SPIRV::lookupAtomicFloatingBuiltin(Builtin->
Name)->Opcode;
 
 1721  case SPIRV::OpAtomicFAddEXT:
 
 1722  case SPIRV::OpAtomicFMinEXT:
 
 1723  case SPIRV::OpAtomicFMaxEXT:
 
 
 1736      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 
 1747      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 1749  if (Opcode == SPIRV::OpGenericCastToPtrExplicit) {
 
 1750    SPIRV::StorageClass::StorageClass ResSC =
 
 1761    MIRBuilder.
buildInstr(TargetOpcode::G_ADDRSPACE_CAST)
 
 
 1772  if (
Call->isSpirvOp())
 
 1777               SPIRV::OpTypeVector;
 
 1779  uint32_t OC = IsVec ? SPIRV::OpDot : SPIRV::OpFMulS;
 
 1780  bool IsSwapReq = 
false;
 
 1785      (ST->canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product) ||
 
 1789        SPIRV::lookupIntegerDotProductBuiltin(Builtin->
Name);
 
 1799      bool IsFirstSigned = TypeStrs[0].trim()[0] != 
'u';
 
 1800      bool IsSecondSigned = TypeStrs[1].trim()[0] != 
'u';
 
 1802      if (
Call->BuiltinName == 
"dot") {
 
 1803        if (IsFirstSigned && IsSecondSigned)
 
 1805        else if (!IsFirstSigned && !IsSecondSigned)
 
 1808          OC = SPIRV::OpSUDot;
 
 1812      } 
else if (
Call->BuiltinName == 
"dot_acc_sat") {
 
 1813        if (IsFirstSigned && IsSecondSigned)
 
 1814          OC = SPIRV::OpSDotAccSat;
 
 1815        else if (!IsFirstSigned && !IsSecondSigned)
 
 1816          OC = SPIRV::OpUDotAccSat;
 
 1818          OC = SPIRV::OpSUDotAccSat;
 
 1834    for (
size_t i = 2; i < 
Call->Arguments.size(); ++i)
 
 1837    for (
size_t i = 0; i < 
Call->Arguments.size(); ++i)
 
 1843  if (!IsVec && OC != SPIRV::OpFMulS)
 
 1844    MIB.
addImm(SPIRV::PackedVectorFormat4x8Bit);
 
 
 1853  SPIRV::BuiltIn::BuiltIn 
Value =
 
 1854      SPIRV::lookupGetBuiltin(Builtin->
Name, Builtin->
Set)->
Value;
 
 1857  assert(
Call->ReturnType->getOpcode() == SPIRV::OpTypeInt);
 
 1861      MIRBuilder, 
Call->ReturnType, GR, 
Value, LLType, 
Call->ReturnRegister,
 
 1862       false,  std::nullopt);
 
 
 1876      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 1883  if (RetType->
getOpcode() != SPIRV::OpTypeStruct)
 
 1885                       "overflow builtins");
 
 1889  if (!OpType1 || !OpType2 || OpType1 != OpType2)
 
 1891  if (OpType1->
getOpcode() == SPIRV::OpTypeVector)
 
 1893    case SPIRV::OpIAddCarryS:
 
 1894      Opcode = SPIRV::OpIAddCarryV;
 
 1896    case SPIRV::OpISubBorrowS:
 
 1897      Opcode = SPIRV::OpISubBorrowV;
 
 1902  Register ResReg = 
MRI->createVirtualRegister(&SPIRV::iIDRegClass);
 
 1904          MRI->getRegClassOrNull(
Call->Arguments[1])) {
 
 1905    MRI->setRegClass(ResReg, DstRC);
 
 1906    MRI->setType(ResReg, 
MRI->getType(
Call->Arguments[1]));
 
 
 1924  SPIRV::BuiltIn::BuiltIn 
Value =
 
 1925      SPIRV::lookupGetBuiltin(
Call->Builtin->Name, 
Call->Builtin->Set)->
Value;
 
 1926  const bool IsDefaultOne = (
Value == SPIRV::BuiltIn::GlobalSize ||
 
 1927                             Value == SPIRV::BuiltIn::NumWorkgroups ||
 
 1928                             Value == SPIRV::BuiltIn::WorkgroupSize ||
 
 1929                             Value == SPIRV::BuiltIn::EnqueuedWorkgroupSize);
 
 
 1939      SPIRV::lookupImageQueryBuiltin(Builtin->
Name, Builtin->
Set)->Component;
 
 1943  unsigned NumExpectedRetComponents =
 
 1944      Call->ReturnType->getOpcode() == SPIRV::OpTypeVector
 
 1945          ? 
Call->ReturnType->getOperand(2).getImm()
 
 1952  if (NumExpectedRetComponents != NumActualRetComponents) {
 
 1953    unsigned Bitwidth = 
Call->ReturnType->getOpcode() == SPIRV::OpTypeInt
 
 1954                            ? 
Call->ReturnType->getOperand(1).getImm()
 
 1961        IntTy, NumActualRetComponents, MIRBuilder, 
true);
 
 1966      IsDimBuf ? SPIRV::OpImageQuerySize : SPIRV::OpImageQuerySizeLod;
 
 1973  if (NumExpectedRetComponents == NumActualRetComponents)
 
 1975  if (NumExpectedRetComponents == 1) {
 
 1977    unsigned ExtractedComposite =
 
 1978        Component == 3 ? NumActualRetComponents - 1 : Component;
 
 1979    assert(ExtractedComposite < NumActualRetComponents &&
 
 1980           "Invalid composite index!");
 
 1983    if (QueryResultType->
getOpcode() == SPIRV::OpTypeVector) {
 
 1985      if (TypeReg != NewTypeReg &&
 
 1987        TypeReg = NewTypeReg;
 
 1989    MIRBuilder.
buildInstr(SPIRV::OpCompositeExtract)
 
 1993        .
addImm(ExtractedComposite);
 
 1994    if (NewType != 
nullptr)
 
 1999    auto MIB = MIRBuilder.
buildInstr(SPIRV::OpVectorShuffle)
 
 2004    for (
unsigned i = 0; i < NumExpectedRetComponents; ++i)
 
 2005      MIB.
addImm(i < NumActualRetComponents ? i : 0xffffffff);
 
 
 2013  assert(
Call->ReturnType->getOpcode() == SPIRV::OpTypeInt &&
 
 2014         "Image samples query result must be of int type!");
 
 2019      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2022  SPIRV::Dim::Dim ImageDimensionality = 
static_cast<SPIRV::Dim::Dim
>(
 
 2024  (void)ImageDimensionality;
 
 2027  case SPIRV::OpImageQuerySamples:
 
 2028    assert(ImageDimensionality == SPIRV::Dim::DIM_2D &&
 
 2029           "Image must be of 2D dimensionality");
 
 2031  case SPIRV::OpImageQueryLevels:
 
 2032    assert((ImageDimensionality == SPIRV::Dim::DIM_1D ||
 
 2033            ImageDimensionality == SPIRV::Dim::DIM_2D ||
 
 2034            ImageDimensionality == SPIRV::Dim::DIM_3D ||
 
 2035            ImageDimensionality == SPIRV::Dim::DIM_Cube) &&
 
 2036           "Image must be of 1D/2D/3D/Cube dimensionality");
 
 
 2048static SPIRV::SamplerAddressingMode::SamplerAddressingMode
 
 2050  switch (Bitmask & SPIRV::CLK_ADDRESS_MODE_MASK) {
 
 2051  case SPIRV::CLK_ADDRESS_CLAMP:
 
 2052    return SPIRV::SamplerAddressingMode::Clamp;
 
 2053  case SPIRV::CLK_ADDRESS_CLAMP_TO_EDGE:
 
 2054    return SPIRV::SamplerAddressingMode::ClampToEdge;
 
 2055  case SPIRV::CLK_ADDRESS_REPEAT:
 
 2056    return SPIRV::SamplerAddressingMode::Repeat;
 
 2057  case SPIRV::CLK_ADDRESS_MIRRORED_REPEAT:
 
 2058    return SPIRV::SamplerAddressingMode::RepeatMirrored;
 
 2059  case SPIRV::CLK_ADDRESS_NONE:
 
 2060    return SPIRV::SamplerAddressingMode::None;
 
 
 2067  return (Bitmask & SPIRV::CLK_NORMALIZED_COORDS_TRUE) ? 1 : 0;
 
 
 2070static SPIRV::SamplerFilterMode::SamplerFilterMode
 
 2072  if (Bitmask & SPIRV::CLK_FILTER_LINEAR)
 
 2073    return SPIRV::SamplerFilterMode::Linear;
 
 2074  if (Bitmask & SPIRV::CLK_FILTER_NEAREST)
 
 2075    return SPIRV::SamplerFilterMode::Nearest;
 
 2076  return SPIRV::SamplerFilterMode::Nearest;
 
 
 2083  if (
Call->isSpirvOp())
 
 2090  if (HasOclSampler) {
 
 2104    Register SampledImage = 
MRI->createVirtualRegister(&SPIRV::iIDRegClass);
 
 2115    if (
Call->ReturnType->getOpcode() != SPIRV::OpTypeVector) {
 
 2119          MRI->createGenericVirtualRegister(GR->
getRegType(TempType));
 
 2122      MIRBuilder.
buildInstr(SPIRV::OpImageSampleExplicitLod)
 
 2127          .
addImm(SPIRV::ImageOperand::Lod)
 
 2129      MIRBuilder.
buildInstr(SPIRV::OpCompositeExtract)
 
 2135      MIRBuilder.
buildInstr(SPIRV::OpImageSampleExplicitLod)
 
 2140          .
addImm(SPIRV::ImageOperand::Lod)
 
 2143  } 
else if (HasMsaa) {
 
 2149        .
addImm(SPIRV::ImageOperand::Sample)
 
 
 2164  if (
Call->isSpirvOp())
 
 
 2179  if (
Call->Builtin->Name.contains_insensitive(
 
 2180          "__translate_sampler_initializer")) {
 
 2187    return Sampler.isValid();
 
 2188  } 
else if (
Call->Builtin->Name.contains_insensitive(
"__spirv_SampledImage")) {
 
 2195        Call->ReturnRegister.isValid()
 
 2196            ? 
Call->ReturnRegister
 
 2197            : 
MRI->createVirtualRegister(&SPIRV::iIDRegClass);
 
 2204  } 
else if (
Call->Builtin->Name.contains_insensitive(
 
 2205                 "__spirv_ImageSampleExplicitLod")) {
 
 2207    std::string ReturnType = DemangledCall.
str();
 
 2208    if (DemangledCall.
contains(
"_R")) {
 
 2209      ReturnType = ReturnType.substr(ReturnType.find(
"_R") + 2);
 
 2210      ReturnType = ReturnType.substr(0, ReturnType.find(
'('));
 
 2217      std::string DiagMsg =
 
 2218          "Unable to recognize SPIRV type name: " + ReturnType;
 
 2221    MIRBuilder.
buildInstr(SPIRV::OpImageSampleExplicitLod)
 
 2226        .
addImm(SPIRV::ImageOperand::Lod)
 
 
 2236                         Call->Arguments[1], 
Call->Arguments[2]);
 
 
 2244                              SPIRV::OpCompositeConstructContinuedINTEL,
 
 2245                              Call->Arguments, 
Call->ReturnRegister,
 
 
 2255      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2256  bool IsSet = Opcode != SPIRV::OpCooperativeMatrixStoreKHR &&
 
 2257               Opcode != SPIRV::OpCooperativeMatrixStoreCheckedINTEL &&
 
 2258               Opcode != SPIRV::OpCooperativeMatrixPrefetchINTEL;
 
 2259  unsigned ArgSz = 
Call->Arguments.size();
 
 2260  unsigned LiteralIdx = 0;
 
 2263  case SPIRV::OpCooperativeMatrixLoadKHR:
 
 2264    LiteralIdx = ArgSz > 3 ? 3 : 0;
 
 2266  case SPIRV::OpCooperativeMatrixStoreKHR:
 
 2267    LiteralIdx = ArgSz > 4 ? 4 : 0;
 
 2269  case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
 
 2270    LiteralIdx = ArgSz > 7 ? 7 : 0;
 
 2272  case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
 
 2273    LiteralIdx = ArgSz > 8 ? 8 : 0;
 
 2276  case SPIRV::OpCooperativeMatrixMulAddKHR:
 
 2277    LiteralIdx = ArgSz > 3 ? 3 : 0;
 
 2283  if (Opcode == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
 
 2285    auto MIB = MIRBuilder.
buildInstr(SPIRV::OpCooperativeMatrixPrefetchINTEL)
 
 2302  if (Opcode == SPIRV::OpCooperativeMatrixLengthKHR) {
 
 2313                            IsSet ? TypeReg : 
Register(0), ImmArgs);
 
 
 2322      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2326  case SPIRV::OpSpecConstant: {
 
 2336           (Const->getOpcode() == TargetOpcode::G_CONSTANT ||
 
 2337            Const->getOpcode() == TargetOpcode::G_FCONSTANT) &&
 
 2338           "Argument should be either an int or floating-point constant");
 
 2341    if (
Call->ReturnType->getOpcode() == SPIRV::OpTypeBool) {
 
 2342      assert(ConstOperand.
isCImm() && 
"Int constant operand is expected");
 
 2344                   ? SPIRV::OpSpecConstantTrue
 
 2345                   : SPIRV::OpSpecConstantFalse;
 
 2351    if (
Call->ReturnType->getOpcode() != SPIRV::OpTypeBool) {
 
 2352      if (Const->getOpcode() == TargetOpcode::G_CONSTANT)
 
 2359  case SPIRV::OpSpecConstantComposite: {
 
 2361                                SPIRV::OpSpecConstantCompositeContinuedINTEL,
 
 2362                                Call->Arguments, 
Call->ReturnRegister,
 
 
 2377      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 
 2388      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 
 2400      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 
 2411      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 
 2421      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2423  unsigned Scope = SPIRV::Scope::Workgroup;
 
 2425    Scope = SPIRV::Scope::Subgroup;
 
 
 2435      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2437  bool IsSet = Opcode != SPIRV::OpPredicatedStoreINTEL;
 
 2438  unsigned ArgSz = 
Call->Arguments.size();
 
 2448                            IsSet ? TypeReg : 
Register(0), ImmArgs);
 
 
 2461  Register TmpReg = 
MRI->createVirtualRegister(&SPIRV::iIDRegClass);
 
 2465  unsigned NumArgs = 
Call->Arguments.size();
 
 2467  Register GlobalWorkSize = 
Call->Arguments[NumArgs < 4 ? 1 : 2];
 
 2469      NumArgs == 2 ? 
Register(0) : 
Call->Arguments[NumArgs < 4 ? 2 : 3];
 
 2474    if (SpvTy->
getOpcode() == SPIRV::OpTypePointer) {
 
 2480      unsigned Size = 
Call->Builtin->Name == 
"ndrange_3D" ? 3 : 2;
 
 2485          FieldTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, 
true);
 
 2486      GlobalWorkSize = 
MRI->createVirtualRegister(&SPIRV::iIDRegClass);
 
 2495                                           SpvFieldTy, *ST.getInstrInfo());
 
 2500      LocalWorkSize = Const;
 
 2501    if (!GlobalWorkOffset.
isValid())
 
 2502      GlobalWorkOffset = Const;
 
 2510      .
addUse(GlobalWorkOffset);
 
 
 2524                                  SPIRV::AccessQualifier::ReadWrite, 
true);
 
 
 2532  bool IsSpirvOp = 
Call->isSpirvOp();
 
 2533  bool HasEvents = 
Call->Builtin->Name.contains(
"events") || IsSpirvOp;
 
 2540  if (
Call->Builtin->Name.contains(
"_varargs") || IsSpirvOp) {
 
 2541    const unsigned LocalSizeArrayIdx = HasEvents ? 9 : 6;
 
 2549    assert(LocalSizeTy && 
"Local size type is expected");
 
 2555        Int32Ty, MIRBuilder, SPIRV::StorageClass::Function);
 
 2556    for (
unsigned I = 0; 
I < LocalSizeNum; ++
I) {
 
 2558      MRI->setType(
Reg, LLType);
 
 2572  auto MIB = MIRBuilder.
buildInstr(SPIRV::OpEnqueueKernel)
 
 2577  const unsigned BlockFIdx = HasEvents ? 6 : 3;
 
 2578  for (
unsigned i = 0; i < BlockFIdx; i++)
 
 2579    MIB.addUse(
Call->Arguments[i]);
 
 2586    MIB.addUse(NullPtr); 
 
 2587    MIB.addUse(NullPtr); 
 
 2595  Register BlockLiteralReg = 
Call->Arguments[BlockFIdx + 1];
 
 2597  MIB.addUse(BlockLiteralReg);
 
 2607  for (
unsigned i = 0; i < LocalSizes.
size(); i++)
 
 2608    MIB.addUse(LocalSizes[i]);
 
 
 2618      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2621  case SPIRV::OpRetainEvent:
 
 2622  case SPIRV::OpReleaseEvent:
 
 2624  case SPIRV::OpCreateUserEvent:
 
 2625  case SPIRV::OpGetDefaultQueue:
 
 2629  case SPIRV::OpIsValidEvent:
 
 2634  case SPIRV::OpSetUserEventStatus:
 
 2638  case SPIRV::OpCaptureEventProfilingInfo:
 
 2643  case SPIRV::OpBuildNDRange:
 
 2645  case SPIRV::OpEnqueueKernel:
 
 
 2658      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2660  bool IsSet = Opcode == SPIRV::OpGroupAsyncCopy;
 
 2662  if (
Call->isSpirvOp())
 
 2669  case SPIRV::OpGroupAsyncCopy: {
 
 2671        Call->ReturnType->getOpcode() == SPIRV::OpTypeEvent
 
 2675    unsigned NumArgs = 
Call->Arguments.size();
 
 2685                               ? 
Call->Arguments[3]
 
 2688    if (NewType != 
nullptr)
 
 2693  case SPIRV::OpGroupWaitEvents:
 
 
 2709      SPIRV::lookupConvertBuiltin(
Call->Builtin->Name, 
Call->Builtin->Set);
 
 2711  if (!Builtin && 
Call->isSpirvOp()) {
 
 2714        SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2719  assert(Builtin && 
"Conversion builtin not found.");
 
 2722                    SPIRV::Decoration::SaturatedConversion, {});
 
 2725                    SPIRV::Decoration::FPRoundingMode,
 
 2726                    {(unsigned)Builtin->RoundingMode});
 
 2728  std::string NeedExtMsg;              
 
 2729  bool IsRightComponentsNumber = 
true; 
 
 2730  unsigned Opcode = SPIRV::OpNop;
 
 2737                                              : SPIRV::OpSatConvertSToU;
 
 2740                                              : SPIRV::OpSConvert;
 
 2742                                          SPIRV::OpTypeFloat)) {
 
 2746            &MIRBuilder.
getMF().getSubtarget());
 
 2747        if (!ST->canUseExtension(
 
 2748                SPIRV::Extension::SPV_INTEL_bfloat16_conversion))
 
 2749          NeedExtMsg = 
"SPV_INTEL_bfloat16_conversion";
 
 2750        IsRightComponentsNumber =
 
 2753        Opcode = SPIRV::OpConvertBF16ToFINTEL;
 
 2755        bool IsSourceSigned =
 
 2757        Opcode = IsSourceSigned ? SPIRV::OpConvertSToF : SPIRV::OpConvertUToF;
 
 2761                                        SPIRV::OpTypeFloat)) {
 
 2767            &MIRBuilder.
getMF().getSubtarget());
 
 2768        if (!ST->canUseExtension(
 
 2769                SPIRV::Extension::SPV_INTEL_bfloat16_conversion))
 
 2770          NeedExtMsg = 
"SPV_INTEL_bfloat16_conversion";
 
 2771        IsRightComponentsNumber =
 
 2774        Opcode = SPIRV::OpConvertFToBF16INTEL;
 
 2777                                              : SPIRV::OpConvertFToU;
 
 2780                                          SPIRV::OpTypeFloat)) {
 
 2783            &MIRBuilder.
getMF().getSubtarget());
 
 2784        if (!ST->canUseExtension(
 
 2785                SPIRV::Extension::SPV_INTEL_tensor_float32_conversion))
 
 2786          NeedExtMsg = 
"SPV_INTEL_tensor_float32_conversion";
 
 2787        IsRightComponentsNumber =
 
 2790        Opcode = SPIRV::OpRoundFToTF32INTEL;
 
 2793        Opcode = SPIRV::OpFConvert;
 
 2798  if (!NeedExtMsg.empty()) {
 
 2799    std::string DiagMsg = std::string(Builtin->
Name) +
 
 2800                          ": the builtin requires the following SPIR-V " 
 2805  if (!IsRightComponentsNumber) {
 
 2806    std::string DiagMsg =
 
 2807        std::string(Builtin->
Name) +
 
 2808        ": result and argument must have the same number of components";
 
 2811  assert(Opcode != SPIRV::OpNop &&
 
 2812         "Conversion between the types not implemented!");
 
 
 2826      SPIRV::lookupVectorLoadStoreBuiltin(
Call->Builtin->Name,
 
 2827                                          Call->Builtin->Set);
 
 2833          .
addImm(
static_cast<uint32_t>(SPIRV::InstructionSet::OpenCL_std))
 
 
 2853      SPIRV::lookupNativeBuiltin(Builtin->
Name, Builtin->
Set)->Opcode;
 
 2854  bool IsLoad = Opcode == SPIRV::OpLoad;
 
 2858    MIB.addDef(
Call->ReturnRegister);
 
 2866    MIB.addUse(
Call->Arguments[1]);
 
 2868  unsigned NumArgs = 
Call->Arguments.size();
 
 2869  if ((IsLoad && NumArgs >= 2) || NumArgs >= 3)
 
 2871  if ((IsLoad && NumArgs >= 3) || NumArgs >= 4)
 
 
 2884std::tuple<int, unsigned, unsigned>
 
 2886                   SPIRV::InstructionSet::InstructionSet Set) {
 
 2889  std::unique_ptr<const IncomingCall> 
Call =
 
 2892    return std::make_tuple(-1, 0, 0);
 
 2894  switch (
Call->Builtin->Group) {
 
 2895  case SPIRV::Relational:
 
 2897  case SPIRV::Barrier:
 
 2898  case SPIRV::CastToPtr:
 
 2899  case SPIRV::ImageMiscQuery:
 
 2900  case SPIRV::SpecConstant:
 
 2901  case SPIRV::Enqueue:
 
 2902  case SPIRV::AsyncCopy:
 
 2903  case SPIRV::LoadStore:
 
 2904  case SPIRV::CoopMatr:
 
 2906            SPIRV::lookupNativeBuiltin(
Call->Builtin->Name, 
Call->Builtin->Set))
 
 2907      return std::make_tuple(
Call->Builtin->Group, R->Opcode, 0);
 
 2909  case SPIRV::Extended:
 
 2910    if (
const auto *R = SPIRV::lookupExtendedBuiltin(
Call->Builtin->Name,
 
 2911                                                     Call->Builtin->Set))
 
 2912      return std::make_tuple(
Call->Builtin->Group, 0, R->Number);
 
 2914  case SPIRV::VectorLoadStore:
 
 2915    if (
const auto *R = SPIRV::lookupVectorLoadStoreBuiltin(
Call->Builtin->Name,
 
 2916                                                            Call->Builtin->Set))
 
 2917      return std::make_tuple(SPIRV::Extended, 0, R->Number);
 
 2920    if (
const auto *R = SPIRV::lookupGroupBuiltin(
Call->Builtin->Name))
 
 2921      return std::make_tuple(
Call->Builtin->Group, R->Opcode, 0);
 
 2923  case SPIRV::AtomicFloating:
 
 2924    if (
const auto *R = SPIRV::lookupAtomicFloatingBuiltin(
Call->Builtin->Name))
 
 2925      return std::make_tuple(
Call->Builtin->Group, R->Opcode, 0);
 
 2927  case SPIRV::IntelSubgroups:
 
 2928    if (
const auto *R = SPIRV::lookupIntelSubgroupsBuiltin(
Call->Builtin->Name))
 
 2929      return std::make_tuple(
Call->Builtin->Group, R->Opcode, 0);
 
 2931  case SPIRV::GroupUniform:
 
 2932    if (
const auto *R = SPIRV::lookupGroupUniformBuiltin(
Call->Builtin->Name))
 
 2933      return std::make_tuple(
Call->Builtin->Group, R->Opcode, 0);
 
 2935  case SPIRV::IntegerDot:
 
 2937            SPIRV::lookupIntegerDotProductBuiltin(
Call->Builtin->Name))
 
 2938      return std::make_tuple(
Call->Builtin->Group, R->Opcode, 0);
 
 2940  case SPIRV::WriteImage:
 
 2941    return std::make_tuple(
Call->Builtin->Group, SPIRV::OpImageWrite, 0);
 
 2943    return std::make_tuple(
Call->Builtin->Group, TargetOpcode::G_SELECT, 0);
 
 2944  case SPIRV::Construct:
 
 2945    return std::make_tuple(
Call->Builtin->Group, SPIRV::OpCompositeConstruct,
 
 2947  case SPIRV::KernelClock:
 
 2948    return std::make_tuple(
Call->Builtin->Group, SPIRV::OpReadClockKHR, 0);
 
 2950    return std::make_tuple(-1, 0, 0);
 
 2952  return std::make_tuple(-1, 0, 0);
 
 
 2956                                 SPIRV::InstructionSet::InstructionSet Set,
 
 2961  LLVM_DEBUG(
dbgs() << 
"Lowering builtin call: " << DemangledCall << 
"\n");
 
 2965  assert(SpvType && 
"Inconsistent return register: expected valid type info");
 
 2966  std::unique_ptr<const IncomingCall> 
Call =
 
 2971    return std::nullopt;
 
 2975  assert(Args.size() >= 
Call->Builtin->MinNumArgs &&
 
 2976         "Too few arguments to generate the builtin");
 
 2977  if (
Call->Builtin->MaxNumArgs && Args.size() > 
Call->Builtin->MaxNumArgs)
 
 2978    LLVM_DEBUG(
dbgs() << 
"More arguments provided than required!\n");
 
 2981  switch (
Call->Builtin->Group) {
 
 2982  case SPIRV::Extended:
 
 2984  case SPIRV::Relational:
 
 2988  case SPIRV::Variable:
 
 2992  case SPIRV::AtomicFloating:
 
 2994  case SPIRV::Barrier:
 
 2996  case SPIRV::CastToPtr:
 
 2999  case SPIRV::IntegerDot:
 
 3003  case SPIRV::ICarryBorrow:
 
 3005  case SPIRV::GetQuery:
 
 3007  case SPIRV::ImageSizeQuery:
 
 3009  case SPIRV::ImageMiscQuery:
 
 3011  case SPIRV::ReadImage:
 
 3013  case SPIRV::WriteImage:
 
 3015  case SPIRV::SampleImage:
 
 3019  case SPIRV::Construct:
 
 3021  case SPIRV::SpecConstant:
 
 3023  case SPIRV::Enqueue:
 
 3025  case SPIRV::AsyncCopy:
 
 3027  case SPIRV::Convert:
 
 3029  case SPIRV::VectorLoadStore:
 
 3031  case SPIRV::LoadStore:
 
 3033  case SPIRV::IntelSubgroups:
 
 3035  case SPIRV::GroupUniform:
 
 3037  case SPIRV::KernelClock:
 
 3039  case SPIRV::CoopMatr:
 
 3041  case SPIRV::ExtendedBitOps:
 
 3043  case SPIRV::BindlessINTEL:
 
 3045  case SPIRV::TernaryBitwiseINTEL:
 
 3047  case SPIRV::Block2DLoadStore:
 
 3051  case SPIRV::PredicatedLoadStore:
 
 
 3062    [[maybe_unused]] 
bool IsOCLBuiltinType = TypeStr.
consume_front(
"ocl_");
 
 3063    assert(IsOCLBuiltinType && 
"Invalid OpenCL builtin prefix");
 
 3080  unsigned VecElts = 0;
 
 3091    TypeStr = TypeStr.
substr(0, TypeStr.
find(
']'));
 
 
 3103  auto Pos1 = DemangledCall.
find(
'(');
 
 3106  auto Pos2 = DemangledCall.
find(
')');
 
 3109  DemangledCall.
slice(Pos1 + 1, Pos2)
 
 3110      .
split(BuiltinArgsTypeStrs, 
',', -1, 
false);
 
 
 3118  if (ArgIdx >= BuiltinArgsTypeStrs.
size())
 
 3120  StringRef TypeStr = BuiltinArgsTypeStrs[ArgIdx].trim();
 
 
 3129#define GET_BuiltinTypes_DECL 
 3130#define GET_BuiltinTypes_IMPL 
 3137#define GET_OpenCLTypes_DECL 
 3138#define GET_OpenCLTypes_IMPL 
 3140#include "SPIRVGenTables.inc" 
 3148  if (Name.starts_with(
"void"))
 
 3150  else if (Name.starts_with(
"int") || Name.starts_with(
"uint"))
 
 3152  else if (Name.starts_with(
"float"))
 
 3154  else if (Name.starts_with(
"half"))
 
 
 3167  unsigned Opcode = TypeRecord->
Opcode;
 
 
 3182         "Invalid number of parameters for SPIR-V pipe builtin!");
 
 3185                                   SPIRV::AccessQualifier::AccessQualifier(
 
 
 3193         "Invalid number of parameters for SPIR-V coop matrices builtin!");
 
 3195         "SPIR-V coop matrices builtin type must have a type parameter!");
 
 3198                               SPIRV::AccessQualifier::ReadWrite, 
true);
 
 3201      MIRBuilder, ExtensionType, ElemType, ExtensionType->
getIntParameter(0),
 
 
 3210      OpaqueType, SPIRV::AccessQualifier::ReadOnly, MIRBuilder);
 
 
 3219         "Inline SPIR-V type builtin takes an opcode, size, and alignment " 
 3226      if (ParamEType->getName() == 
"spirv.IntegralConstant") {
 
 3227        assert(ParamEType->getNumTypeParameters() == 1 &&
 
 3228               "Inline SPIR-V integral constant builtin must have a type " 
 3230        assert(ParamEType->getNumIntParameters() == 1 &&
 
 3231               "Inline SPIR-V integral constant builtin must have a " 
 3234        auto OperandValue = ParamEType->getIntParameter(0);
 
 3235        auto *OperandType = ParamEType->getTypeParameter(0);
 
 3238            OperandType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, 
true);
 
 3241            OperandValue, MIRBuilder, OperandSPIRVType, 
true)));
 
 3243      } 
else if (ParamEType->getName() == 
"spirv.Literal") {
 
 3244        assert(ParamEType->getNumTypeParameters() == 0 &&
 
 3245               "Inline SPIR-V literal builtin does not take type " 
 3247        assert(ParamEType->getNumIntParameters() == 1 &&
 
 3248               "Inline SPIR-V literal builtin must have an integer " 
 3251        auto OperandValue = ParamEType->getIntParameter(0);
 
 3258        Param, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, 
true);
 
 
 3270         "Vulkan buffers have exactly one type for the type of the buffer.");
 
 3272         "Vulkan buffer have 2 integer parameters: storage class and is " 
 3276  auto SC = 
static_cast<SPIRV::StorageClass::StorageClass
>(
 
 
 3291  StringRef NameWithParameters = TypeName;
 
 3298        SPIRV::lookupOpenCLType(NameWithParameters);
 
 3301                         NameWithParameters);
 
 3309         "Unknown builtin opaque type!");
 
 3313  if (!NameWithParameters.
contains(
'_'))
 
 3317  unsigned BaseNameLength = NameWithParameters.
find(
'_') - 1;
 
 3321  bool HasTypeParameter = !
isDigit(Parameters[0][0]);
 
 3322  if (HasTypeParameter)
 
 3325  for (
unsigned i = HasTypeParameter ? 1 : 0; i < Parameters.size(); i++) {
 
 3326    unsigned IntParameter = 0;
 
 3327    bool ValidLiteral = !Parameters[i].getAsInteger(10, IntParameter);
 
 3330           "Invalid format of SPIR-V builtin parameter literal!");
 
 3334                            NameWithParameters.
substr(0, BaseNameLength),
 
 3335                            TypeParameters, IntParameters);
 
 
 3339                            SPIRV::AccessQualifier::AccessQualifier AccessQual,
 
 3361  if (Name == 
"spirv.Type") {
 
 3363  } 
else if (Name == 
"spirv.VulkanBuffer") {
 
 3365  } 
else if (Name == 
"spirv.Layout") {
 
 3379    switch (TypeRecord->
Opcode) {
 
 3380    case SPIRV::OpTypeImage:
 
 3383    case SPIRV::OpTypePipe:
 
 3386    case SPIRV::OpTypeDeviceEvent:
 
 3389    case SPIRV::OpTypeSampler:
 
 3392    case SPIRV::OpTypeSampledImage:
 
 3395    case SPIRV::OpTypeCooperativeMatrixKHR:
 
 
unsigned const MachineRegisterInfo * MRI
 
MachineInstrBuilder MachineInstrBuilder & DefMI
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
AMDGPU Lower Kernel Arguments
 
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
 
Promote Memory to Register
 
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
 
static const fltSemantics & IEEEsingle()
 
APInt bitcastToAPInt() const
 
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
 
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
 
uint64_t getZExtValue() const
Get zero extended value.
 
This class represents an incoming formal argument to a Function.
 
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
 
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
 
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
 
@ ICMP_ULT
unsigned less than
 
const APFloat & getValueAPF() const
 
const APInt & getValue() const
Return the constant as an APInt value reference.
 
A parsed version of the target data layout string in and methods for querying it.
 
Tagged union holding either a T or a Error.
 
Class to represent fixed width SIMD vectors.
 
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
 
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
 
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
 
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
 
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
 
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
 
This is an important class for using LLVM in a threaded context.
 
static MCOperand createReg(MCRegister Reg)
 
static MCOperand createImm(int64_t Val)
 
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
 
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
 
Function & getFunction()
Return the LLVM function that this machine code represents.
 
Helper class to build MachineInstr.
 
LLVMContext & getContext() const
 
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
 
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
 
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
 
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef< Register > Res, bool HasSideEffects, bool isConvergent)
Build and insert a G_INTRINSIC instruction.
 
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
 
MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
 
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
 
MachineFunction & getMF()
Getter for the function we currently build.
 
MachineRegisterInfo * getMRI()
Getter for MRI.
 
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
 
const DataLayout & getDataLayout() const
 
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
 
Register getReg(unsigned Idx) const
Get the register for the operand index.
 
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
 
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
 
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
 
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
 
Representation of each machine instruction.
 
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
 
LLVM_ABI void copyIRFlags(const Instruction &I)
Copy all flags to MachineInst MIFlags.
 
const MachineOperand & getOperand(unsigned i) const
 
MachineOperand class - Representation of each machine instruction operand.
 
const GlobalValue * getGlobal() const
 
const ConstantInt * getCImm() const
 
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
 
bool isReg() const
isReg - Tests if this is a MO_Register operand.
 
const MDNode * getMetadata() const
 
Register getReg() const
getReg - Returns the register number.
 
const ConstantFP * getFPImm() const
 
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
 
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
 
LLVM_ABI void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
 
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
 
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
 
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
 
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
 
Wrapper class representing virtual and physical registers.
 
constexpr bool isValid() const
 
SPIRVType * getOrCreateOpTypePipe(MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AccQual)
 
SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
 
SPIRVType * getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder, bool EmitIR)
 
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
 
Register buildGlobalVariable(Register Reg, SPIRVType *BaseType, StringRef Name, const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage, const MachineInstr *Init, bool IsConst, const std::optional< SPIRV::LinkageType::LinkageType > &LinkageType, MachineIRBuilder &MIRBuilder, bool IsInstSelector)
 
const Type * getTypeForSPIRVType(const SPIRVType *Ty) const
 
SPIRVType * getOrCreateUnknownType(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode, const ArrayRef< MCOperand > Operands)
 
unsigned getScalarOrVectorComponentCount(Register VReg) const
 
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
 
unsigned getPointerSize() const
 
SPIRVType * getOrCreateSPIRVPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC)
 
SPIRVType * getOrCreateOpTypeByOpcode(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode)
 
Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType=nullptr)
 
SPIRVType * getPointeeType(SPIRVType *PtrType)
 
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
 
bool isScalarOfType(Register VReg, unsigned TypeOpcode) const
 
SPIRVType * getOrCreateOpTypeSampledImage(SPIRVType *ImageType, MachineIRBuilder &MIRBuilder)
 
SPIRVType * getOrCreateVulkanBufferType(MachineIRBuilder &MIRBuilder, Type *ElemType, SPIRV::StorageClass::StorageClass SC, bool IsWritable, bool EmitIr=false)
 
SPIRVType * getOrCreateSPIRVTypeByName(StringRef TypeStr, MachineIRBuilder &MIRBuilder, bool EmitIR, SPIRV::StorageClass::StorageClass SC=SPIRV::StorageClass::Function, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite)
 
SPIRVType * getOrCreateLayoutType(MachineIRBuilder &MIRBuilder, const TargetExtType *T, bool EmitIr=false)
 
Register getOrCreateConsIntVector(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR)
 
const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const
 
SPIRVType * getOrCreateSPIRVVectorType(SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder, bool EmitIR)
 
SPIRVType * getOrCreateOpTypeCoopMatr(MachineIRBuilder &MIRBuilder, const TargetExtType *ExtensionType, const SPIRVType *ElemType, uint32_t Scope, uint32_t Rows, uint32_t Columns, uint32_t Use, bool EmitIR)
 
bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const
 
Register getOrCreateConstIntArray(uint64_t Val, size_t Num, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII)
 
SPIRVType * getOrCreateOpTypeDeviceEvent(MachineIRBuilder &MIRBuilder)
 
SPIRVType * getImageType(const TargetExtType *ExtensionType, const SPIRV::AccessQualifier::AccessQualifier Qualifier, MachineIRBuilder &MIRBuilder)
 
SPIRVType * getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
 
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR, bool ZeroAsNull=true)
 
LLT getRegType(SPIRVType *SpvType) const
 
SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const
 
SPIRVType * getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder)
 
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param, unsigned FilerMode, MachineIRBuilder &MIRBuilder)
 
Register getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder, SPIRVType *SpvType)
 
unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const
 
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
 
void push_back(const T &Elt)
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
StringRef - Represent a constant reference to a string, i.e.
 
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
 
static constexpr size_t npos
 
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
 
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
 
std::string str() const
str - Get the contents as an std::string.
 
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
 
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
 
bool contains_insensitive(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
 
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
 
constexpr size_t size() const
size - Get the string size.
 
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
 
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
 
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
 
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
 
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
 
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
 
A switch()-like statement whose cases are string literals.
 
StringSwitch & EndsWith(StringLiteral S, T Value)
 
Class to represent struct types.
 
Class to represent target extensions types, which are generally unintrospectable from target-independ...
 
ArrayRef< Type * > type_params() const
Return the type parameters for this particular target extension type.
 
unsigned getNumIntParameters() const
 
static LLVM_ABI TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types={}, ArrayRef< unsigned > Ints={})
Return a target extension type having the specified name and optional type and integer parameters.
 
Type * getTypeParameter(unsigned i) const
 
unsigned getNumTypeParameters() const
 
unsigned getIntParameter(unsigned i) const
 
The instances of the Type class are immutable: once they are created, they are never changed.
 
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
 
LLVM_ABI StringRef getStructName() const
 
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
 
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
 
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
 
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
 
LLVM Value Representation.
 
LLVM_ABI Value(Type *Ty, unsigned scid)
 
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
 
Represents a version number in the form major[.minor[.subminor[.build]]].
 
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
 
LLVM_C_ABI LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount)
Create a vector type that contains a defined type and has a specific number of elements.
 
std::string lookupBuiltinNameHelper(StringRef DemangledCall, FPDecorationId *DecorationId)
Parses the name part of the demangled builtin call.
 
Type * parseBuiltinCallArgumentType(StringRef TypeStr, LLVMContext &Ctx)
 
bool parseBuiltinTypeStr(SmallVector< StringRef, 10 > &BuiltinArgsTypeStrs, const StringRef DemangledCall, LLVMContext &Ctx)
 
std::optional< bool > lowerBuiltin(const StringRef DemangledCall, SPIRV::InstructionSet::InstructionSet Set, MachineIRBuilder &MIRBuilder, const Register OrigRet, const Type *OrigRetTy, const SmallVectorImpl< Register > &Args, SPIRVGlobalRegistry *GR, const CallBase &CB)
 
std::tuple< int, unsigned, unsigned > mapBuiltinToOpcode(const StringRef DemangledCall, SPIRV::InstructionSet::InstructionSet Set)
Helper function for finding a builtin function attributes by a demangled function name.
 
Type * parseBuiltinCallArgumentBaseType(const StringRef DemangledCall, unsigned ArgIdx, LLVMContext &Ctx)
Parses the provided ArgIdx argument base type in the DemangledCall skeleton.
 
TargetExtType * parseBuiltinTypeNameToTargetExtType(std::string TypeName, LLVMContext &Context)
Translates a string representing a SPIR-V or OpenCL builtin type to a TargetExtType that can be furth...
 
SPIRVType * lowerBuiltinType(const Type *OpaqueType, SPIRV::AccessQualifier::AccessQualifier AccessQual, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
This is an optimization pass for GlobalISel generic memory operations.
 
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
 
static bool build2DBlockIOINTELInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building Intel's 2d block io instructions.
 
static SPIRVType * getVulkanBufferType(const TargetExtType *ExtensionType, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateExtInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR, const CallBase &CB)
 
void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
Helper external function for inserting ASSIGN_TYPE instuction between Reg and its definition,...
 
static bool generateBindlessImageINTELInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateGetQueryInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateLoadStoreInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static SPIRVType * getInlineSpirvType(const TargetExtType *ExtensionType, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateConstructInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool buildAtomicFlagInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building atomic flag instructions (e.g.
 
static bool generateImageSizeQueryInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static SPIRV::SamplerFilterMode::SamplerFilterMode getSamplerFilterModeFromBitmask(unsigned Bitmask)
 
static bool buildAtomicStoreInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building an atomic store instruction.
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
 
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
 
static bool buildExtendedBitOpsInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building extended bit operations.
 
static const Type * getBlockStructType(Register ParamReg, MachineRegisterInfo *MRI)
 
static bool generateGroupInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
FPDecorationId demangledPostfixToDecorationId(const std::string &S)
 
static unsigned getNumComponentsForDim(SPIRV::Dim::Dim dim)
 
static bool generateICarryBorrowInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static Register buildScopeReg(Register CLScopeRegister, SPIRV::Scope::Scope Scope, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI)
 
static std::tuple< Register, SPIRVType * > buildBoolRegister(MachineIRBuilder &MIRBuilder, const SPIRVType *ResultType, SPIRVGlobalRegistry *GR)
Helper function building either a resulting scalar or vector bool register depending on the expected ...
 
static unsigned getNumSizeComponents(SPIRVType *imgType)
Helper function for obtaining the number of size components.
 
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI)
 
static Register buildConstantIntReg32(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static SPIRVType * getSampledImageType(const TargetExtType *OpaqueType, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
SmallVector< MachineInstr *, 4 > createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode, unsigned MinWC, unsigned ContinuedOpcode, ArrayRef< Register > Args, Register ReturnRegister, Register TypeID)
 
SPIRV::MemorySemantics::MemorySemantics getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC)
 
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
 
static bool generateSampleImageInst(const StringRef DemangledCall, const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateBarrierInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
LLVM_ABI void SplitString(StringRef Source, SmallVectorImpl< StringRef > &OutFragments, StringRef Delimiters=" \t\n\v\f\r")
SplitString - Split up the specified string according to the specified delimiters,...
 
static SPIRVType * getCoopMatrType(const TargetExtType *ExtensionType, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateKernelClockInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static void setRegClassIfNull(Register Reg, MachineRegisterInfo *MRI, SPIRVGlobalRegistry *GR)
 
static bool generateGroupUniformInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateWaveInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
 
Register createVirtualRegister(SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF)
 
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
 
static bool buildBarrierInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building barriers, i.e., memory/control ordering operations.
 
static bool generateAsyncCopy(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static SPIRV::Scope::Scope getSPIRVScope(SPIRV::CLMemoryScope ClScope)
 
static SPIRVType * getSamplerType(MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
static Register buildLoadInst(SPIRVType *BaseType, Register PtrRegister, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR, LLT LowLevelType, Register DestinationReg=Register(0))
Helper function for building a load instruction loading into the DestinationReg.
 
static bool generateEnqueueInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
 
static bool buildSelectInst(MachineIRBuilder &MIRBuilder, Register ReturnRegister, Register SourceRegister, const SPIRVType *ReturnType, SPIRVGlobalRegistry *GR)
Helper function for building either a vector or scalar select instruction depending on the expected R...
 
static const Type * getMachineInstrType(MachineInstr *MI)
 
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
 
static SPIRV::SamplerAddressingMode::SamplerAddressingMode getSamplerAddressingModeFromBitmask(unsigned Bitmask)
 
static bool generateAtomicInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
const MachineInstr SPIRVType
 
static SPIRVType * getLayoutType(const TargetExtType *ExtensionType, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateDotOrFMulInst(const StringRef DemangledCall, const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static Register buildBuiltinVariableLoad(MachineIRBuilder &MIRBuilder, SPIRVType *VariableType, SPIRVGlobalRegistry *GR, SPIRV::BuiltIn::BuiltIn BuiltinValue, LLT LLType, Register Reg=Register(0), bool isConst=true, const std::optional< SPIRV::LinkageType::LinkageType > &LinkageTy={ SPIRV::LinkageType::Import})
Helper function for building a load instruction for loading a builtin global variable of BuiltinValue...
 
static bool generateConvertInst(const StringRef DemangledCall, const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateTernaryBitwiseFunctionINTELInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateCastToPtrInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
constexpr bool isGenericCastablePtr(SPIRV::StorageClass::StorageClass SC)
 
static Register buildMemSemanticsReg(Register SemanticsRegister, Register PtrRegister, unsigned &Semantics, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static unsigned getConstFromIntrinsic(Register Reg, MachineRegisterInfo *MRI)
 
static bool generateImageMiscQueryInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateSelectInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder)
 
static bool buildAtomicLoadInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building an atomic load instruction.
 
static bool generateIntelSubgroupsInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateExtendedBitOpsInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool buildPipeInst(const SPIRV::IncomingCall *Call, unsigned Opcode, unsigned Scope, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateSpecConstantInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static SPIRVType * getOrCreateSPIRVDeviceEventPointer(MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
 
static bool generateVectorLoadStoreInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool genWorkgroupQuery(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR, SPIRV::BuiltIn::BuiltIn BuiltinValue, uint64_t DefaultValue)
 
static bool generateCoopMatrInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool buildBindlessImageINTELInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building Intel's bindless image instructions.
 
static std::unique_ptr< const SPIRV::IncomingCall > lookupBuiltin(StringRef DemangledCall, SPIRV::InstructionSet::InstructionSet Set, Register ReturnRegister, const SPIRVType *ReturnType, const SmallVectorImpl< Register > &Arguments)
Looks up the demangled builtin call in the SPIRVBuiltins.td records using the provided DemangledCall ...
 
static bool buildAtomicFloatingRMWInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building an atomic floating-type instruction.
 
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
 
constexpr unsigned BitWidth
 
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
 
static bool generate2DBlockIOINTELInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateReadImageInst(const StringRef DemangledCall, const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
bool hasBuiltinTypePrefix(StringRef Name)
 
static bool buildEnqueueKernel(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
Type * getMDOperandAsType(const MDNode *N, unsigned I)
 
static bool generatePipeInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool buildTernaryBitwiseFunctionINTELInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building Intel's OpBitwiseFunctionINTEL instruction.
 
static bool buildAtomicRMWInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building atomic instructions.
 
static SPIRV::MemorySemantics::MemorySemantics getSPIRVMemSemantics(std::memory_order MemOrder)
 
static bool generateRelationalInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool buildAtomicInitInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder)
Helper function for translating atomic init to OpStore.
 
static bool generateWriteImageInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static SPIRVType * getPipeType(const TargetExtType *ExtensionType, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static Type * parseTypeString(const StringRef Name, LLVMContext &Context)
 
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
 
static bool generatePredicatedLoadStoreInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool generateAtomicFloatingInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static bool buildNDRange(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static SPIRVType * getNonParameterizedType(const TargetExtType *ExtensionType, const SPIRV::BuiltinType *TypeRecord, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
static MachineInstr * getBlockStructInstr(Register ParamReg, MachineRegisterInfo *MRI)
 
static bool buildOpFromWrapper(MachineIRBuilder &MIRBuilder, unsigned Opcode, const SPIRV::IncomingCall *Call, Register TypeReg, ArrayRef< uint32_t > ImmArgs={})
 
static unsigned getSamplerParamFromBitmask(unsigned Bitmask)
 
static bool buildAtomicCompareExchangeInst(const SPIRV::IncomingCall *Call, const SPIRV::DemangledBuiltin *Builtin, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
Helper function for building an atomic compare-exchange instruction.
 
std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue)
 
static bool generateBuiltinVar(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
 
Implement std::hash so that hash_code can be used in STL containers.
 
This struct is a compact representation of a valid (non-zero power of two) alignment.
 
This class contains a discriminated union of information about pointers in memory operands,...
 
FPRoundingMode::FPRoundingMode RoundingMode
 
InstructionSet::InstructionSet Set
 
InstructionSet::InstructionSet Set
 
InstructionSet::InstructionSet Set
 
InstructionSet::InstructionSet Set
 
const SmallVectorImpl< Register > & Arguments
 
const std::string BuiltinName
 
const SPIRVType * ReturnType
 
const Register ReturnRegister
 
const DemangledBuiltin * Builtin
 
IncomingCall(const std::string BuiltinName, const DemangledBuiltin *Builtin, const Register ReturnRegister, const SPIRVType *ReturnType, const SmallVectorImpl< Register > &Arguments)
 
InstructionSet::InstructionSet Set
 
StringRef SpirvTypeLiteral
 
InstructionSet::InstructionSet Set
 
FPRoundingMode::FPRoundingMode RoundingMode