xref: /llvm-project/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (revision 21edac25f09faee23015c6a69d95fcbda287efe2)
1 //===- SPIRVInstructionSelector.cpp ------------------------------*- 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 the targeting of the InstructionSelector class for
10 // SPIRV.
11 // TODO: This should be generated by TableGen.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "MCTargetDesc/SPIRVBaseInfo.h"
16 #include "MCTargetDesc/SPIRVMCTargetDesc.h"
17 #include "SPIRV.h"
18 #include "SPIRVGlobalRegistry.h"
19 #include "SPIRVInstrInfo.h"
20 #include "SPIRVRegisterBankInfo.h"
21 #include "SPIRVRegisterInfo.h"
22 #include "SPIRVTargetMachine.h"
23 #include "SPIRVUtils.h"
24 #include "llvm/ADT/APFloat.h"
25 #include "llvm/ADT/StringExtras.h"
26 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
27 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
28 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
29 #include "llvm/CodeGen/MachineInstrBuilder.h"
30 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
31 #include "llvm/CodeGen/MachineRegisterInfo.h"
32 #include "llvm/CodeGen/Register.h"
33 #include "llvm/CodeGen/TargetOpcodes.h"
34 #include "llvm/IR/IntrinsicsSPIRV.h"
35 #include "llvm/Support/Debug.h"
36 
37 #define DEBUG_TYPE "spirv-isel"
38 
39 using namespace llvm;
40 namespace CL = SPIRV::OpenCLExtInst;
41 namespace GL = SPIRV::GLSLExtInst;
42 
43 using ExtInstList =
44     std::vector<std::pair<SPIRV::InstructionSet::InstructionSet, uint32_t>>;
45 
46 namespace {
47 
48 #define GET_GLOBALISEL_PREDICATE_BITSET
49 #include "SPIRVGenGlobalISel.inc"
50 #undef GET_GLOBALISEL_PREDICATE_BITSET
51 
52 class SPIRVInstructionSelector : public InstructionSelector {
53   const SPIRVSubtarget &STI;
54   const SPIRVInstrInfo &TII;
55   const SPIRVRegisterInfo &TRI;
56   const RegisterBankInfo &RBI;
57   SPIRVGlobalRegistry &GR;
58   MachineRegisterInfo *MRI;
59   MachineFunction *HasVRegsReset = nullptr;
60 
61   /// We need to keep track of the number we give to anonymous global values to
62   /// generate the same name every time when this is needed.
63   mutable DenseMap<const GlobalValue *, unsigned> UnnamedGlobalIDs;
64   SmallPtrSet<MachineInstr *, 8> DeadMIs;
65 
66 public:
67   SPIRVInstructionSelector(const SPIRVTargetMachine &TM,
68                            const SPIRVSubtarget &ST,
69                            const RegisterBankInfo &RBI);
70   void setupMF(MachineFunction &MF, GISelKnownBits *KB,
71                CodeGenCoverage *CoverageInfo, ProfileSummaryInfo *PSI,
72                BlockFrequencyInfo *BFI) override;
73   // Common selection code. Instruction-specific selection occurs in spvSelect.
74   bool select(MachineInstr &I) override;
75   static const char *getName() { return DEBUG_TYPE; }
76 
77 #define GET_GLOBALISEL_PREDICATES_DECL
78 #include "SPIRVGenGlobalISel.inc"
79 #undef GET_GLOBALISEL_PREDICATES_DECL
80 
81 #define GET_GLOBALISEL_TEMPORARIES_DECL
82 #include "SPIRVGenGlobalISel.inc"
83 #undef GET_GLOBALISEL_TEMPORARIES_DECL
84 
85 private:
86   void resetVRegsType(MachineFunction &MF);
87 
88   // tblgen-erated 'select' implementation, used as the initial selector for
89   // the patterns that don't require complex C++.
90   bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
91 
92   // All instruction-specific selection that didn't happen in "select()".
93   // Is basically a large Switch/Case delegating to all other select method.
94   bool spvSelect(Register ResVReg, const SPIRVType *ResType,
95                  MachineInstr &I) const;
96 
97   bool selectFirstBitHigh(Register ResVReg, const SPIRVType *ResType,
98                           MachineInstr &I, bool IsSigned) const;
99 
100   bool selectFirstBitHigh16(Register ResVReg, const SPIRVType *ResType,
101                             MachineInstr &I, bool IsSigned) const;
102 
103   bool selectFirstBitHigh32(Register ResVReg, const SPIRVType *ResType,
104                             MachineInstr &I, Register SrcReg,
105                             bool IsSigned) const;
106 
107   bool selectFirstBitHigh64(Register ResVReg, const SPIRVType *ResType,
108                             MachineInstr &I, bool IsSigned) const;
109 
110   bool selectGlobalValue(Register ResVReg, MachineInstr &I,
111                          const MachineInstr *Init = nullptr) const;
112 
113   bool selectOpWithSrcs(Register ResVReg, const SPIRVType *ResType,
114                         MachineInstr &I, std::vector<Register> SrcRegs,
115                         unsigned Opcode) const;
116 
117   bool selectUnOp(Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
118                   unsigned Opcode) const;
119 
120   bool selectBitcast(Register ResVReg, const SPIRVType *ResType,
121                      MachineInstr &I) const;
122 
123   bool selectLoad(Register ResVReg, const SPIRVType *ResType,
124                   MachineInstr &I) const;
125   bool selectStore(MachineInstr &I) const;
126 
127   bool selectStackSave(Register ResVReg, const SPIRVType *ResType,
128                        MachineInstr &I) const;
129   bool selectStackRestore(MachineInstr &I) const;
130 
131   bool selectMemOperation(Register ResVReg, MachineInstr &I) const;
132 
133   bool selectAtomicRMW(Register ResVReg, const SPIRVType *ResType,
134                        MachineInstr &I, unsigned NewOpcode,
135                        unsigned NegateOpcode = 0) const;
136 
137   bool selectAtomicCmpXchg(Register ResVReg, const SPIRVType *ResType,
138                            MachineInstr &I) const;
139 
140   bool selectFence(MachineInstr &I) const;
141 
142   bool selectAddrSpaceCast(Register ResVReg, const SPIRVType *ResType,
143                            MachineInstr &I) const;
144 
145   bool selectAnyOrAll(Register ResVReg, const SPIRVType *ResType,
146                       MachineInstr &I, unsigned OpType) const;
147 
148   bool selectAll(Register ResVReg, const SPIRVType *ResType,
149                  MachineInstr &I) const;
150 
151   bool selectAny(Register ResVReg, const SPIRVType *ResType,
152                  MachineInstr &I) const;
153 
154   bool selectBitreverse(Register ResVReg, const SPIRVType *ResType,
155                         MachineInstr &I) const;
156 
157   bool selectBuildVector(Register ResVReg, const SPIRVType *ResType,
158                          MachineInstr &I) const;
159   bool selectSplatVector(Register ResVReg, const SPIRVType *ResType,
160                          MachineInstr &I) const;
161 
162   bool selectCmp(Register ResVReg, const SPIRVType *ResType,
163                  unsigned comparisonOpcode, MachineInstr &I) const;
164   bool selectCross(Register ResVReg, const SPIRVType *ResType,
165                    MachineInstr &I) const;
166   bool selectDiscard(Register ResVReg, const SPIRVType *ResType,
167                      MachineInstr &I) const;
168 
169   bool selectICmp(Register ResVReg, const SPIRVType *ResType,
170                   MachineInstr &I) const;
171   bool selectFCmp(Register ResVReg, const SPIRVType *ResType,
172                   MachineInstr &I) const;
173 
174   bool selectSign(Register ResVReg, const SPIRVType *ResType,
175                   MachineInstr &I) const;
176 
177   bool selectFloatDot(Register ResVReg, const SPIRVType *ResType,
178                       MachineInstr &I) const;
179 
180   bool selectOverflowArith(Register ResVReg, const SPIRVType *ResType,
181                            MachineInstr &I, unsigned Opcode) const;
182 
183   bool selectIntegerDot(Register ResVReg, const SPIRVType *ResType,
184                         MachineInstr &I, bool Signed) const;
185 
186   bool selectIntegerDotExpansion(Register ResVReg, const SPIRVType *ResType,
187                                  MachineInstr &I) const;
188 
189   template <bool Signed>
190   bool selectDot4AddPacked(Register ResVReg, const SPIRVType *ResType,
191                            MachineInstr &I) const;
192   template <bool Signed>
193   bool selectDot4AddPackedExpansion(Register ResVReg, const SPIRVType *ResType,
194                                     MachineInstr &I) const;
195 
196   void renderImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
197                    int OpIdx) const;
198   void renderFImm64(MachineInstrBuilder &MIB, const MachineInstr &I,
199                     int OpIdx) const;
200 
201   bool selectConst(Register ResVReg, const SPIRVType *ResType, const APInt &Imm,
202                    MachineInstr &I) const;
203 
204   bool selectSelect(Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
205                     bool IsSigned) const;
206   bool selectIToF(Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
207                   bool IsSigned, unsigned Opcode) const;
208   bool selectExt(Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
209                  bool IsSigned) const;
210 
211   bool selectTrunc(Register ResVReg, const SPIRVType *ResType,
212                    MachineInstr &I) const;
213 
214   bool selectSUCmp(Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
215                    bool IsSigned) const;
216 
217   bool selectIntToBool(Register IntReg, Register ResVReg, MachineInstr &I,
218                        const SPIRVType *intTy, const SPIRVType *boolTy) const;
219 
220   bool selectOpUndef(Register ResVReg, const SPIRVType *ResType,
221                      MachineInstr &I) const;
222   bool selectFreeze(Register ResVReg, const SPIRVType *ResType,
223                     MachineInstr &I) const;
224   bool selectIntrinsic(Register ResVReg, const SPIRVType *ResType,
225                        MachineInstr &I) const;
226   bool selectExtractVal(Register ResVReg, const SPIRVType *ResType,
227                         MachineInstr &I) const;
228   bool selectInsertVal(Register ResVReg, const SPIRVType *ResType,
229                        MachineInstr &I) const;
230   bool selectExtractElt(Register ResVReg, const SPIRVType *ResType,
231                         MachineInstr &I) const;
232   bool selectInsertElt(Register ResVReg, const SPIRVType *ResType,
233                        MachineInstr &I) const;
234   bool selectGEP(Register ResVReg, const SPIRVType *ResType,
235                  MachineInstr &I) const;
236 
237   bool selectFrameIndex(Register ResVReg, const SPIRVType *ResType,
238                         MachineInstr &I) const;
239   bool selectAllocaArray(Register ResVReg, const SPIRVType *ResType,
240                          MachineInstr &I) const;
241 
242   bool selectBranch(MachineInstr &I) const;
243   bool selectBranchCond(MachineInstr &I) const;
244 
245   bool selectPhi(Register ResVReg, const SPIRVType *ResType,
246                  MachineInstr &I) const;
247 
248   [[maybe_unused]] bool selectExtInst(Register ResVReg,
249                                       const SPIRVType *RestType,
250                                       MachineInstr &I,
251                                       GL::GLSLExtInst GLInst) const;
252   bool selectExtInst(Register ResVReg, const SPIRVType *ResType,
253                      MachineInstr &I, CL::OpenCLExtInst CLInst) const;
254   bool selectExtInst(Register ResVReg, const SPIRVType *ResType,
255                      MachineInstr &I, CL::OpenCLExtInst CLInst,
256                      GL::GLSLExtInst GLInst) const;
257   bool selectExtInst(Register ResVReg, const SPIRVType *ResType,
258                      MachineInstr &I, const ExtInstList &ExtInsts) const;
259 
260   bool selectLog10(Register ResVReg, const SPIRVType *ResType,
261                    MachineInstr &I) const;
262 
263   bool selectSaturate(Register ResVReg, const SPIRVType *ResType,
264                       MachineInstr &I) const;
265 
266   bool selectWaveOpInst(Register ResVReg, const SPIRVType *ResType,
267                         MachineInstr &I, unsigned Opcode) const;
268 
269   bool selectWaveActiveCountBits(Register ResVReg, const SPIRVType *ResType,
270                                  MachineInstr &I) const;
271 
272   bool selectUnmergeValues(MachineInstr &I) const;
273 
274   bool selectHandleFromBinding(Register &ResVReg, const SPIRVType *ResType,
275                                MachineInstr &I) const;
276 
277   void selectReadImageIntrinsic(Register &ResVReg, const SPIRVType *ResType,
278                                 MachineInstr &I) const;
279 
280   void selectImageWriteIntrinsic(MachineInstr &I) const;
281 
282   // Utilities
283   std::pair<Register, bool>
284   buildI32Constant(uint32_t Val, MachineInstr &I,
285                    const SPIRVType *ResType = nullptr) const;
286 
287   Register buildZerosVal(const SPIRVType *ResType, MachineInstr &I) const;
288   Register buildZerosValF(const SPIRVType *ResType, MachineInstr &I) const;
289   Register buildOnesVal(bool AllOnes, const SPIRVType *ResType,
290                         MachineInstr &I) const;
291   Register buildOnesValF(const SPIRVType *ResType, MachineInstr &I) const;
292 
293   bool wrapIntoSpecConstantOp(MachineInstr &I,
294                               SmallVector<Register> &CompositeArgs) const;
295 
296   Register getUcharPtrTypeReg(MachineInstr &I,
297                               SPIRV::StorageClass::StorageClass SC) const;
298   MachineInstrBuilder buildSpecConstantOp(MachineInstr &I, Register Dest,
299                                           Register Src, Register DestType,
300                                           uint32_t Opcode) const;
301   MachineInstrBuilder buildConstGenericPtr(MachineInstr &I, Register SrcPtr,
302                                            SPIRVType *SrcPtrTy) const;
303   Register buildPointerToResource(const SPIRVType *ResType, uint32_t Set,
304                                   uint32_t Binding, uint32_t ArraySize,
305                                   Register IndexReg, bool IsNonUniform,
306                                   MachineIRBuilder MIRBuilder) const;
307   SPIRVType *widenTypeToVec4(const SPIRVType *Type, MachineInstr &I) const;
308   void extractSubvector(Register &ResVReg, const SPIRVType *ResType,
309                         Register &ReadReg, MachineInstr &InsertionPoint) const;
310   bool BuildCOPY(Register DestReg, Register SrcReg, MachineInstr &I) const;
311   bool loadVec3BuiltinInputID(SPIRV::BuiltIn::BuiltIn BuiltInValue,
312                               Register ResVReg, const SPIRVType *ResType,
313                               MachineInstr &I) const;
314 };
315 
316 } // end anonymous namespace
317 
318 #define GET_GLOBALISEL_IMPL
319 #include "SPIRVGenGlobalISel.inc"
320 #undef GET_GLOBALISEL_IMPL
321 
322 SPIRVInstructionSelector::SPIRVInstructionSelector(const SPIRVTargetMachine &TM,
323                                                    const SPIRVSubtarget &ST,
324                                                    const RegisterBankInfo &RBI)
325     : InstructionSelector(), STI(ST), TII(*ST.getInstrInfo()),
326       TRI(*ST.getRegisterInfo()), RBI(RBI), GR(*ST.getSPIRVGlobalRegistry()),
327 #define GET_GLOBALISEL_PREDICATES_INIT
328 #include "SPIRVGenGlobalISel.inc"
329 #undef GET_GLOBALISEL_PREDICATES_INIT
330 #define GET_GLOBALISEL_TEMPORARIES_INIT
331 #include "SPIRVGenGlobalISel.inc"
332 #undef GET_GLOBALISEL_TEMPORARIES_INIT
333 {
334 }
335 
336 void SPIRVInstructionSelector::setupMF(MachineFunction &MF, GISelKnownBits *KB,
337                                        CodeGenCoverage *CoverageInfo,
338                                        ProfileSummaryInfo *PSI,
339                                        BlockFrequencyInfo *BFI) {
340   MRI = &MF.getRegInfo();
341   GR.setCurrentFunc(MF);
342   InstructionSelector::setupMF(MF, KB, CoverageInfo, PSI, BFI);
343 }
344 
345 // Ensure that register classes correspond to pattern matching rules.
346 void SPIRVInstructionSelector::resetVRegsType(MachineFunction &MF) {
347   if (HasVRegsReset == &MF)
348     return;
349   HasVRegsReset = &MF;
350 
351   MachineRegisterInfo &MRI = MF.getRegInfo();
352   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
353     Register Reg = Register::index2VirtReg(I);
354     LLT RegType = MRI.getType(Reg);
355     if (RegType.isScalar())
356       MRI.setType(Reg, LLT::scalar(64));
357     else if (RegType.isPointer())
358       MRI.setType(Reg, LLT::pointer(0, 64));
359     else if (RegType.isVector())
360       MRI.setType(Reg, LLT::fixed_vector(2, LLT::scalar(64)));
361   }
362   for (const auto &MBB : MF) {
363     for (const auto &MI : MBB) {
364       if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
365         continue;
366       Register DstReg = MI.getOperand(0).getReg();
367       LLT DstType = MRI.getType(DstReg);
368       Register SrcReg = MI.getOperand(1).getReg();
369       LLT SrcType = MRI.getType(SrcReg);
370       if (DstType != SrcType)
371         MRI.setType(DstReg, MRI.getType(SrcReg));
372 
373       const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
374       const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
375       if (DstRC != SrcRC && SrcRC)
376         MRI.setRegClass(DstReg, SrcRC);
377     }
378   }
379 }
380 
381 static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI);
382 
383 // Defined in SPIRVLegalizerInfo.cpp.
384 extern bool isTypeFoldingSupported(unsigned Opcode);
385 
386 bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI) {
387   for (const auto &MO : MI.all_defs()) {
388     Register Reg = MO.getReg();
389     if (Reg.isPhysical() || !MRI.use_nodbg_empty(Reg))
390       return false;
391   }
392   if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE || MI.isFakeUse() ||
393       MI.isLifetimeMarker())
394     return false;
395   if (MI.isPHI())
396     return true;
397   if (MI.mayStore() || MI.isCall() ||
398       (MI.mayLoad() && MI.hasOrderedMemoryRef()) || MI.isPosition() ||
399       MI.isDebugInstr() || MI.isTerminator() || MI.isJumpTableDebugInfo())
400     return false;
401   return true;
402 }
403 
404 bool SPIRVInstructionSelector::select(MachineInstr &I) {
405   resetVRegsType(*I.getParent()->getParent());
406 
407   assert(I.getParent() && "Instruction should be in a basic block!");
408   assert(I.getParent()->getParent() && "Instruction should be in a function!");
409 
410   Register Opcode = I.getOpcode();
411   // If it's not a GMIR instruction, we've selected it already.
412   if (!isPreISelGenericOpcode(Opcode)) {
413     if (Opcode == SPIRV::ASSIGN_TYPE) { // These pseudos aren't needed any more.
414       Register DstReg = I.getOperand(0).getReg();
415       Register SrcReg = I.getOperand(1).getReg();
416       auto *Def = MRI->getVRegDef(SrcReg);
417       if (isTypeFoldingSupported(Def->getOpcode())) {
418         bool Res = selectImpl(I, *CoverageInfo);
419         LLVM_DEBUG({
420           if (!Res && Def->getOpcode() != TargetOpcode::G_CONSTANT) {
421             dbgs() << "Unexpected pattern in ASSIGN_TYPE.\nInstruction: ";
422             I.print(dbgs());
423           }
424         });
425         assert(Res || Def->getOpcode() == TargetOpcode::G_CONSTANT);
426         if (Res) {
427           if (!isTriviallyDead(*Def, *MRI) && isDead(*Def, *MRI))
428             DeadMIs.insert(Def);
429           return Res;
430         }
431       }
432       MRI->setRegClass(SrcReg, MRI->getRegClass(DstReg));
433       MRI->replaceRegWith(SrcReg, DstReg);
434       GR.invalidateMachineInstr(&I);
435       I.removeFromParent();
436       return true;
437     } else if (I.getNumDefs() == 1) {
438       // Make all vregs 64 bits (for SPIR-V IDs).
439       MRI->setType(I.getOperand(0).getReg(), LLT::scalar(64));
440     }
441     return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
442   }
443 
444   if (DeadMIs.contains(&I)) {
445     // if the instruction has been already made dead by folding it away
446     // erase it
447     LLVM_DEBUG(dbgs() << "Instruction is folded and dead.\n");
448     salvageDebugInfo(*MRI, I);
449     GR.invalidateMachineInstr(&I);
450     I.eraseFromParent();
451     return true;
452   }
453 
454   if (I.getNumOperands() != I.getNumExplicitOperands()) {
455     LLVM_DEBUG(errs() << "Generic instr has unexpected implicit operands\n");
456     return false;
457   }
458 
459   // Common code for getting return reg+type, and removing selected instr
460   // from parent occurs here. Instr-specific selection happens in spvSelect().
461   bool HasDefs = I.getNumDefs() > 0;
462   Register ResVReg = HasDefs ? I.getOperand(0).getReg() : Register(0);
463   SPIRVType *ResType = HasDefs ? GR.getSPIRVTypeForVReg(ResVReg) : nullptr;
464   assert(!HasDefs || ResType || I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE);
465   if (spvSelect(ResVReg, ResType, I)) {
466     if (HasDefs) // Make all vregs 64 bits (for SPIR-V IDs).
467       for (unsigned i = 0; i < I.getNumDefs(); ++i)
468         MRI->setType(I.getOperand(i).getReg(), LLT::scalar(64));
469     GR.invalidateMachineInstr(&I);
470     I.removeFromParent();
471     return true;
472   }
473   return false;
474 }
475 
476 static bool mayApplyGenericSelection(unsigned Opcode) {
477   switch (Opcode) {
478   case TargetOpcode::G_CONSTANT:
479     return false;
480   case TargetOpcode::G_SADDO:
481   case TargetOpcode::G_SSUBO:
482     return true;
483   }
484   return isTypeFoldingSupported(Opcode);
485 }
486 
487 bool SPIRVInstructionSelector::BuildCOPY(Register DestReg, Register SrcReg,
488                                          MachineInstr &I) const {
489   const TargetRegisterClass *DstRC = MRI->getRegClassOrNull(DestReg);
490   const TargetRegisterClass *SrcRC = MRI->getRegClassOrNull(SrcReg);
491   if (DstRC != SrcRC && SrcRC)
492     MRI->setRegClass(DestReg, SrcRC);
493   return BuildMI(*I.getParent(), I, I.getDebugLoc(),
494                  TII.get(TargetOpcode::COPY))
495       .addDef(DestReg)
496       .addUse(SrcReg)
497       .constrainAllUses(TII, TRI, RBI);
498 }
499 
500 bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
501                                          const SPIRVType *ResType,
502                                          MachineInstr &I) const {
503   const unsigned Opcode = I.getOpcode();
504   if (mayApplyGenericSelection(Opcode))
505     return selectImpl(I, *CoverageInfo);
506   switch (Opcode) {
507   case TargetOpcode::G_CONSTANT:
508     return selectConst(ResVReg, ResType, I.getOperand(1).getCImm()->getValue(),
509                        I);
510   case TargetOpcode::G_GLOBAL_VALUE:
511     return selectGlobalValue(ResVReg, I);
512   case TargetOpcode::G_IMPLICIT_DEF:
513     return selectOpUndef(ResVReg, ResType, I);
514   case TargetOpcode::G_FREEZE:
515     return selectFreeze(ResVReg, ResType, I);
516 
517   case TargetOpcode::G_INTRINSIC:
518   case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
519   case TargetOpcode::G_INTRINSIC_CONVERGENT:
520   case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
521     return selectIntrinsic(ResVReg, ResType, I);
522   case TargetOpcode::G_BITREVERSE:
523     return selectBitreverse(ResVReg, ResType, I);
524 
525   case TargetOpcode::G_BUILD_VECTOR:
526     return selectBuildVector(ResVReg, ResType, I);
527   case TargetOpcode::G_SPLAT_VECTOR:
528     return selectSplatVector(ResVReg, ResType, I);
529 
530   case TargetOpcode::G_SHUFFLE_VECTOR: {
531     MachineBasicBlock &BB = *I.getParent();
532     auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpVectorShuffle))
533                    .addDef(ResVReg)
534                    .addUse(GR.getSPIRVTypeID(ResType))
535                    .addUse(I.getOperand(1).getReg())
536                    .addUse(I.getOperand(2).getReg());
537     for (auto V : I.getOperand(3).getShuffleMask())
538       MIB.addImm(V);
539     return MIB.constrainAllUses(TII, TRI, RBI);
540   }
541   case TargetOpcode::G_MEMMOVE:
542   case TargetOpcode::G_MEMCPY:
543   case TargetOpcode::G_MEMSET:
544     return selectMemOperation(ResVReg, I);
545 
546   case TargetOpcode::G_ICMP:
547     return selectICmp(ResVReg, ResType, I);
548   case TargetOpcode::G_FCMP:
549     return selectFCmp(ResVReg, ResType, I);
550 
551   case TargetOpcode::G_FRAME_INDEX:
552     return selectFrameIndex(ResVReg, ResType, I);
553 
554   case TargetOpcode::G_LOAD:
555     return selectLoad(ResVReg, ResType, I);
556   case TargetOpcode::G_STORE:
557     return selectStore(I);
558 
559   case TargetOpcode::G_BR:
560     return selectBranch(I);
561   case TargetOpcode::G_BRCOND:
562     return selectBranchCond(I);
563 
564   case TargetOpcode::G_PHI:
565     return selectPhi(ResVReg, ResType, I);
566 
567   case TargetOpcode::G_FPTOSI:
568     return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertFToS);
569   case TargetOpcode::G_FPTOUI:
570     return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertFToU);
571 
572   case TargetOpcode::G_SITOFP:
573     return selectIToF(ResVReg, ResType, I, true, SPIRV::OpConvertSToF);
574   case TargetOpcode::G_UITOFP:
575     return selectIToF(ResVReg, ResType, I, false, SPIRV::OpConvertUToF);
576 
577   case TargetOpcode::G_CTPOP:
578     return selectUnOp(ResVReg, ResType, I, SPIRV::OpBitCount);
579   case TargetOpcode::G_SMIN:
580     return selectExtInst(ResVReg, ResType, I, CL::s_min, GL::SMin);
581   case TargetOpcode::G_UMIN:
582     return selectExtInst(ResVReg, ResType, I, CL::u_min, GL::UMin);
583 
584   case TargetOpcode::G_SMAX:
585     return selectExtInst(ResVReg, ResType, I, CL::s_max, GL::SMax);
586   case TargetOpcode::G_UMAX:
587     return selectExtInst(ResVReg, ResType, I, CL::u_max, GL::UMax);
588 
589   case TargetOpcode::G_SCMP:
590     return selectSUCmp(ResVReg, ResType, I, true);
591   case TargetOpcode::G_UCMP:
592     return selectSUCmp(ResVReg, ResType, I, false);
593 
594   case TargetOpcode::G_STRICT_FMA:
595   case TargetOpcode::G_FMA:
596     return selectExtInst(ResVReg, ResType, I, CL::fma, GL::Fma);
597 
598   case TargetOpcode::G_STRICT_FLDEXP:
599     return selectExtInst(ResVReg, ResType, I, CL::ldexp);
600 
601   case TargetOpcode::G_FPOW:
602     return selectExtInst(ResVReg, ResType, I, CL::pow, GL::Pow);
603   case TargetOpcode::G_FPOWI:
604     return selectExtInst(ResVReg, ResType, I, CL::pown);
605 
606   case TargetOpcode::G_FEXP:
607     return selectExtInst(ResVReg, ResType, I, CL::exp, GL::Exp);
608   case TargetOpcode::G_FEXP2:
609     return selectExtInst(ResVReg, ResType, I, CL::exp2, GL::Exp2);
610 
611   case TargetOpcode::G_FLOG:
612     return selectExtInst(ResVReg, ResType, I, CL::log, GL::Log);
613   case TargetOpcode::G_FLOG2:
614     return selectExtInst(ResVReg, ResType, I, CL::log2, GL::Log2);
615   case TargetOpcode::G_FLOG10:
616     return selectLog10(ResVReg, ResType, I);
617 
618   case TargetOpcode::G_FABS:
619     return selectExtInst(ResVReg, ResType, I, CL::fabs, GL::FAbs);
620   case TargetOpcode::G_ABS:
621     return selectExtInst(ResVReg, ResType, I, CL::s_abs, GL::SAbs);
622 
623   case TargetOpcode::G_FMINNUM:
624   case TargetOpcode::G_FMINIMUM:
625     return selectExtInst(ResVReg, ResType, I, CL::fmin, GL::NMin);
626   case TargetOpcode::G_FMAXNUM:
627   case TargetOpcode::G_FMAXIMUM:
628     return selectExtInst(ResVReg, ResType, I, CL::fmax, GL::NMax);
629 
630   case TargetOpcode::G_FCOPYSIGN:
631     return selectExtInst(ResVReg, ResType, I, CL::copysign);
632 
633   case TargetOpcode::G_FCEIL:
634     return selectExtInst(ResVReg, ResType, I, CL::ceil, GL::Ceil);
635   case TargetOpcode::G_FFLOOR:
636     return selectExtInst(ResVReg, ResType, I, CL::floor, GL::Floor);
637 
638   case TargetOpcode::G_FCOS:
639     return selectExtInst(ResVReg, ResType, I, CL::cos, GL::Cos);
640   case TargetOpcode::G_FSIN:
641     return selectExtInst(ResVReg, ResType, I, CL::sin, GL::Sin);
642   case TargetOpcode::G_FTAN:
643     return selectExtInst(ResVReg, ResType, I, CL::tan, GL::Tan);
644   case TargetOpcode::G_FACOS:
645     return selectExtInst(ResVReg, ResType, I, CL::acos, GL::Acos);
646   case TargetOpcode::G_FASIN:
647     return selectExtInst(ResVReg, ResType, I, CL::asin, GL::Asin);
648   case TargetOpcode::G_FATAN:
649     return selectExtInst(ResVReg, ResType, I, CL::atan, GL::Atan);
650   case TargetOpcode::G_FATAN2:
651     return selectExtInst(ResVReg, ResType, I, CL::atan2, GL::Atan2);
652   case TargetOpcode::G_FCOSH:
653     return selectExtInst(ResVReg, ResType, I, CL::cosh, GL::Cosh);
654   case TargetOpcode::G_FSINH:
655     return selectExtInst(ResVReg, ResType, I, CL::sinh, GL::Sinh);
656   case TargetOpcode::G_FTANH:
657     return selectExtInst(ResVReg, ResType, I, CL::tanh, GL::Tanh);
658 
659   case TargetOpcode::G_STRICT_FSQRT:
660   case TargetOpcode::G_FSQRT:
661     return selectExtInst(ResVReg, ResType, I, CL::sqrt, GL::Sqrt);
662 
663   case TargetOpcode::G_CTTZ:
664   case TargetOpcode::G_CTTZ_ZERO_UNDEF:
665     return selectExtInst(ResVReg, ResType, I, CL::ctz);
666   case TargetOpcode::G_CTLZ:
667   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
668     return selectExtInst(ResVReg, ResType, I, CL::clz);
669 
670   case TargetOpcode::G_INTRINSIC_ROUND:
671     return selectExtInst(ResVReg, ResType, I, CL::round, GL::Round);
672   case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
673     return selectExtInst(ResVReg, ResType, I, CL::rint, GL::RoundEven);
674   case TargetOpcode::G_INTRINSIC_TRUNC:
675     return selectExtInst(ResVReg, ResType, I, CL::trunc, GL::Trunc);
676   case TargetOpcode::G_FRINT:
677   case TargetOpcode::G_FNEARBYINT:
678     return selectExtInst(ResVReg, ResType, I, CL::rint, GL::RoundEven);
679 
680   case TargetOpcode::G_SMULH:
681     return selectExtInst(ResVReg, ResType, I, CL::s_mul_hi);
682   case TargetOpcode::G_UMULH:
683     return selectExtInst(ResVReg, ResType, I, CL::u_mul_hi);
684 
685   case TargetOpcode::G_SADDSAT:
686     return selectExtInst(ResVReg, ResType, I, CL::s_add_sat);
687   case TargetOpcode::G_UADDSAT:
688     return selectExtInst(ResVReg, ResType, I, CL::u_add_sat);
689   case TargetOpcode::G_SSUBSAT:
690     return selectExtInst(ResVReg, ResType, I, CL::s_sub_sat);
691   case TargetOpcode::G_USUBSAT:
692     return selectExtInst(ResVReg, ResType, I, CL::u_sub_sat);
693 
694   case TargetOpcode::G_UADDO:
695     return selectOverflowArith(ResVReg, ResType, I,
696                                ResType->getOpcode() == SPIRV::OpTypeVector
697                                    ? SPIRV::OpIAddCarryV
698                                    : SPIRV::OpIAddCarryS);
699   case TargetOpcode::G_USUBO:
700     return selectOverflowArith(ResVReg, ResType, I,
701                                ResType->getOpcode() == SPIRV::OpTypeVector
702                                    ? SPIRV::OpISubBorrowV
703                                    : SPIRV::OpISubBorrowS);
704   case TargetOpcode::G_UMULO:
705     return selectOverflowArith(ResVReg, ResType, I, SPIRV::OpUMulExtended);
706   case TargetOpcode::G_SMULO:
707     return selectOverflowArith(ResVReg, ResType, I, SPIRV::OpSMulExtended);
708 
709   case TargetOpcode::G_SEXT:
710     return selectExt(ResVReg, ResType, I, true);
711   case TargetOpcode::G_ANYEXT:
712   case TargetOpcode::G_ZEXT:
713     return selectExt(ResVReg, ResType, I, false);
714   case TargetOpcode::G_TRUNC:
715     return selectTrunc(ResVReg, ResType, I);
716   case TargetOpcode::G_FPTRUNC:
717   case TargetOpcode::G_FPEXT:
718     return selectUnOp(ResVReg, ResType, I, SPIRV::OpFConvert);
719 
720   case TargetOpcode::G_PTRTOINT:
721     return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertPtrToU);
722   case TargetOpcode::G_INTTOPTR:
723     return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertUToPtr);
724   case TargetOpcode::G_BITCAST:
725     return selectBitcast(ResVReg, ResType, I);
726   case TargetOpcode::G_ADDRSPACE_CAST:
727     return selectAddrSpaceCast(ResVReg, ResType, I);
728   case TargetOpcode::G_PTR_ADD: {
729     // Currently, we get G_PTR_ADD only applied to global variables.
730     assert(I.getOperand(1).isReg() && I.getOperand(2).isReg());
731     Register GV = I.getOperand(1).getReg();
732     MachineRegisterInfo::def_instr_iterator II = MRI->def_instr_begin(GV);
733     (void)II;
734     assert(((*II).getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
735             (*II).getOpcode() == TargetOpcode::COPY ||
736             (*II).getOpcode() == SPIRV::OpVariable) &&
737            isImm(I.getOperand(2), MRI));
738     // It may be the initialization of a global variable.
739     bool IsGVInit = false;
740     for (MachineRegisterInfo::use_instr_iterator
741              UseIt = MRI->use_instr_begin(I.getOperand(0).getReg()),
742              UseEnd = MRI->use_instr_end();
743          UseIt != UseEnd; UseIt = std::next(UseIt)) {
744       if ((*UseIt).getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
745           (*UseIt).getOpcode() == SPIRV::OpVariable) {
746         IsGVInit = true;
747         break;
748       }
749     }
750     MachineBasicBlock &BB = *I.getParent();
751     if (!IsGVInit) {
752       SPIRVType *GVType = GR.getSPIRVTypeForVReg(GV);
753       SPIRVType *GVPointeeType = GR.getPointeeType(GVType);
754       SPIRVType *ResPointeeType = GR.getPointeeType(ResType);
755       if (GVPointeeType && ResPointeeType && GVPointeeType != ResPointeeType) {
756         // Build a new virtual register that is associated with the required
757         // data type.
758         Register NewVReg = MRI->createGenericVirtualRegister(MRI->getType(GV));
759         MRI->setRegClass(NewVReg, MRI->getRegClass(GV));
760         //  Having a correctly typed base we are ready to build the actually
761         //  required GEP. It may not be a constant though, because all Operands
762         //  of OpSpecConstantOp is to originate from other const instructions,
763         //  and only the AccessChain named opcodes accept a global OpVariable
764         //  instruction. We can't use an AccessChain opcode because of the type
765         //  mismatch between result and base types.
766         if (!GR.isBitcastCompatible(ResType, GVType))
767           report_fatal_error(
768               "incompatible result and operand types in a bitcast");
769         Register ResTypeReg = GR.getSPIRVTypeID(ResType);
770         MachineInstrBuilder MIB =
771             BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitcast))
772                 .addDef(NewVReg)
773                 .addUse(ResTypeReg)
774                 .addUse(GV);
775         return MIB.constrainAllUses(TII, TRI, RBI) &&
776                BuildMI(BB, I, I.getDebugLoc(),
777                        TII.get(STI.isVulkanEnv()
778                                    ? SPIRV::OpInBoundsAccessChain
779                                    : SPIRV::OpInBoundsPtrAccessChain))
780                    .addDef(ResVReg)
781                    .addUse(ResTypeReg)
782                    .addUse(NewVReg)
783                    .addUse(I.getOperand(2).getReg())
784                    .constrainAllUses(TII, TRI, RBI);
785       } else {
786         return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSpecConstantOp))
787             .addDef(ResVReg)
788             .addUse(GR.getSPIRVTypeID(ResType))
789             .addImm(
790                 static_cast<uint32_t>(SPIRV::Opcode::InBoundsPtrAccessChain))
791             .addUse(GV)
792             .addUse(I.getOperand(2).getReg())
793             .constrainAllUses(TII, TRI, RBI);
794       }
795     }
796     // It's possible to translate G_PTR_ADD to OpSpecConstantOp: either to
797     // initialize a global variable with a constant expression (e.g., the test
798     // case opencl/basic/progvar_prog_scope_init.ll), or for another use case
799     Register Idx = buildZerosVal(GR.getOrCreateSPIRVIntegerType(32, I, TII), I);
800     auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSpecConstantOp))
801                    .addDef(ResVReg)
802                    .addUse(GR.getSPIRVTypeID(ResType))
803                    .addImm(static_cast<uint32_t>(
804                        SPIRV::Opcode::InBoundsPtrAccessChain))
805                    .addUse(GV)
806                    .addUse(Idx)
807                    .addUse(I.getOperand(2).getReg());
808     return MIB.constrainAllUses(TII, TRI, RBI);
809   }
810 
811   case TargetOpcode::G_ATOMICRMW_OR:
812     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicOr);
813   case TargetOpcode::G_ATOMICRMW_ADD:
814     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicIAdd);
815   case TargetOpcode::G_ATOMICRMW_AND:
816     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicAnd);
817   case TargetOpcode::G_ATOMICRMW_MAX:
818     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicSMax);
819   case TargetOpcode::G_ATOMICRMW_MIN:
820     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicSMin);
821   case TargetOpcode::G_ATOMICRMW_SUB:
822     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicISub);
823   case TargetOpcode::G_ATOMICRMW_XOR:
824     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicXor);
825   case TargetOpcode::G_ATOMICRMW_UMAX:
826     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicUMax);
827   case TargetOpcode::G_ATOMICRMW_UMIN:
828     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicUMin);
829   case TargetOpcode::G_ATOMICRMW_XCHG:
830     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicExchange);
831   case TargetOpcode::G_ATOMIC_CMPXCHG:
832     return selectAtomicCmpXchg(ResVReg, ResType, I);
833 
834   case TargetOpcode::G_ATOMICRMW_FADD:
835     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicFAddEXT);
836   case TargetOpcode::G_ATOMICRMW_FSUB:
837     // Translate G_ATOMICRMW_FSUB to OpAtomicFAddEXT with negative value operand
838     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicFAddEXT,
839                            SPIRV::OpFNegate);
840   case TargetOpcode::G_ATOMICRMW_FMIN:
841     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicFMinEXT);
842   case TargetOpcode::G_ATOMICRMW_FMAX:
843     return selectAtomicRMW(ResVReg, ResType, I, SPIRV::OpAtomicFMaxEXT);
844 
845   case TargetOpcode::G_FENCE:
846     return selectFence(I);
847 
848   case TargetOpcode::G_STACKSAVE:
849     return selectStackSave(ResVReg, ResType, I);
850   case TargetOpcode::G_STACKRESTORE:
851     return selectStackRestore(I);
852 
853   case TargetOpcode::G_UNMERGE_VALUES:
854     return selectUnmergeValues(I);
855 
856   // Discard gen opcodes for intrinsics which we do not expect to actually
857   // represent code after lowering or intrinsics which are not implemented but
858   // should not crash when found in a customer's LLVM IR input.
859   case TargetOpcode::G_TRAP:
860   case TargetOpcode::G_DEBUGTRAP:
861   case TargetOpcode::G_UBSANTRAP:
862   case TargetOpcode::DBG_LABEL:
863     return true;
864 
865   default:
866     return false;
867   }
868 }
869 
870 bool SPIRVInstructionSelector::selectExtInst(Register ResVReg,
871                                              const SPIRVType *ResType,
872                                              MachineInstr &I,
873                                              GL::GLSLExtInst GLInst) const {
874   return selectExtInst(ResVReg, ResType, I,
875                        {{SPIRV::InstructionSet::GLSL_std_450, GLInst}});
876 }
877 
878 bool SPIRVInstructionSelector::selectExtInst(Register ResVReg,
879                                              const SPIRVType *ResType,
880                                              MachineInstr &I,
881                                              CL::OpenCLExtInst CLInst) const {
882   return selectExtInst(ResVReg, ResType, I,
883                        {{SPIRV::InstructionSet::OpenCL_std, CLInst}});
884 }
885 
886 bool SPIRVInstructionSelector::selectExtInst(Register ResVReg,
887                                              const SPIRVType *ResType,
888                                              MachineInstr &I,
889                                              CL::OpenCLExtInst CLInst,
890                                              GL::GLSLExtInst GLInst) const {
891   ExtInstList ExtInsts = {{SPIRV::InstructionSet::OpenCL_std, CLInst},
892                           {SPIRV::InstructionSet::GLSL_std_450, GLInst}};
893   return selectExtInst(ResVReg, ResType, I, ExtInsts);
894 }
895 
896 bool SPIRVInstructionSelector::selectExtInst(Register ResVReg,
897                                              const SPIRVType *ResType,
898                                              MachineInstr &I,
899                                              const ExtInstList &Insts) const {
900 
901   for (const auto &Ex : Insts) {
902     SPIRV::InstructionSet::InstructionSet Set = Ex.first;
903     uint32_t Opcode = Ex.second;
904     if (STI.canUseExtInstSet(Set)) {
905       MachineBasicBlock &BB = *I.getParent();
906       auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst))
907                      .addDef(ResVReg)
908                      .addUse(GR.getSPIRVTypeID(ResType))
909                      .addImm(static_cast<uint32_t>(Set))
910                      .addImm(Opcode);
911       const unsigned NumOps = I.getNumOperands();
912       unsigned Index = 1;
913       if (Index < NumOps &&
914           I.getOperand(Index).getType() ==
915               MachineOperand::MachineOperandType::MO_IntrinsicID)
916         Index = 2;
917       for (; Index < NumOps; ++Index)
918         MIB.add(I.getOperand(Index));
919       return MIB.constrainAllUses(TII, TRI, RBI);
920     }
921   }
922   return false;
923 }
924 
925 bool SPIRVInstructionSelector::selectOpWithSrcs(Register ResVReg,
926                                                 const SPIRVType *ResType,
927                                                 MachineInstr &I,
928                                                 std::vector<Register> Srcs,
929                                                 unsigned Opcode) const {
930   auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode))
931                  .addDef(ResVReg)
932                  .addUse(GR.getSPIRVTypeID(ResType));
933   for (Register SReg : Srcs) {
934     MIB.addUse(SReg);
935   }
936   return MIB.constrainAllUses(TII, TRI, RBI);
937 }
938 
939 bool SPIRVInstructionSelector::selectUnOp(Register ResVReg,
940                                           const SPIRVType *ResType,
941                                           MachineInstr &I,
942                                           unsigned Opcode) const {
943   if (STI.isOpenCLEnv() && I.getOperand(1).isReg()) {
944     Register SrcReg = I.getOperand(1).getReg();
945     bool IsGV = false;
946     for (MachineRegisterInfo::def_instr_iterator DefIt =
947              MRI->def_instr_begin(SrcReg);
948          DefIt != MRI->def_instr_end(); DefIt = std::next(DefIt)) {
949       if ((*DefIt).getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
950         IsGV = true;
951         break;
952       }
953     }
954     if (IsGV) {
955       uint32_t SpecOpcode = 0;
956       switch (Opcode) {
957       case SPIRV::OpConvertPtrToU:
958         SpecOpcode = static_cast<uint32_t>(SPIRV::Opcode::ConvertPtrToU);
959         break;
960       case SPIRV::OpConvertUToPtr:
961         SpecOpcode = static_cast<uint32_t>(SPIRV::Opcode::ConvertUToPtr);
962         break;
963       }
964       if (SpecOpcode)
965         return BuildMI(*I.getParent(), I, I.getDebugLoc(),
966                        TII.get(SPIRV::OpSpecConstantOp))
967             .addDef(ResVReg)
968             .addUse(GR.getSPIRVTypeID(ResType))
969             .addImm(SpecOpcode)
970             .addUse(SrcReg)
971             .constrainAllUses(TII, TRI, RBI);
972     }
973   }
974   return selectOpWithSrcs(ResVReg, ResType, I, {I.getOperand(1).getReg()},
975                           Opcode);
976 }
977 
978 bool SPIRVInstructionSelector::selectBitcast(Register ResVReg,
979                                              const SPIRVType *ResType,
980                                              MachineInstr &I) const {
981   Register OpReg = I.getOperand(1).getReg();
982   SPIRVType *OpType = OpReg.isValid() ? GR.getSPIRVTypeForVReg(OpReg) : nullptr;
983   if (!GR.isBitcastCompatible(ResType, OpType))
984     report_fatal_error("incompatible result and operand types in a bitcast");
985   return selectUnOp(ResVReg, ResType, I, SPIRV::OpBitcast);
986 }
987 
988 static void addMemoryOperands(MachineMemOperand *MemOp,
989                               MachineInstrBuilder &MIB) {
990   uint32_t SpvMemOp = static_cast<uint32_t>(SPIRV::MemoryOperand::None);
991   if (MemOp->isVolatile())
992     SpvMemOp |= static_cast<uint32_t>(SPIRV::MemoryOperand::Volatile);
993   if (MemOp->isNonTemporal())
994     SpvMemOp |= static_cast<uint32_t>(SPIRV::MemoryOperand::Nontemporal);
995   if (MemOp->getAlign().value())
996     SpvMemOp |= static_cast<uint32_t>(SPIRV::MemoryOperand::Aligned);
997 
998   if (SpvMemOp != static_cast<uint32_t>(SPIRV::MemoryOperand::None)) {
999     MIB.addImm(SpvMemOp);
1000     if (SpvMemOp & static_cast<uint32_t>(SPIRV::MemoryOperand::Aligned))
1001       MIB.addImm(MemOp->getAlign().value());
1002   }
1003 }
1004 
1005 static void addMemoryOperands(uint64_t Flags, MachineInstrBuilder &MIB) {
1006   uint32_t SpvMemOp = static_cast<uint32_t>(SPIRV::MemoryOperand::None);
1007   if (Flags & MachineMemOperand::Flags::MOVolatile)
1008     SpvMemOp |= static_cast<uint32_t>(SPIRV::MemoryOperand::Volatile);
1009   if (Flags & MachineMemOperand::Flags::MONonTemporal)
1010     SpvMemOp |= static_cast<uint32_t>(SPIRV::MemoryOperand::Nontemporal);
1011 
1012   if (SpvMemOp != static_cast<uint32_t>(SPIRV::MemoryOperand::None))
1013     MIB.addImm(SpvMemOp);
1014 }
1015 
1016 bool SPIRVInstructionSelector::selectLoad(Register ResVReg,
1017                                           const SPIRVType *ResType,
1018                                           MachineInstr &I) const {
1019   unsigned OpOffset = isa<GIntrinsic>(I) ? 1 : 0;
1020   Register Ptr = I.getOperand(1 + OpOffset).getReg();
1021   auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpLoad))
1022                  .addDef(ResVReg)
1023                  .addUse(GR.getSPIRVTypeID(ResType))
1024                  .addUse(Ptr);
1025   if (!I.getNumMemOperands()) {
1026     assert(I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS ||
1027            I.getOpcode() ==
1028                TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS);
1029     addMemoryOperands(I.getOperand(2 + OpOffset).getImm(), MIB);
1030   } else {
1031     addMemoryOperands(*I.memoperands_begin(), MIB);
1032   }
1033   return MIB.constrainAllUses(TII, TRI, RBI);
1034 }
1035 
1036 bool SPIRVInstructionSelector::selectStore(MachineInstr &I) const {
1037   unsigned OpOffset = isa<GIntrinsic>(I) ? 1 : 0;
1038   Register StoreVal = I.getOperand(0 + OpOffset).getReg();
1039   Register Ptr = I.getOperand(1 + OpOffset).getReg();
1040   MachineBasicBlock &BB = *I.getParent();
1041   auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpStore))
1042                  .addUse(Ptr)
1043                  .addUse(StoreVal);
1044   if (!I.getNumMemOperands()) {
1045     assert(I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS ||
1046            I.getOpcode() ==
1047                TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS);
1048     addMemoryOperands(I.getOperand(2 + OpOffset).getImm(), MIB);
1049   } else {
1050     addMemoryOperands(*I.memoperands_begin(), MIB);
1051   }
1052   return MIB.constrainAllUses(TII, TRI, RBI);
1053 }
1054 
1055 bool SPIRVInstructionSelector::selectStackSave(Register ResVReg,
1056                                                const SPIRVType *ResType,
1057                                                MachineInstr &I) const {
1058   if (!STI.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array))
1059     report_fatal_error(
1060         "llvm.stacksave intrinsic: this instruction requires the following "
1061         "SPIR-V extension: SPV_INTEL_variable_length_array",
1062         false);
1063   MachineBasicBlock &BB = *I.getParent();
1064   return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSaveMemoryINTEL))
1065       .addDef(ResVReg)
1066       .addUse(GR.getSPIRVTypeID(ResType))
1067       .constrainAllUses(TII, TRI, RBI);
1068 }
1069 
1070 bool SPIRVInstructionSelector::selectStackRestore(MachineInstr &I) const {
1071   if (!STI.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array))
1072     report_fatal_error(
1073         "llvm.stackrestore intrinsic: this instruction requires the following "
1074         "SPIR-V extension: SPV_INTEL_variable_length_array",
1075         false);
1076   if (!I.getOperand(0).isReg())
1077     return false;
1078   MachineBasicBlock &BB = *I.getParent();
1079   return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpRestoreMemoryINTEL))
1080       .addUse(I.getOperand(0).getReg())
1081       .constrainAllUses(TII, TRI, RBI);
1082 }
1083 
1084 bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
1085                                                   MachineInstr &I) const {
1086   MachineBasicBlock &BB = *I.getParent();
1087   Register SrcReg = I.getOperand(1).getReg();
1088   bool Result = true;
1089   if (I.getOpcode() == TargetOpcode::G_MEMSET) {
1090     assert(I.getOperand(1).isReg() && I.getOperand(2).isReg());
1091     unsigned Val = getIConstVal(I.getOperand(1).getReg(), MRI);
1092     unsigned Num = getIConstVal(I.getOperand(2).getReg(), MRI);
1093     SPIRVType *ValTy = GR.getOrCreateSPIRVIntegerType(8, I, TII);
1094     SPIRVType *ArrTy = GR.getOrCreateSPIRVArrayType(ValTy, Num, I, TII);
1095     Register Const = GR.getOrCreateConstIntArray(Val, Num, I, ArrTy, TII);
1096     SPIRVType *VarTy = GR.getOrCreateSPIRVPointerType(
1097         ArrTy, I, TII, SPIRV::StorageClass::UniformConstant);
1098     // TODO: check if we have such GV, add init, use buildGlobalVariable.
1099     Function &CurFunction = GR.CurMF->getFunction();
1100     Type *LLVMArrTy =
1101         ArrayType::get(IntegerType::get(CurFunction.getContext(), 8), Num);
1102     // Module takes ownership of the global var.
1103     GlobalVariable *GV = new GlobalVariable(*CurFunction.getParent(), LLVMArrTy,
1104                                             true, GlobalValue::InternalLinkage,
1105                                             Constant::getNullValue(LLVMArrTy));
1106     Register VarReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
1107     GR.add(GV, GR.CurMF, VarReg);
1108 
1109     Result &=
1110         BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpVariable))
1111             .addDef(VarReg)
1112             .addUse(GR.getSPIRVTypeID(VarTy))
1113             .addImm(SPIRV::StorageClass::UniformConstant)
1114             .addUse(Const)
1115             .constrainAllUses(TII, TRI, RBI);
1116     buildOpDecorate(VarReg, I, TII, SPIRV::Decoration::Constant, {});
1117     SPIRVType *SourceTy = GR.getOrCreateSPIRVPointerType(
1118         ValTy, I, TII, SPIRV::StorageClass::UniformConstant);
1119     SrcReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
1120     selectOpWithSrcs(SrcReg, SourceTy, I, {VarReg}, SPIRV::OpBitcast);
1121   }
1122   auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCopyMemorySized))
1123                  .addUse(I.getOperand(0).getReg())
1124                  .addUse(SrcReg)
1125                  .addUse(I.getOperand(2).getReg());
1126   if (I.getNumMemOperands())
1127     addMemoryOperands(*I.memoperands_begin(), MIB);
1128   Result &= MIB.constrainAllUses(TII, TRI, RBI);
1129   if (ResVReg.isValid() && ResVReg != MIB->getOperand(0).getReg())
1130     Result &= BuildCOPY(ResVReg, MIB->getOperand(0).getReg(), I);
1131   return Result;
1132 }
1133 
1134 bool SPIRVInstructionSelector::selectAtomicRMW(Register ResVReg,
1135                                                const SPIRVType *ResType,
1136                                                MachineInstr &I,
1137                                                unsigned NewOpcode,
1138                                                unsigned NegateOpcode) const {
1139   bool Result = true;
1140   assert(I.hasOneMemOperand());
1141   const MachineMemOperand *MemOp = *I.memoperands_begin();
1142   uint32_t Scope = static_cast<uint32_t>(getMemScope(
1143       GR.CurMF->getFunction().getContext(), MemOp->getSyncScopeID()));
1144   auto ScopeConstant = buildI32Constant(Scope, I);
1145   Register ScopeReg = ScopeConstant.first;
1146   Result &= ScopeConstant.second;
1147 
1148   Register Ptr = I.getOperand(1).getReg();
1149   // TODO: Changed as it's implemented in the translator. See test/atomicrmw.ll
1150   // auto ScSem =
1151   // getMemSemanticsForStorageClass(GR.getPointerStorageClass(Ptr));
1152   AtomicOrdering AO = MemOp->getSuccessOrdering();
1153   uint32_t MemSem = static_cast<uint32_t>(getMemSemantics(AO));
1154   auto MemSemConstant = buildI32Constant(MemSem /*| ScSem*/, I);
1155   Register MemSemReg = MemSemConstant.first;
1156   Result &= MemSemConstant.second;
1157 
1158   Register ValueReg = I.getOperand(2).getReg();
1159   if (NegateOpcode != 0) {
1160     // Translation with negative value operand is requested
1161     Register TmpReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
1162     Result &= selectOpWithSrcs(TmpReg, ResType, I, {ValueReg}, NegateOpcode);
1163     ValueReg = TmpReg;
1164   }
1165 
1166   return Result &&
1167          BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(NewOpcode))
1168              .addDef(ResVReg)
1169              .addUse(GR.getSPIRVTypeID(ResType))
1170              .addUse(Ptr)
1171              .addUse(ScopeReg)
1172              .addUse(MemSemReg)
1173              .addUse(ValueReg)
1174              .constrainAllUses(TII, TRI, RBI);
1175 }
1176 
1177 bool SPIRVInstructionSelector::selectUnmergeValues(MachineInstr &I) const {
1178   unsigned ArgI = I.getNumOperands() - 1;
1179   Register SrcReg =
1180       I.getOperand(ArgI).isReg() ? I.getOperand(ArgI).getReg() : Register(0);
1181   SPIRVType *DefType =
1182       SrcReg.isValid() ? GR.getSPIRVTypeForVReg(SrcReg) : nullptr;
1183   if (!DefType || DefType->getOpcode() != SPIRV::OpTypeVector)
1184     report_fatal_error(
1185         "cannot select G_UNMERGE_VALUES with a non-vector argument");
1186 
1187   SPIRVType *ScalarType =
1188       GR.getSPIRVTypeForVReg(DefType->getOperand(1).getReg());
1189   MachineBasicBlock &BB = *I.getParent();
1190   bool Res = false;
1191   for (unsigned i = 0; i < I.getNumDefs(); ++i) {
1192     Register ResVReg = I.getOperand(i).getReg();
1193     SPIRVType *ResType = GR.getSPIRVTypeForVReg(ResVReg);
1194     if (!ResType) {
1195       // There was no "assign type" actions, let's fix this now
1196       ResType = ScalarType;
1197       MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
1198       MRI->setType(ResVReg, LLT::scalar(GR.getScalarOrVectorBitWidth(ResType)));
1199       GR.assignSPIRVTypeToVReg(ResType, ResVReg, *GR.CurMF);
1200     }
1201     auto MIB =
1202         BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract))
1203             .addDef(ResVReg)
1204             .addUse(GR.getSPIRVTypeID(ResType))
1205             .addUse(SrcReg)
1206             .addImm(static_cast<int64_t>(i));
1207     Res |= MIB.constrainAllUses(TII, TRI, RBI);
1208   }
1209   return Res;
1210 }
1211 
1212 bool SPIRVInstructionSelector::selectFence(MachineInstr &I) const {
1213   AtomicOrdering AO = AtomicOrdering(I.getOperand(0).getImm());
1214   uint32_t MemSem = static_cast<uint32_t>(getMemSemantics(AO));
1215   auto MemSemConstant = buildI32Constant(MemSem, I);
1216   Register MemSemReg = MemSemConstant.first;
1217   bool Result = MemSemConstant.second;
1218   SyncScope::ID Ord = SyncScope::ID(I.getOperand(1).getImm());
1219   uint32_t Scope = static_cast<uint32_t>(
1220       getMemScope(GR.CurMF->getFunction().getContext(), Ord));
1221   auto ScopeConstant = buildI32Constant(Scope, I);
1222   Register ScopeReg = ScopeConstant.first;
1223   Result &= ScopeConstant.second;
1224   MachineBasicBlock &BB = *I.getParent();
1225   return Result &&
1226          BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpMemoryBarrier))
1227              .addUse(ScopeReg)
1228              .addUse(MemSemReg)
1229              .constrainAllUses(TII, TRI, RBI);
1230 }
1231 
1232 bool SPIRVInstructionSelector::selectOverflowArith(Register ResVReg,
1233                                                    const SPIRVType *ResType,
1234                                                    MachineInstr &I,
1235                                                    unsigned Opcode) const {
1236   Type *ResTy = nullptr;
1237   StringRef ResName;
1238   if (!GR.findValueAttrs(&I, ResTy, ResName))
1239     report_fatal_error(
1240         "Not enough info to select the arithmetic with overflow instruction");
1241   if (!ResTy || !ResTy->isStructTy())
1242     report_fatal_error("Expect struct type result for the arithmetic "
1243                        "with overflow instruction");
1244   // "Result Type must be from OpTypeStruct. The struct must have two members,
1245   // and the two members must be the same type."
1246   Type *ResElemTy = cast<StructType>(ResTy)->getElementType(0);
1247   ResTy = StructType::get(ResElemTy, ResElemTy);
1248   // Build SPIR-V types and constant(s) if needed.
1249   MachineIRBuilder MIRBuilder(I);
1250   SPIRVType *StructType = GR.getOrCreateSPIRVType(
1251       ResTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, false);
1252   assert(I.getNumDefs() > 1 && "Not enought operands");
1253   SPIRVType *BoolType = GR.getOrCreateSPIRVBoolType(I, TII);
1254   unsigned N = GR.getScalarOrVectorComponentCount(ResType);
1255   if (N > 1)
1256     BoolType = GR.getOrCreateSPIRVVectorType(BoolType, N, I, TII);
1257   Register BoolTypeReg = GR.getSPIRVTypeID(BoolType);
1258   Register ZeroReg = buildZerosVal(ResType, I);
1259   // A new virtual register to store the result struct.
1260   Register StructVReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
1261   MRI->setRegClass(StructVReg, &SPIRV::IDRegClass);
1262   // Build the result name if needed.
1263   if (ResName.size() > 0)
1264     buildOpName(StructVReg, ResName, MIRBuilder);
1265   // Build the arithmetic with overflow instruction.
1266   MachineBasicBlock &BB = *I.getParent();
1267   auto MIB =
1268       BuildMI(BB, MIRBuilder.getInsertPt(), I.getDebugLoc(), TII.get(Opcode))
1269           .addDef(StructVReg)
1270           .addUse(GR.getSPIRVTypeID(StructType));
1271   for (unsigned i = I.getNumDefs(); i < I.getNumOperands(); ++i)
1272     MIB.addUse(I.getOperand(i).getReg());
1273   bool Result = MIB.constrainAllUses(TII, TRI, RBI);
1274   // Build instructions to extract fields of the instruction's result.
1275   // A new virtual register to store the higher part of the result struct.
1276   Register HigherVReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
1277   MRI->setRegClass(HigherVReg, &SPIRV::iIDRegClass);
1278   for (unsigned i = 0; i < I.getNumDefs(); ++i) {
1279     auto MIB =
1280         BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract))
1281             .addDef(i == 1 ? HigherVReg : I.getOperand(i).getReg())
1282             .addUse(GR.getSPIRVTypeID(ResType))
1283             .addUse(StructVReg)
1284             .addImm(i);
1285     Result &= MIB.constrainAllUses(TII, TRI, RBI);
1286   }
1287   // Build boolean value from the higher part.
1288   return Result && BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpINotEqual))
1289                        .addDef(I.getOperand(1).getReg())
1290                        .addUse(BoolTypeReg)
1291                        .addUse(HigherVReg)
1292                        .addUse(ZeroReg)
1293                        .constrainAllUses(TII, TRI, RBI);
1294 }
1295 
1296 bool SPIRVInstructionSelector::selectAtomicCmpXchg(Register ResVReg,
1297                                                    const SPIRVType *ResType,
1298                                                    MachineInstr &I) const {
1299   bool Result = true;
1300   Register ScopeReg;
1301   Register MemSemEqReg;
1302   Register MemSemNeqReg;
1303   Register Ptr = I.getOperand(2).getReg();
1304   if (!isa<GIntrinsic>(I)) {
1305     assert(I.hasOneMemOperand());
1306     const MachineMemOperand *MemOp = *I.memoperands_begin();
1307     unsigned Scope = static_cast<uint32_t>(getMemScope(
1308         GR.CurMF->getFunction().getContext(), MemOp->getSyncScopeID()));
1309     auto ScopeConstant = buildI32Constant(Scope, I);
1310     ScopeReg = ScopeConstant.first;
1311     Result &= ScopeConstant.second;
1312 
1313     unsigned ScSem = static_cast<uint32_t>(
1314         getMemSemanticsForStorageClass(GR.getPointerStorageClass(Ptr)));
1315     AtomicOrdering AO = MemOp->getSuccessOrdering();
1316     unsigned MemSemEq = static_cast<uint32_t>(getMemSemantics(AO)) | ScSem;
1317     auto MemSemEqConstant = buildI32Constant(MemSemEq, I);
1318     MemSemEqReg = MemSemEqConstant.first;
1319     Result &= MemSemEqConstant.second;
1320     AtomicOrdering FO = MemOp->getFailureOrdering();
1321     unsigned MemSemNeq = static_cast<uint32_t>(getMemSemantics(FO)) | ScSem;
1322     if (MemSemEq == MemSemNeq)
1323       MemSemNeqReg = MemSemEqReg;
1324     else {
1325       auto MemSemNeqConstant = buildI32Constant(MemSemEq, I);
1326       MemSemNeqReg = MemSemNeqConstant.first;
1327       Result &= MemSemNeqConstant.second;
1328     }
1329   } else {
1330     ScopeReg = I.getOperand(5).getReg();
1331     MemSemEqReg = I.getOperand(6).getReg();
1332     MemSemNeqReg = I.getOperand(7).getReg();
1333   }
1334 
1335   Register Cmp = I.getOperand(3).getReg();
1336   Register Val = I.getOperand(4).getReg();
1337   SPIRVType *SpvValTy = GR.getSPIRVTypeForVReg(Val);
1338   Register ACmpRes = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
1339   const DebugLoc &DL = I.getDebugLoc();
1340   Result &=
1341       BuildMI(*I.getParent(), I, DL, TII.get(SPIRV::OpAtomicCompareExchange))
1342           .addDef(ACmpRes)
1343           .addUse(GR.getSPIRVTypeID(SpvValTy))
1344           .addUse(Ptr)
1345           .addUse(ScopeReg)
1346           .addUse(MemSemEqReg)
1347           .addUse(MemSemNeqReg)
1348           .addUse(Val)
1349           .addUse(Cmp)
1350           .constrainAllUses(TII, TRI, RBI);
1351   Register CmpSuccReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
1352   SPIRVType *BoolTy = GR.getOrCreateSPIRVBoolType(I, TII);
1353   Result &= BuildMI(*I.getParent(), I, DL, TII.get(SPIRV::OpIEqual))
1354                 .addDef(CmpSuccReg)
1355                 .addUse(GR.getSPIRVTypeID(BoolTy))
1356                 .addUse(ACmpRes)
1357                 .addUse(Cmp)
1358                 .constrainAllUses(TII, TRI, RBI);
1359   Register TmpReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
1360   Result &= BuildMI(*I.getParent(), I, DL, TII.get(SPIRV::OpCompositeInsert))
1361                 .addDef(TmpReg)
1362                 .addUse(GR.getSPIRVTypeID(ResType))
1363                 .addUse(ACmpRes)
1364                 .addUse(GR.getOrCreateUndef(I, ResType, TII))
1365                 .addImm(0)
1366                 .constrainAllUses(TII, TRI, RBI);
1367   return Result &&
1368          BuildMI(*I.getParent(), I, DL, TII.get(SPIRV::OpCompositeInsert))
1369              .addDef(ResVReg)
1370              .addUse(GR.getSPIRVTypeID(ResType))
1371              .addUse(CmpSuccReg)
1372              .addUse(TmpReg)
1373              .addImm(1)
1374              .constrainAllUses(TII, TRI, RBI);
1375 }
1376 
1377 static bool isGenericCastablePtr(SPIRV::StorageClass::StorageClass SC) {
1378   switch (SC) {
1379   case SPIRV::StorageClass::Workgroup:
1380   case SPIRV::StorageClass::CrossWorkgroup:
1381   case SPIRV::StorageClass::Function:
1382     return true;
1383   default:
1384     return false;
1385   }
1386 }
1387 
1388 static bool isUSMStorageClass(SPIRV::StorageClass::StorageClass SC) {
1389   switch (SC) {
1390   case SPIRV::StorageClass::DeviceOnlyINTEL:
1391   case SPIRV::StorageClass::HostOnlyINTEL:
1392     return true;
1393   default:
1394     return false;
1395   }
1396 }
1397 
1398 // Returns true ResVReg is referred only from global vars and OpName's.
1399 static bool isASCastInGVar(MachineRegisterInfo *MRI, Register ResVReg) {
1400   bool IsGRef = false;
1401   bool IsAllowedRefs =
1402       std::all_of(MRI->use_instr_begin(ResVReg), MRI->use_instr_end(),
1403                   [&IsGRef](auto const &It) {
1404                     unsigned Opcode = It.getOpcode();
1405                     if (Opcode == SPIRV::OpConstantComposite ||
1406                         Opcode == SPIRV::OpVariable ||
1407                         isSpvIntrinsic(It, Intrinsic::spv_init_global))
1408                       return IsGRef = true;
1409                     return Opcode == SPIRV::OpName;
1410                   });
1411   return IsAllowedRefs && IsGRef;
1412 }
1413 
1414 Register SPIRVInstructionSelector::getUcharPtrTypeReg(
1415     MachineInstr &I, SPIRV::StorageClass::StorageClass SC) const {
1416   return GR.getSPIRVTypeID(GR.getOrCreateSPIRVPointerType(
1417       GR.getOrCreateSPIRVIntegerType(8, I, TII), I, TII, SC));
1418 }
1419 
1420 MachineInstrBuilder
1421 SPIRVInstructionSelector::buildSpecConstantOp(MachineInstr &I, Register Dest,
1422                                               Register Src, Register DestType,
1423                                               uint32_t Opcode) const {
1424   return BuildMI(*I.getParent(), I, I.getDebugLoc(),
1425                  TII.get(SPIRV::OpSpecConstantOp))
1426       .addDef(Dest)
1427       .addUse(DestType)
1428       .addImm(Opcode)
1429       .addUse(Src);
1430 }
1431 
1432 MachineInstrBuilder
1433 SPIRVInstructionSelector::buildConstGenericPtr(MachineInstr &I, Register SrcPtr,
1434                                                SPIRVType *SrcPtrTy) const {
1435   SPIRVType *GenericPtrTy = GR.getOrCreateSPIRVPointerType(
1436       GR.getPointeeType(SrcPtrTy), I, TII, SPIRV::StorageClass::Generic);
1437   Register Tmp = MRI->createVirtualRegister(&SPIRV::pIDRegClass);
1438   MRI->setType(Tmp, LLT::pointer(storageClassToAddressSpace(
1439                                      SPIRV::StorageClass::Generic),
1440                                  GR.getPointerSize()));
1441   MachineFunction *MF = I.getParent()->getParent();
1442   GR.assignSPIRVTypeToVReg(GenericPtrTy, Tmp, *MF);
1443   MachineInstrBuilder MIB = buildSpecConstantOp(
1444       I, Tmp, SrcPtr, GR.getSPIRVTypeID(GenericPtrTy),
1445       static_cast<uint32_t>(SPIRV::Opcode::PtrCastToGeneric));
1446   GR.add(MIB.getInstr(), MF, Tmp);
1447   return MIB;
1448 }
1449 
1450 // In SPIR-V address space casting can only happen to and from the Generic
1451 // storage class. We can also only cast Workgroup, CrossWorkgroup, or Function
1452 // pointers to and from Generic pointers. As such, we can convert e.g. from
1453 // Workgroup to Function by going via a Generic pointer as an intermediary. All
1454 // other combinations can only be done by a bitcast, and are probably not safe.
1455 bool SPIRVInstructionSelector::selectAddrSpaceCast(Register ResVReg,
1456                                                    const SPIRVType *ResType,
1457                                                    MachineInstr &I) const {
1458   MachineBasicBlock &BB = *I.getParent();
1459   const DebugLoc &DL = I.getDebugLoc();
1460 
1461   Register SrcPtr = I.getOperand(1).getReg();
1462   SPIRVType *SrcPtrTy = GR.getSPIRVTypeForVReg(SrcPtr);
1463 
1464   // don't generate a cast for a null that may be represented by OpTypeInt
1465   if (SrcPtrTy->getOpcode() != SPIRV::OpTypePointer ||
1466       ResType->getOpcode() != SPIRV::OpTypePointer)
1467     return BuildCOPY(ResVReg, SrcPtr, I);
1468 
1469   SPIRV::StorageClass::StorageClass SrcSC = GR.getPointerStorageClass(SrcPtrTy);
1470   SPIRV::StorageClass::StorageClass DstSC = GR.getPointerStorageClass(ResType);
1471 
1472   if (isASCastInGVar(MRI, ResVReg)) {
1473     // AddrSpaceCast uses within OpVariable and OpConstantComposite instructions
1474     // are expressed by OpSpecConstantOp with an Opcode.
1475     // TODO: maybe insert a check whether the Kernel capability was declared and
1476     // so PtrCastToGeneric/GenericCastToPtr are available.
1477     unsigned SpecOpcode =
1478         DstSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(SrcSC)
1479             ? static_cast<uint32_t>(SPIRV::Opcode::PtrCastToGeneric)
1480             : (SrcSC == SPIRV::StorageClass::Generic &&
1481                        isGenericCastablePtr(DstSC)
1482                    ? static_cast<uint32_t>(SPIRV::Opcode::GenericCastToPtr)
1483                    : 0);
1484     // TODO: OpConstantComposite expects i8*, so we are forced to forget a
1485     // correct value of ResType and use general i8* instead. Maybe this should
1486     // be addressed in the emit-intrinsic step to infer a correct
1487     // OpConstantComposite type.
1488     if (SpecOpcode) {
1489       return buildSpecConstantOp(I, ResVReg, SrcPtr,
1490                                  getUcharPtrTypeReg(I, DstSC), SpecOpcode)
1491           .constrainAllUses(TII, TRI, RBI);
1492     } else if (isGenericCastablePtr(SrcSC) && isGenericCastablePtr(DstSC)) {
1493       MachineInstrBuilder MIB = buildConstGenericPtr(I, SrcPtr, SrcPtrTy);
1494       return MIB.constrainAllUses(TII, TRI, RBI) &&
1495              buildSpecConstantOp(
1496                  I, ResVReg, MIB->getOperand(0).getReg(),
1497                  getUcharPtrTypeReg(I, DstSC),
1498                  static_cast<uint32_t>(SPIRV::Opcode::GenericCastToPtr))
1499                  .constrainAllUses(TII, TRI, RBI);
1500     }
1501   }
1502 
1503   // don't generate a cast between identical storage classes
1504   if (SrcSC == DstSC)
1505     return BuildCOPY(ResVReg, SrcPtr, I);
1506 
1507   if ((SrcSC == SPIRV::StorageClass::Function &&
1508        DstSC == SPIRV::StorageClass::Private) ||
1509       (DstSC == SPIRV::StorageClass::Function &&
1510        SrcSC == SPIRV::StorageClass::Private))
1511     return BuildCOPY(ResVReg, SrcPtr, I);
1512 
1513   // Casting from an eligible pointer to Generic.
1514   if (DstSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(SrcSC))
1515     return selectUnOp(ResVReg, ResType, I, SPIRV::OpPtrCastToGeneric);
1516   // Casting from Generic to an eligible pointer.
1517   if (SrcSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(DstSC))
1518     return selectUnOp(ResVReg, ResType, I, SPIRV::OpGenericCastToPtr);
1519   // Casting between 2 eligible pointers using Generic as an intermediary.
1520   if (isGenericCastablePtr(SrcSC) && isGenericCastablePtr(DstSC)) {
1521     Register Tmp = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
1522     SPIRVType *GenericPtrTy = GR.getOrCreateSPIRVPointerType(
1523         GR.getPointeeType(SrcPtrTy), I, TII, SPIRV::StorageClass::Generic);
1524     bool Result = BuildMI(BB, I, DL, TII.get(SPIRV::OpPtrCastToGeneric))
1525                       .addDef(Tmp)
1526                       .addUse(GR.getSPIRVTypeID(GenericPtrTy))
1527                       .addUse(SrcPtr)
1528                       .constrainAllUses(TII, TRI, RBI);
1529     return Result && BuildMI(BB, I, DL, TII.get(SPIRV::OpGenericCastToPtr))
1530                          .addDef(ResVReg)
1531                          .addUse(GR.getSPIRVTypeID(ResType))
1532                          .addUse(Tmp)
1533                          .constrainAllUses(TII, TRI, RBI);
1534   }
1535 
1536   // Check if instructions from the SPV_INTEL_usm_storage_classes extension may
1537   // be applied
1538   if (isUSMStorageClass(SrcSC) && DstSC == SPIRV::StorageClass::CrossWorkgroup)
1539     return selectUnOp(ResVReg, ResType, I,
1540                       SPIRV::OpPtrCastToCrossWorkgroupINTEL);
1541   if (SrcSC == SPIRV::StorageClass::CrossWorkgroup && isUSMStorageClass(DstSC))
1542     return selectUnOp(ResVReg, ResType, I,
1543                       SPIRV::OpCrossWorkgroupCastToPtrINTEL);
1544   if (isUSMStorageClass(SrcSC) && DstSC == SPIRV::StorageClass::Generic)
1545     return selectUnOp(ResVReg, ResType, I, SPIRV::OpPtrCastToGeneric);
1546   if (SrcSC == SPIRV::StorageClass::Generic && isUSMStorageClass(DstSC))
1547     return selectUnOp(ResVReg, ResType, I, SPIRV::OpGenericCastToPtr);
1548 
1549   // Bitcast for pointers requires that the address spaces must match
1550   return false;
1551 }
1552 
1553 static unsigned getFCmpOpcode(unsigned PredNum) {
1554   auto Pred = static_cast<CmpInst::Predicate>(PredNum);
1555   switch (Pred) {
1556   case CmpInst::FCMP_OEQ:
1557     return SPIRV::OpFOrdEqual;
1558   case CmpInst::FCMP_OGE:
1559     return SPIRV::OpFOrdGreaterThanEqual;
1560   case CmpInst::FCMP_OGT:
1561     return SPIRV::OpFOrdGreaterThan;
1562   case CmpInst::FCMP_OLE:
1563     return SPIRV::OpFOrdLessThanEqual;
1564   case CmpInst::FCMP_OLT:
1565     return SPIRV::OpFOrdLessThan;
1566   case CmpInst::FCMP_ONE:
1567     return SPIRV::OpFOrdNotEqual;
1568   case CmpInst::FCMP_ORD:
1569     return SPIRV::OpOrdered;
1570   case CmpInst::FCMP_UEQ:
1571     return SPIRV::OpFUnordEqual;
1572   case CmpInst::FCMP_UGE:
1573     return SPIRV::OpFUnordGreaterThanEqual;
1574   case CmpInst::FCMP_UGT:
1575     return SPIRV::OpFUnordGreaterThan;
1576   case CmpInst::FCMP_ULE:
1577     return SPIRV::OpFUnordLessThanEqual;
1578   case CmpInst::FCMP_ULT:
1579     return SPIRV::OpFUnordLessThan;
1580   case CmpInst::FCMP_UNE:
1581     return SPIRV::OpFUnordNotEqual;
1582   case CmpInst::FCMP_UNO:
1583     return SPIRV::OpUnordered;
1584   default:
1585     llvm_unreachable("Unknown predicate type for FCmp");
1586   }
1587 }
1588 
1589 static unsigned getICmpOpcode(unsigned PredNum) {
1590   auto Pred = static_cast<CmpInst::Predicate>(PredNum);
1591   switch (Pred) {
1592   case CmpInst::ICMP_EQ:
1593     return SPIRV::OpIEqual;
1594   case CmpInst::ICMP_NE:
1595     return SPIRV::OpINotEqual;
1596   case CmpInst::ICMP_SGE:
1597     return SPIRV::OpSGreaterThanEqual;
1598   case CmpInst::ICMP_SGT:
1599     return SPIRV::OpSGreaterThan;
1600   case CmpInst::ICMP_SLE:
1601     return SPIRV::OpSLessThanEqual;
1602   case CmpInst::ICMP_SLT:
1603     return SPIRV::OpSLessThan;
1604   case CmpInst::ICMP_UGE:
1605     return SPIRV::OpUGreaterThanEqual;
1606   case CmpInst::ICMP_UGT:
1607     return SPIRV::OpUGreaterThan;
1608   case CmpInst::ICMP_ULE:
1609     return SPIRV::OpULessThanEqual;
1610   case CmpInst::ICMP_ULT:
1611     return SPIRV::OpULessThan;
1612   default:
1613     llvm_unreachable("Unknown predicate type for ICmp");
1614   }
1615 }
1616 
1617 static unsigned getPtrCmpOpcode(unsigned Pred) {
1618   switch (static_cast<CmpInst::Predicate>(Pred)) {
1619   case CmpInst::ICMP_EQ:
1620     return SPIRV::OpPtrEqual;
1621   case CmpInst::ICMP_NE:
1622     return SPIRV::OpPtrNotEqual;
1623   default:
1624     llvm_unreachable("Unknown predicate type for pointer comparison");
1625   }
1626 }
1627 
1628 // Return the logical operation, or abort if none exists.
1629 static unsigned getBoolCmpOpcode(unsigned PredNum) {
1630   auto Pred = static_cast<CmpInst::Predicate>(PredNum);
1631   switch (Pred) {
1632   case CmpInst::ICMP_EQ:
1633     return SPIRV::OpLogicalEqual;
1634   case CmpInst::ICMP_NE:
1635     return SPIRV::OpLogicalNotEqual;
1636   default:
1637     llvm_unreachable("Unknown predicate type for Bool comparison");
1638   }
1639 }
1640 
1641 static APFloat getZeroFP(const Type *LLVMFloatTy) {
1642   if (!LLVMFloatTy)
1643     return APFloat::getZero(APFloat::IEEEsingle());
1644   switch (LLVMFloatTy->getScalarType()->getTypeID()) {
1645   case Type::HalfTyID:
1646     return APFloat::getZero(APFloat::IEEEhalf());
1647   default:
1648   case Type::FloatTyID:
1649     return APFloat::getZero(APFloat::IEEEsingle());
1650   case Type::DoubleTyID:
1651     return APFloat::getZero(APFloat::IEEEdouble());
1652   }
1653 }
1654 
1655 static APFloat getOneFP(const Type *LLVMFloatTy) {
1656   if (!LLVMFloatTy)
1657     return APFloat::getOne(APFloat::IEEEsingle());
1658   switch (LLVMFloatTy->getScalarType()->getTypeID()) {
1659   case Type::HalfTyID:
1660     return APFloat::getOne(APFloat::IEEEhalf());
1661   default:
1662   case Type::FloatTyID:
1663     return APFloat::getOne(APFloat::IEEEsingle());
1664   case Type::DoubleTyID:
1665     return APFloat::getOne(APFloat::IEEEdouble());
1666   }
1667 }
1668 
1669 bool SPIRVInstructionSelector::selectAnyOrAll(Register ResVReg,
1670                                               const SPIRVType *ResType,
1671                                               MachineInstr &I,
1672                                               unsigned OpAnyOrAll) const {
1673   assert(I.getNumOperands() == 3);
1674   assert(I.getOperand(2).isReg());
1675   MachineBasicBlock &BB = *I.getParent();
1676   Register InputRegister = I.getOperand(2).getReg();
1677   SPIRVType *InputType = GR.getSPIRVTypeForVReg(InputRegister);
1678 
1679   if (!InputType)
1680     report_fatal_error("Input Type could not be determined.");
1681 
1682   bool IsBoolTy = GR.isScalarOrVectorOfType(InputRegister, SPIRV::OpTypeBool);
1683   bool IsVectorTy = InputType->getOpcode() == SPIRV::OpTypeVector;
1684   if (IsBoolTy && !IsVectorTy) {
1685     assert(ResVReg == I.getOperand(0).getReg());
1686     return BuildCOPY(ResVReg, InputRegister, I);
1687   }
1688 
1689   bool IsFloatTy = GR.isScalarOrVectorOfType(InputRegister, SPIRV::OpTypeFloat);
1690   unsigned SpirvNotEqualId =
1691       IsFloatTy ? SPIRV::OpFOrdNotEqual : SPIRV::OpINotEqual;
1692   SPIRVType *SpvBoolScalarTy = GR.getOrCreateSPIRVBoolType(I, TII);
1693   SPIRVType *SpvBoolTy = SpvBoolScalarTy;
1694   Register NotEqualReg = ResVReg;
1695 
1696   if (IsVectorTy) {
1697     NotEqualReg = IsBoolTy ? InputRegister
1698                            : MRI->createVirtualRegister(&SPIRV::iIDRegClass);
1699     const unsigned NumElts = InputType->getOperand(2).getImm();
1700     SpvBoolTy = GR.getOrCreateSPIRVVectorType(SpvBoolTy, NumElts, I, TII);
1701   }
1702 
1703   bool Result = true;
1704   if (!IsBoolTy) {
1705     Register ConstZeroReg =
1706         IsFloatTy ? buildZerosValF(InputType, I) : buildZerosVal(InputType, I);
1707 
1708     Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(SpirvNotEqualId))
1709                   .addDef(NotEqualReg)
1710                   .addUse(GR.getSPIRVTypeID(SpvBoolTy))
1711                   .addUse(InputRegister)
1712                   .addUse(ConstZeroReg)
1713                   .constrainAllUses(TII, TRI, RBI);
1714   }
1715 
1716   if (!IsVectorTy)
1717     return Result;
1718 
1719   return Result && BuildMI(BB, I, I.getDebugLoc(), TII.get(OpAnyOrAll))
1720                        .addDef(ResVReg)
1721                        .addUse(GR.getSPIRVTypeID(SpvBoolScalarTy))
1722                        .addUse(NotEqualReg)
1723                        .constrainAllUses(TII, TRI, RBI);
1724 }
1725 
1726 bool SPIRVInstructionSelector::selectAll(Register ResVReg,
1727                                          const SPIRVType *ResType,
1728                                          MachineInstr &I) const {
1729   return selectAnyOrAll(ResVReg, ResType, I, SPIRV::OpAll);
1730 }
1731 
1732 bool SPIRVInstructionSelector::selectAny(Register ResVReg,
1733                                          const SPIRVType *ResType,
1734                                          MachineInstr &I) const {
1735   return selectAnyOrAll(ResVReg, ResType, I, SPIRV::OpAny);
1736 }
1737 
1738 // Select the OpDot instruction for the given float dot
1739 bool SPIRVInstructionSelector::selectFloatDot(Register ResVReg,
1740                                               const SPIRVType *ResType,
1741                                               MachineInstr &I) const {
1742   assert(I.getNumOperands() == 4);
1743   assert(I.getOperand(2).isReg());
1744   assert(I.getOperand(3).isReg());
1745 
1746   [[maybe_unused]] SPIRVType *VecType =
1747       GR.getSPIRVTypeForVReg(I.getOperand(2).getReg());
1748 
1749   assert(VecType->getOpcode() == SPIRV::OpTypeVector &&
1750          GR.getScalarOrVectorComponentCount(VecType) > 1 &&
1751          "dot product requires a vector of at least 2 components");
1752 
1753   [[maybe_unused]] SPIRVType *EltType =
1754       GR.getSPIRVTypeForVReg(VecType->getOperand(1).getReg());
1755 
1756   assert(EltType->getOpcode() == SPIRV::OpTypeFloat);
1757 
1758   MachineBasicBlock &BB = *I.getParent();
1759   return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpDot))
1760       .addDef(ResVReg)
1761       .addUse(GR.getSPIRVTypeID(ResType))
1762       .addUse(I.getOperand(2).getReg())
1763       .addUse(I.getOperand(3).getReg())
1764       .constrainAllUses(TII, TRI, RBI);
1765 }
1766 
1767 bool SPIRVInstructionSelector::selectIntegerDot(Register ResVReg,
1768                                                 const SPIRVType *ResType,
1769                                                 MachineInstr &I,
1770                                                 bool Signed) const {
1771   assert(I.getNumOperands() == 4);
1772   assert(I.getOperand(2).isReg());
1773   assert(I.getOperand(3).isReg());
1774   MachineBasicBlock &BB = *I.getParent();
1775 
1776   auto DotOp = Signed ? SPIRV::OpSDot : SPIRV::OpUDot;
1777   return BuildMI(BB, I, I.getDebugLoc(), TII.get(DotOp))
1778       .addDef(ResVReg)
1779       .addUse(GR.getSPIRVTypeID(ResType))
1780       .addUse(I.getOperand(2).getReg())
1781       .addUse(I.getOperand(3).getReg())
1782       .constrainAllUses(TII, TRI, RBI);
1783 }
1784 
1785 // Since pre-1.6 SPIRV has no integer dot implementation,
1786 // expand by piecewise multiplying and adding the results
1787 bool SPIRVInstructionSelector::selectIntegerDotExpansion(
1788     Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const {
1789   assert(I.getNumOperands() == 4);
1790   assert(I.getOperand(2).isReg());
1791   assert(I.getOperand(3).isReg());
1792   MachineBasicBlock &BB = *I.getParent();
1793 
1794   // Multiply the vectors, then sum the results
1795   Register Vec0 = I.getOperand(2).getReg();
1796   Register Vec1 = I.getOperand(3).getReg();
1797   Register TmpVec = MRI->createVirtualRegister(GR.getRegClass(ResType));
1798   SPIRVType *VecType = GR.getSPIRVTypeForVReg(Vec0);
1799 
1800   bool Result = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpIMulV))
1801                     .addDef(TmpVec)
1802                     .addUse(GR.getSPIRVTypeID(VecType))
1803                     .addUse(Vec0)
1804                     .addUse(Vec1)
1805                     .constrainAllUses(TII, TRI, RBI);
1806 
1807   assert(VecType->getOpcode() == SPIRV::OpTypeVector &&
1808          GR.getScalarOrVectorComponentCount(VecType) > 1 &&
1809          "dot product requires a vector of at least 2 components");
1810 
1811   Register Res = MRI->createVirtualRegister(GR.getRegClass(ResType));
1812   Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract))
1813                 .addDef(Res)
1814                 .addUse(GR.getSPIRVTypeID(ResType))
1815                 .addUse(TmpVec)
1816                 .addImm(0)
1817                 .constrainAllUses(TII, TRI, RBI);
1818 
1819   for (unsigned i = 1; i < GR.getScalarOrVectorComponentCount(VecType); i++) {
1820     Register Elt = MRI->createVirtualRegister(GR.getRegClass(ResType));
1821 
1822     Result &=
1823         BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract))
1824             .addDef(Elt)
1825             .addUse(GR.getSPIRVTypeID(ResType))
1826             .addUse(TmpVec)
1827             .addImm(i)
1828             .constrainAllUses(TII, TRI, RBI);
1829 
1830     Register Sum = i < GR.getScalarOrVectorComponentCount(VecType) - 1
1831                        ? MRI->createVirtualRegister(GR.getRegClass(ResType))
1832                        : ResVReg;
1833 
1834     Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpIAddS))
1835                   .addDef(Sum)
1836                   .addUse(GR.getSPIRVTypeID(ResType))
1837                   .addUse(Res)
1838                   .addUse(Elt)
1839                   .constrainAllUses(TII, TRI, RBI);
1840     Res = Sum;
1841   }
1842 
1843   return Result;
1844 }
1845 
1846 template <bool Signed>
1847 bool SPIRVInstructionSelector::selectDot4AddPacked(Register ResVReg,
1848                                                    const SPIRVType *ResType,
1849                                                    MachineInstr &I) const {
1850   assert(I.getNumOperands() == 5);
1851   assert(I.getOperand(2).isReg());
1852   assert(I.getOperand(3).isReg());
1853   assert(I.getOperand(4).isReg());
1854   MachineBasicBlock &BB = *I.getParent();
1855 
1856   auto DotOp = Signed ? SPIRV::OpSDot : SPIRV::OpUDot;
1857   Register Dot = MRI->createVirtualRegister(GR.getRegClass(ResType));
1858   bool Result = BuildMI(BB, I, I.getDebugLoc(), TII.get(DotOp))
1859                     .addDef(Dot)
1860                     .addUse(GR.getSPIRVTypeID(ResType))
1861                     .addUse(I.getOperand(2).getReg())
1862                     .addUse(I.getOperand(3).getReg())
1863                     .constrainAllUses(TII, TRI, RBI);
1864 
1865   return Result && BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpIAddS))
1866                        .addDef(ResVReg)
1867                        .addUse(GR.getSPIRVTypeID(ResType))
1868                        .addUse(Dot)
1869                        .addUse(I.getOperand(4).getReg())
1870                        .constrainAllUses(TII, TRI, RBI);
1871 }
1872 
1873 // Since pre-1.6 SPIRV has no DotProductInput4x8BitPacked implementation,
1874 // extract the elements of the packed inputs, multiply them and add the result
1875 // to the accumulator.
1876 template <bool Signed>
1877 bool SPIRVInstructionSelector::selectDot4AddPackedExpansion(
1878     Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const {
1879   assert(I.getNumOperands() == 5);
1880   assert(I.getOperand(2).isReg());
1881   assert(I.getOperand(3).isReg());
1882   assert(I.getOperand(4).isReg());
1883   MachineBasicBlock &BB = *I.getParent();
1884 
1885   bool Result = true;
1886 
1887   // Acc = C
1888   Register Acc = I.getOperand(4).getReg();
1889   SPIRVType *EltType = GR.getOrCreateSPIRVIntegerType(8, I, TII);
1890   auto ExtractOp =
1891       Signed ? SPIRV::OpBitFieldSExtract : SPIRV::OpBitFieldUExtract;
1892 
1893   // Extract the i8 element, multiply and add it to the accumulator
1894   for (unsigned i = 0; i < 4; i++) {
1895     // A[i]
1896     Register AElt = MRI->createVirtualRegister(&SPIRV::IDRegClass);
1897     Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
1898                   .addDef(AElt)
1899                   .addUse(GR.getSPIRVTypeID(ResType))
1900                   .addUse(I.getOperand(2).getReg())
1901                   .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII))
1902                   .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
1903                   .constrainAllUses(TII, TRI, RBI);
1904 
1905     // B[i]
1906     Register BElt = MRI->createVirtualRegister(&SPIRV::IDRegClass);
1907     Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
1908                   .addDef(BElt)
1909                   .addUse(GR.getSPIRVTypeID(ResType))
1910                   .addUse(I.getOperand(3).getReg())
1911                   .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII))
1912                   .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
1913                   .constrainAllUses(TII, TRI, RBI);
1914 
1915     // A[i] * B[i]
1916     Register Mul = MRI->createVirtualRegister(&SPIRV::IDRegClass);
1917     Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpIMulS))
1918                   .addDef(Mul)
1919                   .addUse(GR.getSPIRVTypeID(ResType))
1920                   .addUse(AElt)
1921                   .addUse(BElt)
1922                   .constrainAllUses(TII, TRI, RBI);
1923 
1924     // Discard 24 highest-bits so that stored i32 register is i8 equivalent
1925     Register MaskMul = MRI->createVirtualRegister(&SPIRV::IDRegClass);
1926     Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
1927                   .addDef(MaskMul)
1928                   .addUse(GR.getSPIRVTypeID(ResType))
1929                   .addUse(Mul)
1930                   .addUse(GR.getOrCreateConstInt(0, I, EltType, TII))
1931                   .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
1932                   .constrainAllUses(TII, TRI, RBI);
1933 
1934     // Acc = Acc + A[i] * B[i]
1935     Register Sum =
1936         i < 3 ? MRI->createVirtualRegister(&SPIRV::IDRegClass) : ResVReg;
1937     Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpIAddS))
1938                   .addDef(Sum)
1939                   .addUse(GR.getSPIRVTypeID(ResType))
1940                   .addUse(Acc)
1941                   .addUse(MaskMul)
1942                   .constrainAllUses(TII, TRI, RBI);
1943 
1944     Acc = Sum;
1945   }
1946 
1947   return Result;
1948 }
1949 
1950 /// Transform saturate(x) to clamp(x, 0.0f, 1.0f) as SPIRV
1951 /// does not have a saturate builtin.
1952 bool SPIRVInstructionSelector::selectSaturate(Register ResVReg,
1953                                               const SPIRVType *ResType,
1954                                               MachineInstr &I) const {
1955   assert(I.getNumOperands() == 3);
1956   assert(I.getOperand(2).isReg());
1957   MachineBasicBlock &BB = *I.getParent();
1958   Register VZero = buildZerosValF(ResType, I);
1959   Register VOne = buildOnesValF(ResType, I);
1960 
1961   return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst))
1962       .addDef(ResVReg)
1963       .addUse(GR.getSPIRVTypeID(ResType))
1964       .addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
1965       .addImm(GL::FClamp)
1966       .addUse(I.getOperand(2).getReg())
1967       .addUse(VZero)
1968       .addUse(VOne)
1969       .constrainAllUses(TII, TRI, RBI);
1970 }
1971 
1972 bool SPIRVInstructionSelector::selectSign(Register ResVReg,
1973                                           const SPIRVType *ResType,
1974                                           MachineInstr &I) const {
1975   assert(I.getNumOperands() == 3);
1976   assert(I.getOperand(2).isReg());
1977   MachineBasicBlock &BB = *I.getParent();
1978   Register InputRegister = I.getOperand(2).getReg();
1979   SPIRVType *InputType = GR.getSPIRVTypeForVReg(InputRegister);
1980   auto &DL = I.getDebugLoc();
1981 
1982   if (!InputType)
1983     report_fatal_error("Input Type could not be determined.");
1984 
1985   bool IsFloatTy = GR.isScalarOrVectorOfType(InputRegister, SPIRV::OpTypeFloat);
1986 
1987   unsigned SignBitWidth = GR.getScalarOrVectorBitWidth(InputType);
1988   unsigned ResBitWidth = GR.getScalarOrVectorBitWidth(ResType);
1989 
1990   bool NeedsConversion = IsFloatTy || SignBitWidth != ResBitWidth;
1991 
1992   auto SignOpcode = IsFloatTy ? GL::FSign : GL::SSign;
1993   Register SignReg = NeedsConversion
1994                          ? MRI->createVirtualRegister(&SPIRV::IDRegClass)
1995                          : ResVReg;
1996 
1997   bool Result =
1998       BuildMI(BB, I, DL, TII.get(SPIRV::OpExtInst))
1999           .addDef(SignReg)
2000           .addUse(GR.getSPIRVTypeID(InputType))
2001           .addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
2002           .addImm(SignOpcode)
2003           .addUse(InputRegister)
2004           .constrainAllUses(TII, TRI, RBI);
2005 
2006   if (NeedsConversion) {
2007     auto ConvertOpcode = IsFloatTy ? SPIRV::OpConvertFToS : SPIRV::OpSConvert;
2008     Result &= BuildMI(*I.getParent(), I, DL, TII.get(ConvertOpcode))
2009                   .addDef(ResVReg)
2010                   .addUse(GR.getSPIRVTypeID(ResType))
2011                   .addUse(SignReg)
2012                   .constrainAllUses(TII, TRI, RBI);
2013   }
2014 
2015   return Result;
2016 }
2017 
2018 bool SPIRVInstructionSelector::selectWaveOpInst(Register ResVReg,
2019                                                 const SPIRVType *ResType,
2020                                                 MachineInstr &I,
2021                                                 unsigned Opcode) const {
2022   MachineBasicBlock &BB = *I.getParent();
2023   SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);
2024 
2025   auto BMI = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
2026                  .addDef(ResVReg)
2027                  .addUse(GR.getSPIRVTypeID(ResType))
2028                  .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I,
2029                                                 IntTy, TII));
2030 
2031   for (unsigned J = 2; J < I.getNumOperands(); J++) {
2032     BMI.addUse(I.getOperand(J).getReg());
2033   }
2034 
2035   return BMI.constrainAllUses(TII, TRI, RBI);
2036 }
2037 
2038 bool SPIRVInstructionSelector::selectWaveActiveCountBits(
2039     Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const {
2040 
2041   SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);
2042   SPIRVType *BallotType = GR.getOrCreateSPIRVVectorType(IntTy, 4, I, TII);
2043   Register BallotReg = MRI->createVirtualRegister(GR.getRegClass(BallotType));
2044   bool Result = selectWaveOpInst(BallotReg, BallotType, I,
2045                                  SPIRV::OpGroupNonUniformBallot);
2046 
2047   MachineBasicBlock &BB = *I.getParent();
2048   Result &=
2049       BuildMI(BB, I, I.getDebugLoc(),
2050               TII.get(SPIRV::OpGroupNonUniformBallotBitCount))
2051           .addDef(ResVReg)
2052           .addUse(GR.getSPIRVTypeID(ResType))
2053           .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
2054           .addImm(SPIRV::GroupOperation::Reduce)
2055           .addUse(BallotReg)
2056           .constrainAllUses(TII, TRI, RBI);
2057 
2058   return Result;
2059 }
2060 
2061 bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
2062                                                 const SPIRVType *ResType,
2063                                                 MachineInstr &I) const {
2064   MachineBasicBlock &BB = *I.getParent();
2065   return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
2066       .addDef(ResVReg)
2067       .addUse(GR.getSPIRVTypeID(ResType))
2068       .addUse(I.getOperand(1).getReg())
2069       .constrainAllUses(TII, TRI, RBI);
2070 }
2071 
2072 bool SPIRVInstructionSelector::selectFreeze(Register ResVReg,
2073                                             const SPIRVType *ResType,
2074                                             MachineInstr &I) const {
2075   // There is no way to implement `freeze` correctly without support on SPIR-V
2076   // standard side, but we may at least address a simple (static) case when
2077   // undef/poison value presence is obvious. The main benefit of even
2078   // incomplete `freeze` support is preventing of translation from crashing due
2079   // to lack of support on legalization and instruction selection steps.
2080   if (!I.getOperand(0).isReg() || !I.getOperand(1).isReg())
2081     return false;
2082   Register OpReg = I.getOperand(1).getReg();
2083   if (MachineInstr *Def = MRI->getVRegDef(OpReg)) {
2084     Register Reg;
2085     switch (Def->getOpcode()) {
2086     case SPIRV::ASSIGN_TYPE:
2087       if (MachineInstr *AssignToDef =
2088               MRI->getVRegDef(Def->getOperand(1).getReg())) {
2089         if (AssignToDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
2090           Reg = Def->getOperand(2).getReg();
2091       }
2092       break;
2093     case SPIRV::OpUndef:
2094       Reg = Def->getOperand(1).getReg();
2095       break;
2096     }
2097     unsigned DestOpCode;
2098     if (Reg.isValid()) {
2099       DestOpCode = SPIRV::OpConstantNull;
2100     } else {
2101       DestOpCode = TargetOpcode::COPY;
2102       Reg = OpReg;
2103     }
2104     return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(DestOpCode))
2105         .addDef(I.getOperand(0).getReg())
2106         .addUse(Reg)
2107         .constrainAllUses(TII, TRI, RBI);
2108   }
2109   return false;
2110 }
2111 
2112 static unsigned getArrayComponentCount(MachineRegisterInfo *MRI,
2113                                        const SPIRVType *ResType) {
2114   Register OpReg = ResType->getOperand(2).getReg();
2115   SPIRVType *OpDef = MRI->getVRegDef(OpReg);
2116   if (!OpDef)
2117     return 0;
2118   if (OpDef->getOpcode() == SPIRV::ASSIGN_TYPE &&
2119       OpDef->getOperand(1).isReg()) {
2120     if (SPIRVType *RefDef = MRI->getVRegDef(OpDef->getOperand(1).getReg()))
2121       OpDef = RefDef;
2122   }
2123   unsigned N = OpDef->getOpcode() == TargetOpcode::G_CONSTANT
2124                    ? OpDef->getOperand(1).getCImm()->getValue().getZExtValue()
2125                    : 0;
2126   return N;
2127 }
2128 
2129 // Return true if the type represents a constant register
2130 static bool isConstReg(MachineRegisterInfo *MRI, SPIRVType *OpDef,
2131                        SmallPtrSet<SPIRVType *, 4> &Visited) {
2132   if (OpDef->getOpcode() == SPIRV::ASSIGN_TYPE &&
2133       OpDef->getOperand(1).isReg()) {
2134     if (SPIRVType *RefDef = MRI->getVRegDef(OpDef->getOperand(1).getReg()))
2135       OpDef = RefDef;
2136   }
2137 
2138   if (Visited.contains(OpDef))
2139     return true;
2140   Visited.insert(OpDef);
2141 
2142   unsigned Opcode = OpDef->getOpcode();
2143   switch (Opcode) {
2144   case TargetOpcode::G_CONSTANT:
2145   case TargetOpcode::G_FCONSTANT:
2146     return true;
2147   case TargetOpcode::G_INTRINSIC:
2148   case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
2149   case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
2150     return cast<GIntrinsic>(*OpDef).getIntrinsicID() ==
2151            Intrinsic::spv_const_composite;
2152   case TargetOpcode::G_BUILD_VECTOR:
2153   case TargetOpcode::G_SPLAT_VECTOR: {
2154     for (unsigned i = OpDef->getNumExplicitDefs(); i < OpDef->getNumOperands();
2155          i++) {
2156       SPIRVType *OpNestedDef =
2157           OpDef->getOperand(i).isReg()
2158               ? MRI->getVRegDef(OpDef->getOperand(i).getReg())
2159               : nullptr;
2160       if (OpNestedDef && !isConstReg(MRI, OpNestedDef, Visited))
2161         return false;
2162     }
2163     return true;
2164   }
2165   }
2166   return false;
2167 }
2168 
2169 // Return true if the virtual register represents a constant
2170 static bool isConstReg(MachineRegisterInfo *MRI, Register OpReg) {
2171   SmallPtrSet<SPIRVType *, 4> Visited;
2172   if (SPIRVType *OpDef = MRI->getVRegDef(OpReg))
2173     return isConstReg(MRI, OpDef, Visited);
2174   return false;
2175 }
2176 
2177 bool SPIRVInstructionSelector::selectBuildVector(Register ResVReg,
2178                                                  const SPIRVType *ResType,
2179                                                  MachineInstr &I) const {
2180   unsigned N = 0;
2181   if (ResType->getOpcode() == SPIRV::OpTypeVector)
2182     N = GR.getScalarOrVectorComponentCount(ResType);
2183   else if (ResType->getOpcode() == SPIRV::OpTypeArray)
2184     N = getArrayComponentCount(MRI, ResType);
2185   else
2186     report_fatal_error("Cannot select G_BUILD_VECTOR with a non-vector result");
2187   if (I.getNumExplicitOperands() - I.getNumExplicitDefs() != N)
2188     report_fatal_error("G_BUILD_VECTOR and the result type are inconsistent");
2189 
2190   // check if we may construct a constant vector
2191   bool IsConst = true;
2192   for (unsigned i = I.getNumExplicitDefs();
2193        i < I.getNumExplicitOperands() && IsConst; ++i)
2194     if (!isConstReg(MRI, I.getOperand(i).getReg()))
2195       IsConst = false;
2196 
2197   if (!IsConst && N < 2)
2198     report_fatal_error(
2199         "There must be at least two constituent operands in a vector");
2200 
2201   MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
2202   auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
2203                      TII.get(IsConst ? SPIRV::OpConstantComposite
2204                                      : SPIRV::OpCompositeConstruct))
2205                  .addDef(ResVReg)
2206                  .addUse(GR.getSPIRVTypeID(ResType));
2207   for (unsigned i = I.getNumExplicitDefs(); i < I.getNumExplicitOperands(); ++i)
2208     MIB.addUse(I.getOperand(i).getReg());
2209   return MIB.constrainAllUses(TII, TRI, RBI);
2210 }
2211 
2212 bool SPIRVInstructionSelector::selectSplatVector(Register ResVReg,
2213                                                  const SPIRVType *ResType,
2214                                                  MachineInstr &I) const {
2215   unsigned N = 0;
2216   if (ResType->getOpcode() == SPIRV::OpTypeVector)
2217     N = GR.getScalarOrVectorComponentCount(ResType);
2218   else if (ResType->getOpcode() == SPIRV::OpTypeArray)
2219     N = getArrayComponentCount(MRI, ResType);
2220   else
2221     report_fatal_error("Cannot select G_SPLAT_VECTOR with a non-vector result");
2222 
2223   unsigned OpIdx = I.getNumExplicitDefs();
2224   if (!I.getOperand(OpIdx).isReg())
2225     report_fatal_error("Unexpected argument in G_SPLAT_VECTOR");
2226 
2227   // check if we may construct a constant vector
2228   Register OpReg = I.getOperand(OpIdx).getReg();
2229   bool IsConst = isConstReg(MRI, OpReg);
2230 
2231   if (!IsConst && N < 2)
2232     report_fatal_error(
2233         "There must be at least two constituent operands in a vector");
2234 
2235   MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
2236   auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
2237                      TII.get(IsConst ? SPIRV::OpConstantComposite
2238                                      : SPIRV::OpCompositeConstruct))
2239                  .addDef(ResVReg)
2240                  .addUse(GR.getSPIRVTypeID(ResType));
2241   for (unsigned i = 0; i < N; ++i)
2242     MIB.addUse(OpReg);
2243   return MIB.constrainAllUses(TII, TRI, RBI);
2244 }
2245 
2246 bool SPIRVInstructionSelector::selectDiscard(Register ResVReg,
2247                                              const SPIRVType *ResType,
2248                                              MachineInstr &I) const {
2249 
2250   unsigned Opcode;
2251 
2252   if (STI.canUseExtension(
2253           SPIRV::Extension::SPV_EXT_demote_to_helper_invocation) ||
2254       STI.isAtLeastSPIRVVer(llvm::VersionTuple(1, 6))) {
2255     Opcode = SPIRV::OpDemoteToHelperInvocation;
2256   } else {
2257     Opcode = SPIRV::OpKill;
2258     // OpKill must be the last operation of any basic block.
2259     if (MachineInstr *NextI = I.getNextNode()) {
2260       GR.invalidateMachineInstr(NextI);
2261       NextI->removeFromParent();
2262     }
2263   }
2264 
2265   MachineBasicBlock &BB = *I.getParent();
2266   return BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
2267       .constrainAllUses(TII, TRI, RBI);
2268 }
2269 
2270 bool SPIRVInstructionSelector::selectCmp(Register ResVReg,
2271                                          const SPIRVType *ResType,
2272                                          unsigned CmpOpc,
2273                                          MachineInstr &I) const {
2274   Register Cmp0 = I.getOperand(2).getReg();
2275   Register Cmp1 = I.getOperand(3).getReg();
2276   assert(GR.getSPIRVTypeForVReg(Cmp0)->getOpcode() ==
2277              GR.getSPIRVTypeForVReg(Cmp1)->getOpcode() &&
2278          "CMP operands should have the same type");
2279   return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CmpOpc))
2280       .addDef(ResVReg)
2281       .addUse(GR.getSPIRVTypeID(ResType))
2282       .addUse(Cmp0)
2283       .addUse(Cmp1)
2284       .constrainAllUses(TII, TRI, RBI);
2285 }
2286 
2287 bool SPIRVInstructionSelector::selectICmp(Register ResVReg,
2288                                           const SPIRVType *ResType,
2289                                           MachineInstr &I) const {
2290   auto Pred = I.getOperand(1).getPredicate();
2291   unsigned CmpOpc;
2292 
2293   Register CmpOperand = I.getOperand(2).getReg();
2294   if (GR.isScalarOfType(CmpOperand, SPIRV::OpTypePointer))
2295     CmpOpc = getPtrCmpOpcode(Pred);
2296   else if (GR.isScalarOrVectorOfType(CmpOperand, SPIRV::OpTypeBool))
2297     CmpOpc = getBoolCmpOpcode(Pred);
2298   else
2299     CmpOpc = getICmpOpcode(Pred);
2300   return selectCmp(ResVReg, ResType, CmpOpc, I);
2301 }
2302 
2303 void SPIRVInstructionSelector::renderFImm64(MachineInstrBuilder &MIB,
2304                                             const MachineInstr &I,
2305                                             int OpIdx) const {
2306   assert(I.getOpcode() == TargetOpcode::G_FCONSTANT && OpIdx == -1 &&
2307          "Expected G_FCONSTANT");
2308   const ConstantFP *FPImm = I.getOperand(1).getFPImm();
2309   addNumImm(FPImm->getValueAPF().bitcastToAPInt(), MIB);
2310 }
2311 
2312 void SPIRVInstructionSelector::renderImm32(MachineInstrBuilder &MIB,
2313                                            const MachineInstr &I,
2314                                            int OpIdx) const {
2315   assert(I.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
2316          "Expected G_CONSTANT");
2317   addNumImm(I.getOperand(1).getCImm()->getValue(), MIB);
2318 }
2319 
2320 std::pair<Register, bool>
2321 SPIRVInstructionSelector::buildI32Constant(uint32_t Val, MachineInstr &I,
2322                                            const SPIRVType *ResType) const {
2323   Type *LLVMTy = IntegerType::get(GR.CurMF->getFunction().getContext(), 32);
2324   const SPIRVType *SpvI32Ty =
2325       ResType ? ResType : GR.getOrCreateSPIRVIntegerType(32, I, TII);
2326   // Find a constant in DT or build a new one.
2327   auto ConstInt = ConstantInt::get(LLVMTy, Val);
2328   Register NewReg = GR.find(ConstInt, GR.CurMF);
2329   bool Result = true;
2330   if (!NewReg.isValid()) {
2331     NewReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
2332     GR.add(ConstInt, GR.CurMF, NewReg);
2333     MachineInstr *MI;
2334     MachineBasicBlock &BB = *I.getParent();
2335     if (Val == 0) {
2336       MI = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
2337                .addDef(NewReg)
2338                .addUse(GR.getSPIRVTypeID(SpvI32Ty));
2339     } else {
2340       MI = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
2341                .addDef(NewReg)
2342                .addUse(GR.getSPIRVTypeID(SpvI32Ty))
2343                .addImm(APInt(32, Val).getZExtValue());
2344     }
2345     Result &= constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
2346   }
2347   return {NewReg, Result};
2348 }
2349 
2350 bool SPIRVInstructionSelector::selectFCmp(Register ResVReg,
2351                                           const SPIRVType *ResType,
2352                                           MachineInstr &I) const {
2353   unsigned CmpOp = getFCmpOpcode(I.getOperand(1).getPredicate());
2354   return selectCmp(ResVReg, ResType, CmpOp, I);
2355 }
2356 
2357 Register SPIRVInstructionSelector::buildZerosVal(const SPIRVType *ResType,
2358                                                  MachineInstr &I) const {
2359   // OpenCL uses nulls for Zero. In HLSL we don't use null constants.
2360   bool ZeroAsNull = STI.isOpenCLEnv();
2361   if (ResType->getOpcode() == SPIRV::OpTypeVector)
2362     return GR.getOrCreateConstVector(0UL, I, ResType, TII, ZeroAsNull);
2363   return GR.getOrCreateConstInt(0, I, ResType, TII, ZeroAsNull);
2364 }
2365 
2366 Register SPIRVInstructionSelector::buildZerosValF(const SPIRVType *ResType,
2367                                                   MachineInstr &I) const {
2368   // OpenCL uses nulls for Zero. In HLSL we don't use null constants.
2369   bool ZeroAsNull = STI.isOpenCLEnv();
2370   APFloat VZero = getZeroFP(GR.getTypeForSPIRVType(ResType));
2371   if (ResType->getOpcode() == SPIRV::OpTypeVector)
2372     return GR.getOrCreateConstVector(VZero, I, ResType, TII, ZeroAsNull);
2373   return GR.getOrCreateConstFP(VZero, I, ResType, TII, ZeroAsNull);
2374 }
2375 
2376 Register SPIRVInstructionSelector::buildOnesValF(const SPIRVType *ResType,
2377                                                  MachineInstr &I) const {
2378   // OpenCL uses nulls for Zero. In HLSL we don't use null constants.
2379   bool ZeroAsNull = STI.isOpenCLEnv();
2380   APFloat VOne = getOneFP(GR.getTypeForSPIRVType(ResType));
2381   if (ResType->getOpcode() == SPIRV::OpTypeVector)
2382     return GR.getOrCreateConstVector(VOne, I, ResType, TII, ZeroAsNull);
2383   return GR.getOrCreateConstFP(VOne, I, ResType, TII, ZeroAsNull);
2384 }
2385 
2386 Register SPIRVInstructionSelector::buildOnesVal(bool AllOnes,
2387                                                 const SPIRVType *ResType,
2388                                                 MachineInstr &I) const {
2389   unsigned BitWidth = GR.getScalarOrVectorBitWidth(ResType);
2390   APInt One =
2391       AllOnes ? APInt::getAllOnes(BitWidth) : APInt::getOneBitSet(BitWidth, 0);
2392   if (ResType->getOpcode() == SPIRV::OpTypeVector)
2393     return GR.getOrCreateConstVector(One.getZExtValue(), I, ResType, TII);
2394   return GR.getOrCreateConstInt(One.getZExtValue(), I, ResType, TII);
2395 }
2396 
2397 bool SPIRVInstructionSelector::selectSelect(Register ResVReg,
2398                                             const SPIRVType *ResType,
2399                                             MachineInstr &I,
2400                                             bool IsSigned) const {
2401   // To extend a bool, we need to use OpSelect between constants.
2402   Register ZeroReg = buildZerosVal(ResType, I);
2403   Register OneReg = buildOnesVal(IsSigned, ResType, I);
2404   bool IsScalarBool =
2405       GR.isScalarOfType(I.getOperand(1).getReg(), SPIRV::OpTypeBool);
2406   unsigned Opcode =
2407       IsScalarBool ? SPIRV::OpSelectSISCond : SPIRV::OpSelectVIVCond;
2408   return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode))
2409       .addDef(ResVReg)
2410       .addUse(GR.getSPIRVTypeID(ResType))
2411       .addUse(I.getOperand(1).getReg())
2412       .addUse(OneReg)
2413       .addUse(ZeroReg)
2414       .constrainAllUses(TII, TRI, RBI);
2415 }
2416 
2417 bool SPIRVInstructionSelector::selectIToF(Register ResVReg,
2418                                           const SPIRVType *ResType,
2419                                           MachineInstr &I, bool IsSigned,
2420                                           unsigned Opcode) const {
2421   Register SrcReg = I.getOperand(1).getReg();
2422   // We can convert bool value directly to float type without OpConvert*ToF,
2423   // however the translator generates OpSelect+OpConvert*ToF, so we do the same.
2424   if (GR.isScalarOrVectorOfType(I.getOperand(1).getReg(), SPIRV::OpTypeBool)) {
2425     unsigned BitWidth = GR.getScalarOrVectorBitWidth(ResType);
2426     SPIRVType *TmpType = GR.getOrCreateSPIRVIntegerType(BitWidth, I, TII);
2427     if (ResType->getOpcode() == SPIRV::OpTypeVector) {
2428       const unsigned NumElts = ResType->getOperand(2).getImm();
2429       TmpType = GR.getOrCreateSPIRVVectorType(TmpType, NumElts, I, TII);
2430     }
2431     SrcReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
2432     selectSelect(SrcReg, TmpType, I, false);
2433   }
2434   return selectOpWithSrcs(ResVReg, ResType, I, {SrcReg}, Opcode);
2435 }
2436 
2437 bool SPIRVInstructionSelector::selectExt(Register ResVReg,
2438                                          const SPIRVType *ResType,
2439                                          MachineInstr &I, bool IsSigned) const {
2440   Register SrcReg = I.getOperand(1).getReg();
2441   if (GR.isScalarOrVectorOfType(SrcReg, SPIRV::OpTypeBool))
2442     return selectSelect(ResVReg, ResType, I, IsSigned);
2443 
2444   SPIRVType *SrcType = GR.getSPIRVTypeForVReg(SrcReg);
2445   if (SrcType == ResType)
2446     return BuildCOPY(ResVReg, SrcReg, I);
2447 
2448   unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
2449   return selectUnOp(ResVReg, ResType, I, Opcode);
2450 }
2451 
2452 bool SPIRVInstructionSelector::selectSUCmp(Register ResVReg,
2453                                            const SPIRVType *ResType,
2454                                            MachineInstr &I,
2455                                            bool IsSigned) const {
2456   MachineIRBuilder MIRBuilder(I);
2457   MachineRegisterInfo *MRI = MIRBuilder.getMRI();
2458   MachineBasicBlock &BB = *I.getParent();
2459   // Ensure we have bool.
2460   SPIRVType *BoolType = GR.getOrCreateSPIRVBoolType(I, TII);
2461   unsigned N = GR.getScalarOrVectorComponentCount(ResType);
2462   if (N > 1)
2463     BoolType = GR.getOrCreateSPIRVVectorType(BoolType, N, I, TII);
2464   Register BoolTypeReg = GR.getSPIRVTypeID(BoolType);
2465   // Build less-than-equal and less-than.
2466   // TODO: replace with one-liner createVirtualRegister() from
2467   // llvm/lib/Target/SPIRV/SPIRVUtils.cpp when PR #116609 is merged.
2468   Register IsLessEqReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
2469   MRI->setType(IsLessEqReg, LLT::scalar(64));
2470   GR.assignSPIRVTypeToVReg(ResType, IsLessEqReg, MIRBuilder.getMF());
2471   bool Result = BuildMI(BB, I, I.getDebugLoc(),
2472                         TII.get(IsSigned ? SPIRV::OpSLessThanEqual
2473                                          : SPIRV::OpULessThanEqual))
2474                     .addDef(IsLessEqReg)
2475                     .addUse(BoolTypeReg)
2476                     .addUse(I.getOperand(1).getReg())
2477                     .addUse(I.getOperand(2).getReg())
2478                     .constrainAllUses(TII, TRI, RBI);
2479   Register IsLessReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
2480   MRI->setType(IsLessReg, LLT::scalar(64));
2481   GR.assignSPIRVTypeToVReg(ResType, IsLessReg, MIRBuilder.getMF());
2482   Result &= BuildMI(BB, I, I.getDebugLoc(),
2483                     TII.get(IsSigned ? SPIRV::OpSLessThan : SPIRV::OpULessThan))
2484                 .addDef(IsLessReg)
2485                 .addUse(BoolTypeReg)
2486                 .addUse(I.getOperand(1).getReg())
2487                 .addUse(I.getOperand(2).getReg())
2488                 .constrainAllUses(TII, TRI, RBI);
2489   // Build selects.
2490   Register ResTypeReg = GR.getSPIRVTypeID(ResType);
2491   Register NegOneOrZeroReg =
2492       MRI->createVirtualRegister(GR.getRegClass(ResType));
2493   MRI->setType(NegOneOrZeroReg, LLT::scalar(64));
2494   GR.assignSPIRVTypeToVReg(ResType, NegOneOrZeroReg, MIRBuilder.getMF());
2495   unsigned SelectOpcode =
2496       N > 1 ? SPIRV::OpSelectVIVCond : SPIRV::OpSelectSISCond;
2497   Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(SelectOpcode))
2498                 .addDef(NegOneOrZeroReg)
2499                 .addUse(ResTypeReg)
2500                 .addUse(IsLessReg)
2501                 .addUse(buildOnesVal(true, ResType, I)) // -1
2502                 .addUse(buildZerosVal(ResType, I))
2503                 .constrainAllUses(TII, TRI, RBI);
2504   return Result & BuildMI(BB, I, I.getDebugLoc(), TII.get(SelectOpcode))
2505                       .addDef(ResVReg)
2506                       .addUse(ResTypeReg)
2507                       .addUse(IsLessEqReg)
2508                       .addUse(NegOneOrZeroReg) // -1 or 0
2509                       .addUse(buildOnesVal(false, ResType, I))
2510                       .constrainAllUses(TII, TRI, RBI);
2511 }
2512 
2513 bool SPIRVInstructionSelector::selectIntToBool(Register IntReg,
2514                                                Register ResVReg,
2515                                                MachineInstr &I,
2516                                                const SPIRVType *IntTy,
2517                                                const SPIRVType *BoolTy) const {
2518   // To truncate to a bool, we use OpBitwiseAnd 1 and OpINotEqual to zero.
2519   Register BitIntReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
2520   bool IsVectorTy = IntTy->getOpcode() == SPIRV::OpTypeVector;
2521   unsigned Opcode = IsVectorTy ? SPIRV::OpBitwiseAndV : SPIRV::OpBitwiseAndS;
2522   Register Zero = buildZerosVal(IntTy, I);
2523   Register One = buildOnesVal(false, IntTy, I);
2524   MachineBasicBlock &BB = *I.getParent();
2525   bool Result = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
2526                     .addDef(BitIntReg)
2527                     .addUse(GR.getSPIRVTypeID(IntTy))
2528                     .addUse(IntReg)
2529                     .addUse(One)
2530                     .constrainAllUses(TII, TRI, RBI);
2531   return Result && BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpINotEqual))
2532                        .addDef(ResVReg)
2533                        .addUse(GR.getSPIRVTypeID(BoolTy))
2534                        .addUse(BitIntReg)
2535                        .addUse(Zero)
2536                        .constrainAllUses(TII, TRI, RBI);
2537 }
2538 
2539 bool SPIRVInstructionSelector::selectTrunc(Register ResVReg,
2540                                            const SPIRVType *ResType,
2541                                            MachineInstr &I) const {
2542   Register IntReg = I.getOperand(1).getReg();
2543   const SPIRVType *ArgType = GR.getSPIRVTypeForVReg(IntReg);
2544   if (GR.isScalarOrVectorOfType(ResVReg, SPIRV::OpTypeBool))
2545     return selectIntToBool(IntReg, ResVReg, I, ArgType, ResType);
2546   if (ArgType == ResType)
2547     return BuildCOPY(ResVReg, IntReg, I);
2548   bool IsSigned = GR.isScalarOrVectorSigned(ResType);
2549   unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
2550   return selectUnOp(ResVReg, ResType, I, Opcode);
2551 }
2552 
2553 bool SPIRVInstructionSelector::selectConst(Register ResVReg,
2554                                            const SPIRVType *ResType,
2555                                            const APInt &Imm,
2556                                            MachineInstr &I) const {
2557   unsigned TyOpcode = ResType->getOpcode();
2558   assert(TyOpcode != SPIRV::OpTypePointer || Imm.isZero());
2559   MachineBasicBlock &BB = *I.getParent();
2560   if ((TyOpcode == SPIRV::OpTypePointer || TyOpcode == SPIRV::OpTypeEvent) &&
2561       Imm.isZero())
2562     return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
2563         .addDef(ResVReg)
2564         .addUse(GR.getSPIRVTypeID(ResType))
2565         .constrainAllUses(TII, TRI, RBI);
2566   if (TyOpcode == SPIRV::OpTypeInt) {
2567     assert(Imm.getBitWidth() <= 64 && "Unsupported integer width!");
2568     Register Reg = GR.getOrCreateConstInt(Imm.getZExtValue(), I, ResType, TII);
2569     return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
2570   }
2571   auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
2572                  .addDef(ResVReg)
2573                  .addUse(GR.getSPIRVTypeID(ResType));
2574   // <=32-bit integers should be caught by the sdag pattern.
2575   assert(Imm.getBitWidth() > 32);
2576   addNumImm(Imm, MIB);
2577   return MIB.constrainAllUses(TII, TRI, RBI);
2578 }
2579 
2580 bool SPIRVInstructionSelector::selectOpUndef(Register ResVReg,
2581                                              const SPIRVType *ResType,
2582                                              MachineInstr &I) const {
2583   return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
2584       .addDef(ResVReg)
2585       .addUse(GR.getSPIRVTypeID(ResType))
2586       .constrainAllUses(TII, TRI, RBI);
2587 }
2588 
2589 static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
2590   assert(MO.isReg());
2591   const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
2592   if (TypeInst->getOpcode() == SPIRV::ASSIGN_TYPE) {
2593     assert(TypeInst->getOperand(1).isReg());
2594     MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
2595     return ImmInst->getOpcode() == TargetOpcode::G_CONSTANT;
2596   }
2597   return TypeInst->getOpcode() == SPIRV::OpConstantI;
2598 }
2599 
2600 static int64_t foldImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
2601   const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
2602   if (TypeInst->getOpcode() == SPIRV::OpConstantI)
2603     return TypeInst->getOperand(2).getImm();
2604   MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
2605   assert(ImmInst->getOpcode() == TargetOpcode::G_CONSTANT);
2606   return ImmInst->getOperand(1).getCImm()->getZExtValue();
2607 }
2608 
2609 bool SPIRVInstructionSelector::selectInsertVal(Register ResVReg,
2610                                                const SPIRVType *ResType,
2611                                                MachineInstr &I) const {
2612   MachineBasicBlock &BB = *I.getParent();
2613   auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeInsert))
2614                  .addDef(ResVReg)
2615                  .addUse(GR.getSPIRVTypeID(ResType))
2616                  // object to insert
2617                  .addUse(I.getOperand(3).getReg())
2618                  // composite to insert into
2619                  .addUse(I.getOperand(2).getReg());
2620   for (unsigned i = 4; i < I.getNumOperands(); i++)
2621     MIB.addImm(foldImm(I.getOperand(i), MRI));
2622   return MIB.constrainAllUses(TII, TRI, RBI);
2623 }
2624 
2625 bool SPIRVInstructionSelector::selectExtractVal(Register ResVReg,
2626                                                 const SPIRVType *ResType,
2627                                                 MachineInstr &I) const {
2628   MachineBasicBlock &BB = *I.getParent();
2629   auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract))
2630                  .addDef(ResVReg)
2631                  .addUse(GR.getSPIRVTypeID(ResType))
2632                  .addUse(I.getOperand(2).getReg());
2633   for (unsigned i = 3; i < I.getNumOperands(); i++)
2634     MIB.addImm(foldImm(I.getOperand(i), MRI));
2635   return MIB.constrainAllUses(TII, TRI, RBI);
2636 }
2637 
2638 bool SPIRVInstructionSelector::selectInsertElt(Register ResVReg,
2639                                                const SPIRVType *ResType,
2640                                                MachineInstr &I) const {
2641   if (isImm(I.getOperand(4), MRI))
2642     return selectInsertVal(ResVReg, ResType, I);
2643   MachineBasicBlock &BB = *I.getParent();
2644   return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpVectorInsertDynamic))
2645       .addDef(ResVReg)
2646       .addUse(GR.getSPIRVTypeID(ResType))
2647       .addUse(I.getOperand(2).getReg())
2648       .addUse(I.getOperand(3).getReg())
2649       .addUse(I.getOperand(4).getReg())
2650       .constrainAllUses(TII, TRI, RBI);
2651 }
2652 
2653 bool SPIRVInstructionSelector::selectExtractElt(Register ResVReg,
2654                                                 const SPIRVType *ResType,
2655                                                 MachineInstr &I) const {
2656   if (isImm(I.getOperand(3), MRI))
2657     return selectExtractVal(ResVReg, ResType, I);
2658   MachineBasicBlock &BB = *I.getParent();
2659   return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpVectorExtractDynamic))
2660       .addDef(ResVReg)
2661       .addUse(GR.getSPIRVTypeID(ResType))
2662       .addUse(I.getOperand(2).getReg())
2663       .addUse(I.getOperand(3).getReg())
2664       .constrainAllUses(TII, TRI, RBI);
2665 }
2666 
2667 bool SPIRVInstructionSelector::selectGEP(Register ResVReg,
2668                                          const SPIRVType *ResType,
2669                                          MachineInstr &I) const {
2670   const bool IsGEPInBounds = I.getOperand(2).getImm();
2671 
2672   // OpAccessChain could be used for OpenCL, but the SPIRV-LLVM Translator only
2673   // relies on PtrAccessChain, so we'll try not to deviate. For Vulkan however,
2674   // we have to use Op[InBounds]AccessChain.
2675   const unsigned Opcode = STI.isVulkanEnv()
2676                               ? (IsGEPInBounds ? SPIRV::OpInBoundsAccessChain
2677                                                : SPIRV::OpAccessChain)
2678                               : (IsGEPInBounds ? SPIRV::OpInBoundsPtrAccessChain
2679                                                : SPIRV::OpPtrAccessChain);
2680 
2681   auto Res = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode))
2682                  .addDef(ResVReg)
2683                  .addUse(GR.getSPIRVTypeID(ResType))
2684                  // Object to get a pointer to.
2685                  .addUse(I.getOperand(3).getReg());
2686   // Adding indices.
2687   const unsigned StartingIndex =
2688       (Opcode == SPIRV::OpAccessChain || Opcode == SPIRV::OpInBoundsAccessChain)
2689           ? 5
2690           : 4;
2691   for (unsigned i = StartingIndex; i < I.getNumExplicitOperands(); ++i)
2692     Res.addUse(I.getOperand(i).getReg());
2693   return Res.constrainAllUses(TII, TRI, RBI);
2694 }
2695 
2696 // Maybe wrap a value into OpSpecConstantOp
2697 bool SPIRVInstructionSelector::wrapIntoSpecConstantOp(
2698     MachineInstr &I, SmallVector<Register> &CompositeArgs) const {
2699   bool Result = true;
2700   unsigned Lim = I.getNumExplicitOperands();
2701   for (unsigned i = I.getNumExplicitDefs() + 1; i < Lim; ++i) {
2702     Register OpReg = I.getOperand(i).getReg();
2703     SPIRVType *OpDefine = MRI->getVRegDef(OpReg);
2704     SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpReg);
2705     SmallPtrSet<SPIRVType *, 4> Visited;
2706     if (!OpDefine || !OpType || isConstReg(MRI, OpDefine, Visited) ||
2707         OpDefine->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST ||
2708         GR.isAggregateType(OpType)) {
2709       // The case of G_ADDRSPACE_CAST inside spv_const_composite() is processed
2710       // by selectAddrSpaceCast()
2711       CompositeArgs.push_back(OpReg);
2712       continue;
2713     }
2714     MachineFunction *MF = I.getMF();
2715     Register WrapReg = GR.find(OpDefine, MF);
2716     if (WrapReg.isValid()) {
2717       CompositeArgs.push_back(WrapReg);
2718       continue;
2719     }
2720     // Create a new register for the wrapper
2721     WrapReg = MRI->createVirtualRegister(GR.getRegClass(OpType));
2722     GR.add(OpDefine, MF, WrapReg);
2723     CompositeArgs.push_back(WrapReg);
2724     // Decorate the wrapper register and generate a new instruction
2725     MRI->setType(WrapReg, LLT::pointer(0, 64));
2726     GR.assignSPIRVTypeToVReg(OpType, WrapReg, *MF);
2727     MachineBasicBlock &BB = *I.getParent();
2728     Result = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSpecConstantOp))
2729                  .addDef(WrapReg)
2730                  .addUse(GR.getSPIRVTypeID(OpType))
2731                  .addImm(static_cast<uint32_t>(SPIRV::Opcode::Bitcast))
2732                  .addUse(OpReg)
2733                  .constrainAllUses(TII, TRI, RBI);
2734     if (!Result)
2735       break;
2736   }
2737   return Result;
2738 }
2739 
2740 bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
2741                                                const SPIRVType *ResType,
2742                                                MachineInstr &I) const {
2743   MachineBasicBlock &BB = *I.getParent();
2744   Intrinsic::ID IID = cast<GIntrinsic>(I).getIntrinsicID();
2745   switch (IID) {
2746   case Intrinsic::spv_load:
2747     return selectLoad(ResVReg, ResType, I);
2748   case Intrinsic::spv_store:
2749     return selectStore(I);
2750   case Intrinsic::spv_extractv:
2751     return selectExtractVal(ResVReg, ResType, I);
2752   case Intrinsic::spv_insertv:
2753     return selectInsertVal(ResVReg, ResType, I);
2754   case Intrinsic::spv_extractelt:
2755     return selectExtractElt(ResVReg, ResType, I);
2756   case Intrinsic::spv_insertelt:
2757     return selectInsertElt(ResVReg, ResType, I);
2758   case Intrinsic::spv_gep:
2759     return selectGEP(ResVReg, ResType, I);
2760   case Intrinsic::spv_unref_global:
2761   case Intrinsic::spv_init_global: {
2762     MachineInstr *MI = MRI->getVRegDef(I.getOperand(1).getReg());
2763     MachineInstr *Init = I.getNumExplicitOperands() > 2
2764                              ? MRI->getVRegDef(I.getOperand(2).getReg())
2765                              : nullptr;
2766     assert(MI);
2767     return selectGlobalValue(MI->getOperand(0).getReg(), *MI, Init);
2768   }
2769   case Intrinsic::spv_undef: {
2770     auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
2771                    .addDef(ResVReg)
2772                    .addUse(GR.getSPIRVTypeID(ResType));
2773     return MIB.constrainAllUses(TII, TRI, RBI);
2774   }
2775   case Intrinsic::spv_const_composite: {
2776     // If no values are attached, the composite is null constant.
2777     bool IsNull = I.getNumExplicitDefs() + 1 == I.getNumExplicitOperands();
2778     // Select a proper instruction.
2779     unsigned Opcode = SPIRV::OpConstantNull;
2780     SmallVector<Register> CompositeArgs;
2781     if (!IsNull) {
2782       Opcode = SPIRV::OpConstantComposite;
2783       if (!wrapIntoSpecConstantOp(I, CompositeArgs))
2784         return false;
2785     }
2786     MRI->setRegClass(ResVReg, GR.getRegClass(ResType));
2787     auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
2788                    .addDef(ResVReg)
2789                    .addUse(GR.getSPIRVTypeID(ResType));
2790     // skip type MD node we already used when generated assign.type for this
2791     if (!IsNull) {
2792       for (Register OpReg : CompositeArgs)
2793         MIB.addUse(OpReg);
2794     }
2795     return MIB.constrainAllUses(TII, TRI, RBI);
2796   }
2797   case Intrinsic::spv_assign_name: {
2798     auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpName));
2799     MIB.addUse(I.getOperand(I.getNumExplicitDefs() + 1).getReg());
2800     for (unsigned i = I.getNumExplicitDefs() + 2;
2801          i < I.getNumExplicitOperands(); ++i) {
2802       MIB.addImm(I.getOperand(i).getImm());
2803     }
2804     return MIB.constrainAllUses(TII, TRI, RBI);
2805   }
2806   case Intrinsic::spv_switch: {
2807     auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSwitch));
2808     for (unsigned i = 1; i < I.getNumExplicitOperands(); ++i) {
2809       if (I.getOperand(i).isReg())
2810         MIB.addReg(I.getOperand(i).getReg());
2811       else if (I.getOperand(i).isCImm())
2812         addNumImm(I.getOperand(i).getCImm()->getValue(), MIB);
2813       else if (I.getOperand(i).isMBB())
2814         MIB.addMBB(I.getOperand(i).getMBB());
2815       else
2816         llvm_unreachable("Unexpected OpSwitch operand");
2817     }
2818     return MIB.constrainAllUses(TII, TRI, RBI);
2819   }
2820   case Intrinsic::spv_loop_merge:
2821   case Intrinsic::spv_selection_merge: {
2822     const auto Opcode = IID == Intrinsic::spv_selection_merge
2823                             ? SPIRV::OpSelectionMerge
2824                             : SPIRV::OpLoopMerge;
2825     auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode));
2826     for (unsigned i = 1; i < I.getNumExplicitOperands(); ++i) {
2827       assert(I.getOperand(i).isMBB());
2828       MIB.addMBB(I.getOperand(i).getMBB());
2829     }
2830     MIB.addImm(SPIRV::SelectionControl::None);
2831     return MIB.constrainAllUses(TII, TRI, RBI);
2832   }
2833   case Intrinsic::spv_cmpxchg:
2834     return selectAtomicCmpXchg(ResVReg, ResType, I);
2835   case Intrinsic::spv_unreachable:
2836     return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpUnreachable))
2837         .constrainAllUses(TII, TRI, RBI);
2838   case Intrinsic::spv_alloca:
2839     return selectFrameIndex(ResVReg, ResType, I);
2840   case Intrinsic::spv_alloca_array:
2841     return selectAllocaArray(ResVReg, ResType, I);
2842   case Intrinsic::spv_assume:
2843     if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume))
2844       return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpAssumeTrueKHR))
2845           .addUse(I.getOperand(1).getReg())
2846           .constrainAllUses(TII, TRI, RBI);
2847     break;
2848   case Intrinsic::spv_expect:
2849     if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume))
2850       return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpExpectKHR))
2851           .addDef(ResVReg)
2852           .addUse(GR.getSPIRVTypeID(ResType))
2853           .addUse(I.getOperand(2).getReg())
2854           .addUse(I.getOperand(3).getReg())
2855           .constrainAllUses(TII, TRI, RBI);
2856     break;
2857   case Intrinsic::arithmetic_fence:
2858     if (STI.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2859       return BuildMI(BB, I, I.getDebugLoc(),
2860                      TII.get(SPIRV::OpArithmeticFenceEXT))
2861           .addDef(ResVReg)
2862           .addUse(GR.getSPIRVTypeID(ResType))
2863           .addUse(I.getOperand(2).getReg())
2864           .constrainAllUses(TII, TRI, RBI);
2865     else
2866       return BuildCOPY(ResVReg, I.getOperand(2).getReg(), I);
2867     break;
2868   case Intrinsic::spv_thread_id:
2869     // The HLSL SV_DispatchThreadID semantic is lowered to llvm.spv.thread.id
2870     // intrinsic in LLVM IR for SPIR-V backend.
2871     //
2872     // In SPIR-V backend, llvm.spv.thread.id is now correctly translated to a
2873     // `GlobalInvocationId` builtin variable
2874     return loadVec3BuiltinInputID(SPIRV::BuiltIn::GlobalInvocationId, ResVReg,
2875                                   ResType, I);
2876   case Intrinsic::spv_thread_id_in_group:
2877     // The HLSL SV_GroupThreadId semantic is lowered to
2878     // llvm.spv.thread.id.in.group intrinsic in LLVM IR for SPIR-V backend.
2879     //
2880     // In SPIR-V backend, llvm.spv.thread.id.in.group is now correctly
2881     // translated to a `LocalInvocationId` builtin variable
2882     return loadVec3BuiltinInputID(SPIRV::BuiltIn::LocalInvocationId, ResVReg,
2883                                   ResType, I);
2884   case Intrinsic::spv_group_id:
2885     // The HLSL SV_GroupId semantic is lowered to
2886     // llvm.spv.group.id intrinsic in LLVM IR for SPIR-V backend.
2887     //
2888     // In SPIR-V backend, llvm.spv.group.id is now translated to a `WorkgroupId`
2889     // builtin variable
2890     return loadVec3BuiltinInputID(SPIRV::BuiltIn::WorkgroupId, ResVReg, ResType,
2891                                   I);
2892   case Intrinsic::spv_fdot:
2893     return selectFloatDot(ResVReg, ResType, I);
2894   case Intrinsic::spv_udot:
2895   case Intrinsic::spv_sdot:
2896     if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product) ||
2897         STI.isAtLeastSPIRVVer(VersionTuple(1, 6)))
2898       return selectIntegerDot(ResVReg, ResType, I,
2899                               /*Signed=*/IID == Intrinsic::spv_sdot);
2900     return selectIntegerDotExpansion(ResVReg, ResType, I);
2901   case Intrinsic::spv_dot4add_i8packed:
2902     if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product) ||
2903         STI.isAtLeastSPIRVVer(VersionTuple(1, 6)))
2904       return selectDot4AddPacked<true>(ResVReg, ResType, I);
2905     return selectDot4AddPackedExpansion<true>(ResVReg, ResType, I);
2906   case Intrinsic::spv_dot4add_u8packed:
2907     if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product) ||
2908         STI.isAtLeastSPIRVVer(VersionTuple(1, 6)))
2909       return selectDot4AddPacked<false>(ResVReg, ResType, I);
2910     return selectDot4AddPackedExpansion<false>(ResVReg, ResType, I);
2911   case Intrinsic::spv_all:
2912     return selectAll(ResVReg, ResType, I);
2913   case Intrinsic::spv_any:
2914     return selectAny(ResVReg, ResType, I);
2915   case Intrinsic::spv_cross:
2916     return selectExtInst(ResVReg, ResType, I, CL::cross, GL::Cross);
2917   case Intrinsic::spv_distance:
2918     return selectExtInst(ResVReg, ResType, I, CL::distance, GL::Distance);
2919   case Intrinsic::spv_lerp:
2920     return selectExtInst(ResVReg, ResType, I, CL::mix, GL::FMix);
2921   case Intrinsic::spv_length:
2922     return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
2923   case Intrinsic::spv_degrees:
2924     return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
2925   case Intrinsic::spv_frac:
2926     return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
2927   case Intrinsic::spv_normalize:
2928     return selectExtInst(ResVReg, ResType, I, CL::normalize, GL::Normalize);
2929   case Intrinsic::spv_rsqrt:
2930     return selectExtInst(ResVReg, ResType, I, CL::rsqrt, GL::InverseSqrt);
2931   case Intrinsic::spv_sign:
2932     return selectSign(ResVReg, ResType, I);
2933   case Intrinsic::spv_firstbituhigh: // There is no CL equivalent of FindUMsb
2934     return selectFirstBitHigh(ResVReg, ResType, I, /*IsSigned=*/false);
2935   case Intrinsic::spv_firstbitshigh: // There is no CL equivalent of FindSMsb
2936     return selectFirstBitHigh(ResVReg, ResType, I, /*IsSigned=*/true);
2937   case Intrinsic::spv_group_memory_barrier_with_group_sync: {
2938     bool Result = true;
2939     auto MemSemConstant =
2940         buildI32Constant(SPIRV::MemorySemantics::SequentiallyConsistent, I);
2941     Register MemSemReg = MemSemConstant.first;
2942     Result &= MemSemConstant.second;
2943     auto ScopeConstant = buildI32Constant(SPIRV::Scope::Workgroup, I);
2944     Register ScopeReg = ScopeConstant.first;
2945     Result &= ScopeConstant.second;
2946     MachineBasicBlock &BB = *I.getParent();
2947     return Result &&
2948            BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpControlBarrier))
2949                .addUse(ScopeReg)
2950                .addUse(ScopeReg)
2951                .addUse(MemSemReg)
2952                .constrainAllUses(TII, TRI, RBI);
2953   }
2954   case Intrinsic::spv_lifetime_start:
2955   case Intrinsic::spv_lifetime_end: {
2956     unsigned Op = IID == Intrinsic::spv_lifetime_start ? SPIRV::OpLifetimeStart
2957                                                        : SPIRV::OpLifetimeStop;
2958     int64_t Size = I.getOperand(I.getNumExplicitDefs() + 1).getImm();
2959     Register PtrReg = I.getOperand(I.getNumExplicitDefs() + 2).getReg();
2960     if (Size == -1)
2961       Size = 0;
2962     return BuildMI(BB, I, I.getDebugLoc(), TII.get(Op))
2963         .addUse(PtrReg)
2964         .addImm(Size)
2965         .constrainAllUses(TII, TRI, RBI);
2966   }
2967   case Intrinsic::spv_saturate:
2968     return selectSaturate(ResVReg, ResType, I);
2969   case Intrinsic::spv_nclamp:
2970     return selectExtInst(ResVReg, ResType, I, CL::fclamp, GL::NClamp);
2971   case Intrinsic::spv_uclamp:
2972     return selectExtInst(ResVReg, ResType, I, CL::u_clamp, GL::UClamp);
2973   case Intrinsic::spv_sclamp:
2974     return selectExtInst(ResVReg, ResType, I, CL::s_clamp, GL::SClamp);
2975   case Intrinsic::spv_wave_active_countbits:
2976     return selectWaveActiveCountBits(ResVReg, ResType, I);
2977   case Intrinsic::spv_wave_all:
2978     return selectWaveOpInst(ResVReg, ResType, I, SPIRV::OpGroupNonUniformAll);
2979   case Intrinsic::spv_wave_any:
2980     return selectWaveOpInst(ResVReg, ResType, I, SPIRV::OpGroupNonUniformAny);
2981   case Intrinsic::spv_wave_is_first_lane:
2982     return selectWaveOpInst(ResVReg, ResType, I, SPIRV::OpGroupNonUniformElect);
2983   case Intrinsic::spv_wave_readlane:
2984     return selectWaveOpInst(ResVReg, ResType, I,
2985                             SPIRV::OpGroupNonUniformShuffle);
2986   case Intrinsic::spv_step:
2987     return selectExtInst(ResVReg, ResType, I, CL::step, GL::Step);
2988   case Intrinsic::spv_radians:
2989     return selectExtInst(ResVReg, ResType, I, CL::radians, GL::Radians);
2990   // Discard intrinsics which we do not expect to actually represent code after
2991   // lowering or intrinsics which are not implemented but should not crash when
2992   // found in a customer's LLVM IR input.
2993   case Intrinsic::instrprof_increment:
2994   case Intrinsic::instrprof_increment_step:
2995   case Intrinsic::instrprof_value_profile:
2996     break;
2997   // Discard internal intrinsics.
2998   case Intrinsic::spv_value_md:
2999     break;
3000   case Intrinsic::spv_resource_handlefrombinding: {
3001     return selectHandleFromBinding(ResVReg, ResType, I);
3002   }
3003   case Intrinsic::spv_resource_store_typedbuffer: {
3004     selectImageWriteIntrinsic(I);
3005     return true;
3006   }
3007   case Intrinsic::spv_resource_load_typedbuffer: {
3008     selectReadImageIntrinsic(ResVReg, ResType, I);
3009     return true;
3010   }
3011   case Intrinsic::spv_discard: {
3012     return selectDiscard(ResVReg, ResType, I);
3013   }
3014   default: {
3015     std::string DiagMsg;
3016     raw_string_ostream OS(DiagMsg);
3017     I.print(OS);
3018     DiagMsg = "Intrinsic selection not implemented: " + DiagMsg;
3019     report_fatal_error(DiagMsg.c_str(), false);
3020   }
3021   }
3022   return true;
3023 }
3024 
3025 bool SPIRVInstructionSelector::selectHandleFromBinding(Register &ResVReg,
3026                                                        const SPIRVType *ResType,
3027                                                        MachineInstr &I) const {
3028 
3029   uint32_t Set = foldImm(I.getOperand(2), MRI);
3030   uint32_t Binding = foldImm(I.getOperand(3), MRI);
3031   uint32_t ArraySize = foldImm(I.getOperand(4), MRI);
3032   Register IndexReg = I.getOperand(5).getReg();
3033   bool IsNonUniform = ArraySize > 1 && foldImm(I.getOperand(6), MRI);
3034 
3035   MachineIRBuilder MIRBuilder(I);
3036   Register VarReg = buildPointerToResource(ResType, Set, Binding, ArraySize,
3037                                            IndexReg, IsNonUniform, MIRBuilder);
3038 
3039   if (IsNonUniform)
3040     buildOpDecorate(ResVReg, I, TII, SPIRV::Decoration::NonUniformEXT, {});
3041 
3042   // TODO: For now we assume the resource is an image, which needs to be
3043   // loaded to get the handle. That will not be true for storage buffers.
3044   return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpLoad))
3045       .addDef(ResVReg)
3046       .addUse(GR.getSPIRVTypeID(ResType))
3047       .addUse(VarReg)
3048       .constrainAllUses(TII, TRI, RBI);
3049 }
3050 
3051 void SPIRVInstructionSelector::selectReadImageIntrinsic(
3052     Register &ResVReg, const SPIRVType *ResType, MachineInstr &I) const {
3053 
3054   // If the load of the image is in a different basic block, then
3055   // this will generate invalid code. A proper solution is to move
3056   // the OpLoad from selectHandleFromBinding here. However, to do
3057   // that we will need to change the return type of the intrinsic.
3058   // We will do that when we can, but for now trying to move forward with other
3059   // issues.
3060   Register ImageReg = I.getOperand(2).getReg();
3061   assert(MRI->getVRegDef(ImageReg)->getParent() == I.getParent() &&
3062          "The image must be loaded in the same basic block as its use.");
3063 
3064   uint64_t ResultSize = GR.getScalarOrVectorComponentCount(ResType);
3065   if (ResultSize == 4) {
3066     BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpImageRead))
3067         .addDef(ResVReg)
3068         .addUse(GR.getSPIRVTypeID(ResType))
3069         .addUse(ImageReg)
3070         .addUse(I.getOperand(3).getReg());
3071     return;
3072   }
3073 
3074   SPIRVType *ReadType = widenTypeToVec4(ResType, I);
3075   Register ReadReg = MRI->createVirtualRegister(GR.getRegClass(ReadType));
3076   BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpImageRead))
3077       .addDef(ReadReg)
3078       .addUse(GR.getSPIRVTypeID(ReadType))
3079       .addUse(ImageReg)
3080       .addUse(I.getOperand(3).getReg());
3081 
3082   if (ResultSize == 1) {
3083     BuildMI(*I.getParent(), I, I.getDebugLoc(),
3084             TII.get(SPIRV::OpCompositeExtract))
3085         .addDef(ResVReg)
3086         .addUse(GR.getSPIRVTypeID(ResType))
3087         .addUse(ReadReg)
3088         .addImm(0);
3089     return;
3090   }
3091   extractSubvector(ResVReg, ResType, ReadReg, I);
3092 }
3093 
3094 void SPIRVInstructionSelector::extractSubvector(
3095     Register &ResVReg, const SPIRVType *ResType, Register &ReadReg,
3096     MachineInstr &InsertionPoint) const {
3097   SPIRVType *InputType = GR.getResultType(ReadReg);
3098   [[maybe_unused]] uint64_t InputSize =
3099       GR.getScalarOrVectorComponentCount(InputType);
3100   uint64_t ResultSize = GR.getScalarOrVectorComponentCount(ResType);
3101   assert(InputSize > 1 && "The input must be a vector.");
3102   assert(ResultSize > 1 && "The result must be a vector.");
3103   assert(ResultSize < InputSize &&
3104          "Cannot extract more element than there are in the input.");
3105   SmallVector<Register> ComponentRegisters;
3106   SPIRVType *ScalarType = GR.getScalarOrVectorComponentType(ResType);
3107   const TargetRegisterClass *ScalarRegClass = GR.getRegClass(ScalarType);
3108   for (uint64_t I = 0; I < ResultSize; I++) {
3109     Register ComponentReg = MRI->createVirtualRegister(ScalarRegClass);
3110     BuildMI(*InsertionPoint.getParent(), InsertionPoint,
3111             InsertionPoint.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract))
3112         .addDef(ComponentReg)
3113         .addUse(ScalarType->getOperand(0).getReg())
3114         .addUse(ReadReg)
3115         .addImm(I);
3116     ComponentRegisters.emplace_back(ComponentReg);
3117   }
3118 
3119   MachineInstrBuilder MIB = BuildMI(*InsertionPoint.getParent(), InsertionPoint,
3120                                     InsertionPoint.getDebugLoc(),
3121                                     TII.get(SPIRV::OpCompositeConstruct))
3122                                 .addDef(ResVReg)
3123                                 .addUse(GR.getSPIRVTypeID(ResType));
3124 
3125   for (Register ComponentReg : ComponentRegisters)
3126     MIB.addUse(ComponentReg);
3127 }
3128 
3129 void SPIRVInstructionSelector::selectImageWriteIntrinsic(
3130     MachineInstr &I) const {
3131   // If the load of the image is in a different basic block, then
3132   // this will generate invalid code. A proper solution is to move
3133   // the OpLoad from selectHandleFromBinding here. However, to do
3134   // that we will need to change the return type of the intrinsic.
3135   // We will do that when we can, but for now trying to move forward with other
3136   // issues.
3137   Register ImageReg = I.getOperand(1).getReg();
3138   assert(MRI->getVRegDef(ImageReg)->getParent() == I.getParent() &&
3139          "The image must be loaded in the same basic block as its use.");
3140   Register CoordinateReg = I.getOperand(2).getReg();
3141   Register DataReg = I.getOperand(3).getReg();
3142   assert(GR.getResultType(DataReg)->getOpcode() == SPIRV::OpTypeVector);
3143   assert(GR.getScalarOrVectorComponentCount(GR.getResultType(DataReg)) == 4);
3144   BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpImageWrite))
3145       .addUse(ImageReg)
3146       .addUse(CoordinateReg)
3147       .addUse(DataReg);
3148 }
3149 
3150 Register SPIRVInstructionSelector::buildPointerToResource(
3151     const SPIRVType *ResType, uint32_t Set, uint32_t Binding,
3152     uint32_t ArraySize, Register IndexReg, bool IsNonUniform,
3153     MachineIRBuilder MIRBuilder) const {
3154   if (ArraySize == 1)
3155     return GR.getOrCreateGlobalVariableWithBinding(ResType, Set, Binding,
3156                                                    MIRBuilder);
3157 
3158   const SPIRVType *VarType = GR.getOrCreateSPIRVArrayType(
3159       ResType, ArraySize, *MIRBuilder.getInsertPt(), TII);
3160   Register VarReg = GR.getOrCreateGlobalVariableWithBinding(
3161       VarType, Set, Binding, MIRBuilder);
3162 
3163   SPIRVType *ResPointerType = GR.getOrCreateSPIRVPointerType(
3164       ResType, MIRBuilder, SPIRV::StorageClass::UniformConstant);
3165 
3166   Register AcReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
3167   if (IsNonUniform) {
3168     // It is unclear which value needs to be marked an non-uniform, so both
3169     // the index and the access changed are decorated as non-uniform.
3170     buildOpDecorate(IndexReg, MIRBuilder, SPIRV::Decoration::NonUniformEXT, {});
3171     buildOpDecorate(AcReg, MIRBuilder, SPIRV::Decoration::NonUniformEXT, {});
3172   }
3173 
3174   MIRBuilder.buildInstr(SPIRV::OpAccessChain)
3175       .addDef(AcReg)
3176       .addUse(GR.getSPIRVTypeID(ResPointerType))
3177       .addUse(VarReg)
3178       .addUse(IndexReg);
3179 
3180   return AcReg;
3181 }
3182 
3183 bool SPIRVInstructionSelector::selectFirstBitHigh16(Register ResVReg,
3184                                                     const SPIRVType *ResType,
3185                                                     MachineInstr &I,
3186                                                     bool IsSigned) const {
3187   unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
3188   // zero or sign extend
3189   Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
3190   bool Result =
3191       selectOpWithSrcs(ExtReg, ResType, I, {I.getOperand(2).getReg()}, Opcode);
3192   return Result && selectFirstBitHigh32(ResVReg, ResType, I, ExtReg, IsSigned);
3193 }
3194 
3195 bool SPIRVInstructionSelector::selectFirstBitHigh32(Register ResVReg,
3196                                                     const SPIRVType *ResType,
3197                                                     MachineInstr &I,
3198                                                     Register SrcReg,
3199                                                     bool IsSigned) const {
3200   unsigned Opcode = IsSigned ? GL::FindSMsb : GL::FindUMsb;
3201   return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst))
3202       .addDef(ResVReg)
3203       .addUse(GR.getSPIRVTypeID(ResType))
3204       .addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
3205       .addImm(Opcode)
3206       .addUse(SrcReg)
3207       .constrainAllUses(TII, TRI, RBI);
3208 }
3209 
3210 bool SPIRVInstructionSelector::selectFirstBitHigh64(Register ResVReg,
3211                                                     const SPIRVType *ResType,
3212                                                     MachineInstr &I,
3213                                                     bool IsSigned) const {
3214   Register OpReg = I.getOperand(2).getReg();
3215   // 1. split our int64 into 2 pieces using a bitcast
3216   unsigned count = GR.getScalarOrVectorComponentCount(ResType);
3217   SPIRVType *baseType = GR.retrieveScalarOrVectorIntType(ResType);
3218   MachineIRBuilder MIRBuilder(I);
3219   SPIRVType *postCastT =
3220       GR.getOrCreateSPIRVVectorType(baseType, 2 * count, MIRBuilder);
3221   Register bitcastReg = MRI->createVirtualRegister(GR.getRegClass(postCastT));
3222   bool Result =
3223       selectOpWithSrcs(bitcastReg, postCastT, I, {OpReg}, SPIRV::OpBitcast);
3224 
3225   // 2. call firstbithigh
3226   Register FBHReg = MRI->createVirtualRegister(GR.getRegClass(postCastT));
3227   Result &= selectFirstBitHigh32(FBHReg, postCastT, I, bitcastReg, IsSigned);
3228 
3229   // 3. split result vector into high bits and low bits
3230   Register HighReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
3231   Register LowReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
3232 
3233   bool ZeroAsNull = STI.isOpenCLEnv();
3234   bool isScalarRes = ResType->getOpcode() != SPIRV::OpTypeVector;
3235   if (isScalarRes) {
3236     // if scalar do a vector extract
3237     Result &= selectOpWithSrcs(
3238         HighReg, ResType, I,
3239         {FBHReg, GR.getOrCreateConstInt(0, I, ResType, TII, ZeroAsNull)},
3240         SPIRV::OpVectorExtractDynamic);
3241     Result &= selectOpWithSrcs(
3242         LowReg, ResType, I,
3243         {FBHReg, GR.getOrCreateConstInt(1, I, ResType, TII, ZeroAsNull)},
3244         SPIRV::OpVectorExtractDynamic);
3245   } else { // vector case do a shufflevector
3246     auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
3247                        TII.get(SPIRV::OpVectorShuffle))
3248                    .addDef(HighReg)
3249                    .addUse(GR.getSPIRVTypeID(ResType))
3250                    .addUse(FBHReg)
3251                    .addUse(FBHReg);
3252     // ^^ this vector will not be selected from; could be empty
3253     unsigned j;
3254     for (j = 0; j < count * 2; j += 2) {
3255       MIB.addImm(j);
3256     }
3257     Result &= MIB.constrainAllUses(TII, TRI, RBI);
3258 
3259     // get low bits
3260     MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
3261                   TII.get(SPIRV::OpVectorShuffle))
3262               .addDef(LowReg)
3263               .addUse(GR.getSPIRVTypeID(ResType))
3264               .addUse(FBHReg)
3265               .addUse(FBHReg);
3266     // ^^ this vector will not be selected from; could be empty
3267     for (j = 1; j < count * 2; j += 2) {
3268       MIB.addImm(j);
3269     }
3270     Result &= MIB.constrainAllUses(TII, TRI, RBI);
3271   }
3272 
3273   // 4. check if result of each top 32 bits is == -1
3274   SPIRVType *BoolType = GR.getOrCreateSPIRVBoolType(I, TII);
3275   Register NegOneReg;
3276   Register Reg0;
3277   Register Reg32;
3278   unsigned selectOp;
3279   unsigned addOp;
3280   if (isScalarRes) {
3281     NegOneReg =
3282         GR.getOrCreateConstInt((unsigned)-1, I, ResType, TII, ZeroAsNull);
3283     Reg0 = GR.getOrCreateConstInt(0, I, ResType, TII, ZeroAsNull);
3284     Reg32 = GR.getOrCreateConstInt(32, I, ResType, TII, ZeroAsNull);
3285     selectOp = SPIRV::OpSelectSISCond;
3286     addOp = SPIRV::OpIAddS;
3287   } else {
3288     BoolType = GR.getOrCreateSPIRVVectorType(BoolType, count, MIRBuilder);
3289     NegOneReg =
3290         GR.getOrCreateConstVector((unsigned)-1, I, ResType, TII, ZeroAsNull);
3291     Reg0 = GR.getOrCreateConstVector(0, I, ResType, TII, ZeroAsNull);
3292     Reg32 = GR.getOrCreateConstVector(32, I, ResType, TII, ZeroAsNull);
3293     selectOp = SPIRV::OpSelectVIVCond;
3294     addOp = SPIRV::OpIAddV;
3295   }
3296 
3297   // check if the high bits are == -1; true if -1
3298   Register BReg = MRI->createVirtualRegister(GR.getRegClass(BoolType));
3299   Result &= selectOpWithSrcs(BReg, BoolType, I, {HighReg, NegOneReg},
3300                              SPIRV::OpIEqual);
3301 
3302   // Select low bits if true in BReg, otherwise high bits
3303   Register TmpReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
3304   Result &=
3305       selectOpWithSrcs(TmpReg, ResType, I, {BReg, LowReg, HighReg}, selectOp);
3306 
3307   // Add 32 for high bits, 0 for low bits
3308   Register ValReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
3309   Result &= selectOpWithSrcs(ValReg, ResType, I, {BReg, Reg0, Reg32}, selectOp);
3310 
3311   return Result &&
3312          selectOpWithSrcs(ResVReg, ResType, I, {ValReg, TmpReg}, addOp);
3313 }
3314 
3315 bool SPIRVInstructionSelector::selectFirstBitHigh(Register ResVReg,
3316                                                   const SPIRVType *ResType,
3317                                                   MachineInstr &I,
3318                                                   bool IsSigned) const {
3319   // FindUMsb and FindSMsb intrinsics only support 32 bit integers
3320   Register OpReg = I.getOperand(2).getReg();
3321   SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpReg);
3322 
3323   switch (GR.getScalarOrVectorBitWidth(OpType)) {
3324   case 16:
3325     return selectFirstBitHigh16(ResVReg, ResType, I, IsSigned);
3326   case 32:
3327     return selectFirstBitHigh32(ResVReg, ResType, I, OpReg, IsSigned);
3328   case 64:
3329     return selectFirstBitHigh64(ResVReg, ResType, I, IsSigned);
3330   default:
3331     report_fatal_error(
3332         "spv_firstbituhigh and spv_firstbitshigh only support 16,32,64 bits.");
3333   }
3334 }
3335 
3336 bool SPIRVInstructionSelector::selectAllocaArray(Register ResVReg,
3337                                                  const SPIRVType *ResType,
3338                                                  MachineInstr &I) const {
3339   // there was an allocation size parameter to the allocation instruction
3340   // that is not 1
3341   MachineBasicBlock &BB = *I.getParent();
3342   bool Res = BuildMI(BB, I, I.getDebugLoc(),
3343                      TII.get(SPIRV::OpVariableLengthArrayINTEL))
3344                  .addDef(ResVReg)
3345                  .addUse(GR.getSPIRVTypeID(ResType))
3346                  .addUse(I.getOperand(2).getReg())
3347                  .constrainAllUses(TII, TRI, RBI);
3348   if (!STI.isVulkanEnv()) {
3349     unsigned Alignment = I.getOperand(3).getImm();
3350     buildOpDecorate(ResVReg, I, TII, SPIRV::Decoration::Alignment, {Alignment});
3351   }
3352   return Res;
3353 }
3354 
3355 bool SPIRVInstructionSelector::selectFrameIndex(Register ResVReg,
3356                                                 const SPIRVType *ResType,
3357                                                 MachineInstr &I) const {
3358   // Change order of instructions if needed: all OpVariable instructions in a
3359   // function must be the first instructions in the first block
3360   auto It = getOpVariableMBBIt(I);
3361   bool Res = BuildMI(*It->getParent(), It, It->getDebugLoc(),
3362                      TII.get(SPIRV::OpVariable))
3363                  .addDef(ResVReg)
3364                  .addUse(GR.getSPIRVTypeID(ResType))
3365                  .addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function))
3366                  .constrainAllUses(TII, TRI, RBI);
3367   if (!STI.isVulkanEnv()) {
3368     unsigned Alignment = I.getOperand(2).getImm();
3369     buildOpDecorate(ResVReg, *It, TII, SPIRV::Decoration::Alignment,
3370                     {Alignment});
3371   }
3372   return Res;
3373 }
3374 
3375 bool SPIRVInstructionSelector::selectBranch(MachineInstr &I) const {
3376   // InstructionSelector walks backwards through the instructions. We can use
3377   // both a G_BR and a G_BRCOND to create an OpBranchConditional. We hit G_BR
3378   // first, so can generate an OpBranchConditional here. If there is no
3379   // G_BRCOND, we just use OpBranch for a regular unconditional branch.
3380   const MachineInstr *PrevI = I.getPrevNode();
3381   MachineBasicBlock &MBB = *I.getParent();
3382   if (PrevI != nullptr && PrevI->getOpcode() == TargetOpcode::G_BRCOND) {
3383     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(SPIRV::OpBranchConditional))
3384         .addUse(PrevI->getOperand(0).getReg())
3385         .addMBB(PrevI->getOperand(1).getMBB())
3386         .addMBB(I.getOperand(0).getMBB())
3387         .constrainAllUses(TII, TRI, RBI);
3388   }
3389   return BuildMI(MBB, I, I.getDebugLoc(), TII.get(SPIRV::OpBranch))
3390       .addMBB(I.getOperand(0).getMBB())
3391       .constrainAllUses(TII, TRI, RBI);
3392 }
3393 
3394 bool SPIRVInstructionSelector::selectBranchCond(MachineInstr &I) const {
3395   // InstructionSelector walks backwards through the instructions. For an
3396   // explicit conditional branch with no fallthrough, we use both a G_BR and a
3397   // G_BRCOND to create an OpBranchConditional. We should hit G_BR first, and
3398   // generate the OpBranchConditional in selectBranch above.
3399   //
3400   // If an OpBranchConditional has been generated, we simply return, as the work
3401   // is alread done. If there is no OpBranchConditional, LLVM must be relying on
3402   // implicit fallthrough to the next basic block, so we need to create an
3403   // OpBranchConditional with an explicit "false" argument pointing to the next
3404   // basic block that LLVM would fall through to.
3405   const MachineInstr *NextI = I.getNextNode();
3406   // Check if this has already been successfully selected.
3407   if (NextI != nullptr && NextI->getOpcode() == SPIRV::OpBranchConditional)
3408     return true;
3409   // Must be relying on implicit block fallthrough, so generate an
3410   // OpBranchConditional with the "next" basic block as the "false" target.
3411   MachineBasicBlock &MBB = *I.getParent();
3412   unsigned NextMBBNum = MBB.getNextNode()->getNumber();
3413   MachineBasicBlock *NextMBB = I.getMF()->getBlockNumbered(NextMBBNum);
3414   return BuildMI(MBB, I, I.getDebugLoc(), TII.get(SPIRV::OpBranchConditional))
3415       .addUse(I.getOperand(0).getReg())
3416       .addMBB(I.getOperand(1).getMBB())
3417       .addMBB(NextMBB)
3418       .constrainAllUses(TII, TRI, RBI);
3419 }
3420 
3421 bool SPIRVInstructionSelector::selectPhi(Register ResVReg,
3422                                          const SPIRVType *ResType,
3423                                          MachineInstr &I) const {
3424   auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpPhi))
3425                  .addDef(ResVReg)
3426                  .addUse(GR.getSPIRVTypeID(ResType));
3427   const unsigned NumOps = I.getNumOperands();
3428   for (unsigned i = 1; i < NumOps; i += 2) {
3429     MIB.addUse(I.getOperand(i + 0).getReg());
3430     MIB.addMBB(I.getOperand(i + 1).getMBB());
3431   }
3432   bool Res = MIB.constrainAllUses(TII, TRI, RBI);
3433   MIB->setDesc(TII.get(TargetOpcode::PHI));
3434   MIB->removeOperand(1);
3435   return Res;
3436 }
3437 
3438 bool SPIRVInstructionSelector::selectGlobalValue(
3439     Register ResVReg, MachineInstr &I, const MachineInstr *Init) const {
3440   // FIXME: don't use MachineIRBuilder here, replace it with BuildMI.
3441   MachineIRBuilder MIRBuilder(I);
3442   const GlobalValue *GV = I.getOperand(1).getGlobal();
3443   Type *GVType = toTypedPointer(GR.getDeducedGlobalValueType(GV));
3444   SPIRVType *PointerBaseType;
3445   if (GVType->isArrayTy()) {
3446     SPIRVType *ArrayElementType =
3447         GR.getOrCreateSPIRVType(GVType->getArrayElementType(), MIRBuilder,
3448                                 SPIRV::AccessQualifier::ReadWrite, false);
3449     PointerBaseType = GR.getOrCreateSPIRVArrayType(
3450         ArrayElementType, GVType->getArrayNumElements(), I, TII);
3451   } else {
3452     PointerBaseType = GR.getOrCreateSPIRVType(
3453         GVType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, false);
3454   }
3455 
3456   std::string GlobalIdent;
3457   if (!GV->hasName()) {
3458     unsigned &ID = UnnamedGlobalIDs[GV];
3459     if (ID == 0)
3460       ID = UnnamedGlobalIDs.size();
3461     GlobalIdent = "__unnamed_" + Twine(ID).str();
3462   } else {
3463     GlobalIdent = GV->getGlobalIdentifier();
3464   }
3465 
3466   // Behaviour of functions as operands depends on availability of the
3467   // corresponding extension (SPV_INTEL_function_pointers):
3468   // - If there is an extension to operate with functions as operands:
3469   // We create a proper constant operand and evaluate a correct type for a
3470   // function pointer.
3471   // - Without the required extension:
3472   // We have functions as operands in tests with blocks of instruction e.g. in
3473   // transcoding/global_block.ll. These operands are not used and should be
3474   // substituted by zero constants. Their type is expected to be always
3475   // OpTypePointer Function %uchar.
3476   if (isa<Function>(GV)) {
3477     const Constant *ConstVal = GV;
3478     MachineBasicBlock &BB = *I.getParent();
3479     Register NewReg = GR.find(ConstVal, GR.CurMF);
3480     if (!NewReg.isValid()) {
3481       Register NewReg = ResVReg;
3482       GR.add(ConstVal, GR.CurMF, NewReg);
3483       const Function *GVFun =
3484           STI.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)
3485               ? dyn_cast<Function>(GV)
3486               : nullptr;
3487       SPIRVType *ResType = GR.getOrCreateSPIRVPointerType(
3488           PointerBaseType, I, TII,
3489           GVFun ? SPIRV::StorageClass::CodeSectionINTEL
3490                 : addressSpaceToStorageClass(GV->getAddressSpace(), STI));
3491       if (GVFun) {
3492         // References to a function via function pointers generate virtual
3493         // registers without a definition. We will resolve it later, during
3494         // module analysis stage.
3495         MachineRegisterInfo *MRI = MIRBuilder.getMRI();
3496         Register FuncVReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
3497         MRI->setRegClass(FuncVReg, &SPIRV::iIDRegClass);
3498         MachineInstrBuilder MB =
3499             BuildMI(BB, I, I.getDebugLoc(),
3500                     TII.get(SPIRV::OpConstantFunctionPointerINTEL))
3501                 .addDef(NewReg)
3502                 .addUse(GR.getSPIRVTypeID(ResType))
3503                 .addUse(FuncVReg);
3504         // mapping the function pointer to the used Function
3505         GR.recordFunctionPointer(&MB.getInstr()->getOperand(2), GVFun);
3506         return MB.constrainAllUses(TII, TRI, RBI);
3507       }
3508       return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
3509           .addDef(NewReg)
3510           .addUse(GR.getSPIRVTypeID(ResType))
3511           .constrainAllUses(TII, TRI, RBI);
3512     }
3513     assert(NewReg != ResVReg);
3514     return BuildCOPY(ResVReg, NewReg, I);
3515   }
3516   auto GlobalVar = cast<GlobalVariable>(GV);
3517   assert(GlobalVar->getName() != "llvm.global.annotations");
3518 
3519   bool HasInit = GlobalVar->hasInitializer() &&
3520                  !isa<UndefValue>(GlobalVar->getInitializer());
3521   // Skip empty declaration for GVs with initilaizers till we get the decl with
3522   // passed initializer.
3523   if (HasInit && !Init)
3524     return true;
3525 
3526   bool HasLnkTy = GV->getLinkage() != GlobalValue::InternalLinkage;
3527   SPIRV::LinkageType::LinkageType LnkType =
3528       (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
3529           ? SPIRV::LinkageType::Import
3530           : (GV->getLinkage() == GlobalValue::LinkOnceODRLinkage &&
3531                      STI.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr)
3532                  ? SPIRV::LinkageType::LinkOnceODR
3533                  : SPIRV::LinkageType::Export);
3534 
3535   const unsigned AddrSpace = GV->getAddressSpace();
3536   SPIRV::StorageClass::StorageClass StorageClass =
3537       addressSpaceToStorageClass(AddrSpace, STI);
3538   SPIRVType *ResType =
3539       GR.getOrCreateSPIRVPointerType(PointerBaseType, I, TII, StorageClass);
3540   Register Reg = GR.buildGlobalVariable(
3541       ResVReg, ResType, GlobalIdent, GV, StorageClass, Init,
3542       GlobalVar->isConstant(), HasLnkTy, LnkType, MIRBuilder, true);
3543   return Reg.isValid();
3544 }
3545 
3546 bool SPIRVInstructionSelector::selectLog10(Register ResVReg,
3547                                            const SPIRVType *ResType,
3548                                            MachineInstr &I) const {
3549   if (STI.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) {
3550     return selectExtInst(ResVReg, ResType, I, CL::log10);
3551   }
3552 
3553   // There is no log10 instruction in the GLSL Extended Instruction set, so it
3554   // is implemented as:
3555   // log10(x) = log2(x) * (1 / log2(10))
3556   //          = log2(x) * 0.30103
3557 
3558   MachineIRBuilder MIRBuilder(I);
3559   MachineBasicBlock &BB = *I.getParent();
3560 
3561   // Build log2(x).
3562   Register VarReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
3563   bool Result =
3564       BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst))
3565           .addDef(VarReg)
3566           .addUse(GR.getSPIRVTypeID(ResType))
3567           .addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
3568           .addImm(GL::Log2)
3569           .add(I.getOperand(1))
3570           .constrainAllUses(TII, TRI, RBI);
3571 
3572   // Build 0.30103.
3573   assert(ResType->getOpcode() == SPIRV::OpTypeVector ||
3574          ResType->getOpcode() == SPIRV::OpTypeFloat);
3575   // TODO: Add matrix implementation once supported by the HLSL frontend.
3576   const SPIRVType *SpirvScalarType =
3577       ResType->getOpcode() == SPIRV::OpTypeVector
3578           ? GR.getSPIRVTypeForVReg(ResType->getOperand(1).getReg())
3579           : ResType;
3580   Register ScaleReg =
3581       GR.buildConstantFP(APFloat(0.30103f), MIRBuilder, SpirvScalarType);
3582 
3583   // Multiply log2(x) by 0.30103 to get log10(x) result.
3584   auto Opcode = ResType->getOpcode() == SPIRV::OpTypeVector
3585                     ? SPIRV::OpVectorTimesScalar
3586                     : SPIRV::OpFMulS;
3587   return Result && BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
3588                        .addDef(ResVReg)
3589                        .addUse(GR.getSPIRVTypeID(ResType))
3590                        .addUse(VarReg)
3591                        .addUse(ScaleReg)
3592                        .constrainAllUses(TII, TRI, RBI);
3593 }
3594 
3595 // Generate the instructions to load 3-element vector builtin input
3596 // IDs/Indices.
3597 // Like: GlobalInvocationId, LocalInvocationId, etc....
3598 bool SPIRVInstructionSelector::loadVec3BuiltinInputID(
3599     SPIRV::BuiltIn::BuiltIn BuiltInValue, Register ResVReg,
3600     const SPIRVType *ResType, MachineInstr &I) const {
3601   MachineIRBuilder MIRBuilder(I);
3602   const SPIRVType *U32Type = GR.getOrCreateSPIRVIntegerType(32, MIRBuilder);
3603   const SPIRVType *Vec3Ty =
3604       GR.getOrCreateSPIRVVectorType(U32Type, 3, MIRBuilder);
3605   const SPIRVType *PtrType = GR.getOrCreateSPIRVPointerType(
3606       Vec3Ty, MIRBuilder, SPIRV::StorageClass::Input);
3607 
3608   // Create new register for the input ID builtin variable.
3609   Register NewRegister =
3610       MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
3611   MIRBuilder.getMRI()->setType(NewRegister, LLT::pointer(0, 64));
3612   GR.assignSPIRVTypeToVReg(PtrType, NewRegister, MIRBuilder.getMF());
3613 
3614   // Build global variable with the necessary decorations for the input ID
3615   // builtin variable.
3616   Register Variable = GR.buildGlobalVariable(
3617       NewRegister, PtrType, getLinkStringForBuiltIn(BuiltInValue), nullptr,
3618       SPIRV::StorageClass::Input, nullptr, true, true,
3619       SPIRV::LinkageType::Import, MIRBuilder, false);
3620 
3621   // Create new register for loading value.
3622   MachineRegisterInfo *MRI = MIRBuilder.getMRI();
3623   Register LoadedRegister = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
3624   MIRBuilder.getMRI()->setType(LoadedRegister, LLT::pointer(0, 64));
3625   GR.assignSPIRVTypeToVReg(Vec3Ty, LoadedRegister, MIRBuilder.getMF());
3626 
3627   // Load v3uint value from the global variable.
3628   bool Result =
3629       BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpLoad))
3630           .addDef(LoadedRegister)
3631           .addUse(GR.getSPIRVTypeID(Vec3Ty))
3632           .addUse(Variable);
3633 
3634   // Get the input ID index. Expecting operand is a constant immediate value,
3635   // wrapped in a type assignment.
3636   assert(I.getOperand(2).isReg());
3637   const uint32_t ThreadId = foldImm(I.getOperand(2), MRI);
3638 
3639   // Extract the input ID from the loaded vector value.
3640   MachineBasicBlock &BB = *I.getParent();
3641   auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpCompositeExtract))
3642                  .addDef(ResVReg)
3643                  .addUse(GR.getSPIRVTypeID(ResType))
3644                  .addUse(LoadedRegister)
3645                  .addImm(ThreadId);
3646   return Result && MIB.constrainAllUses(TII, TRI, RBI);
3647 }
3648 
3649 SPIRVType *SPIRVInstructionSelector::widenTypeToVec4(const SPIRVType *Type,
3650                                                      MachineInstr &I) const {
3651   MachineIRBuilder MIRBuilder(I);
3652   if (Type->getOpcode() != SPIRV::OpTypeVector)
3653     return GR.getOrCreateSPIRVVectorType(Type, 4, MIRBuilder);
3654 
3655   uint64_t VectorSize = Type->getOperand(2).getImm();
3656   if (VectorSize == 4)
3657     return Type;
3658 
3659   Register ScalarTypeReg = Type->getOperand(1).getReg();
3660   const SPIRVType *ScalarType = GR.getSPIRVTypeForVReg(ScalarTypeReg);
3661   return GR.getOrCreateSPIRVVectorType(ScalarType, 4, MIRBuilder);
3662 }
3663 
3664 namespace llvm {
3665 InstructionSelector *
3666 createSPIRVInstructionSelector(const SPIRVTargetMachine &TM,
3667                                const SPIRVSubtarget &Subtarget,
3668                                const RegisterBankInfo &RBI) {
3669   return new SPIRVInstructionSelector(TM, Subtarget, RBI);
3670 }
3671 } // namespace llvm
3672