1 //===-- WebAssemblyFastISel.cpp - WebAssembly FastISel implementation -----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file defines the WebAssembly-specific support for the FastISel
12 /// class. Some of the target-specific code is generated by tablegen in the file
13 /// WebAssemblyGenFastISel.inc, which is #included here.
14 ///
15 /// TODO: kill flags
16 ///
17 //===----------------------------------------------------------------------===//
18 
19 #include "WebAssembly.h"
20 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
21 #include "WebAssemblyMachineFunctionInfo.h"
22 #include "WebAssemblySubtarget.h"
23 #include "WebAssemblyTargetMachine.h"
24 #include "llvm/Analysis/BranchProbabilityInfo.h"
25 #include "llvm/CodeGen/FastISel.h"
26 #include "llvm/CodeGen/FunctionLoweringInfo.h"
27 #include "llvm/CodeGen/MachineConstantPool.h"
28 #include "llvm/CodeGen/MachineFrameInfo.h"
29 #include "llvm/CodeGen/MachineInstrBuilder.h"
30 #include "llvm/CodeGen/MachineRegisterInfo.h"
31 #include "llvm/IR/DataLayout.h"
32 #include "llvm/IR/DerivedTypes.h"
33 #include "llvm/IR/Function.h"
34 #include "llvm/IR/GetElementPtrTypeIterator.h"
35 #include "llvm/IR/GlobalAlias.h"
36 #include "llvm/IR/GlobalVariable.h"
37 #include "llvm/IR/Instructions.h"
38 #include "llvm/IR/IntrinsicInst.h"
39 #include "llvm/IR/Operator.h"
40 using namespace llvm;
41 
42 #define DEBUG_TYPE "wasm-fastisel"
43 
44 namespace {
45 
46 class WebAssemblyFastISel final : public FastISel {
47   // All possible address modes.
48   class Address {
49   public:
50     typedef enum { RegBase, FrameIndexBase } BaseKind;
51 
52   private:
53     BaseKind Kind;
54     union {
55       unsigned Reg;
56       int FI;
57     } Base;
58 
59     int64_t Offset;
60 
61     const GlobalValue *GV;
62 
63   public:
64     // Innocuous defaults for our address.
65     Address() : Kind(RegBase), Offset(0), GV(0) { Base.Reg = 0; }
66     void setKind(BaseKind K) { Kind = K; }
67     BaseKind getKind() const { return Kind; }
68     bool isRegBase() const { return Kind == RegBase; }
69     bool isFIBase() const { return Kind == FrameIndexBase; }
70     void setReg(unsigned Reg) {
71       assert(isRegBase() && "Invalid base register access!");
72       Base.Reg = Reg;
73     }
74     unsigned getReg() const {
75       assert(isRegBase() && "Invalid base register access!");
76       return Base.Reg;
77     }
78     void setFI(unsigned FI) {
79       assert(isFIBase() && "Invalid base frame index access!");
80       Base.FI = FI;
81     }
82     unsigned getFI() const {
83       assert(isFIBase() && "Invalid base frame index access!");
84       return Base.FI;
85     }
86 
87     void setOffset(int64_t Offset_) { Offset = Offset_; }
88     int64_t getOffset() const { return Offset; }
89     void setGlobalValue(const GlobalValue *G) { GV = G; }
90     const GlobalValue *getGlobalValue() const { return GV; }
91   };
92 
93   /// Keep a pointer to the WebAssemblySubtarget around so that we can make the
94   /// right decision when generating code for different targets.
95   const WebAssemblySubtarget *Subtarget;
96   LLVMContext *Context;
97 
98 private:
99   // Utility helper routines
100   MVT::SimpleValueType getSimpleType(Type *Ty) {
101     EVT VT = TLI.getValueType(DL, Ty, /*HandleUnknown=*/true);
102     return VT.isSimple() ? VT.getSimpleVT().SimpleTy :
103                            MVT::INVALID_SIMPLE_VALUE_TYPE;
104   }
105   MVT::SimpleValueType getLegalType(MVT::SimpleValueType VT) {
106     switch (VT) {
107     case MVT::i1:
108     case MVT::i8:
109     case MVT::i16:
110       return MVT::i32;
111     case MVT::i32:
112     case MVT::i64:
113     case MVT::f32:
114     case MVT::f64:
115       return VT;
116     case MVT::v16i8:
117     case MVT::v8i16:
118     case MVT::v4i32:
119     case MVT::v4f32:
120       if (Subtarget->hasSIMD128())
121         return VT;
122       break;
123     default:
124       break;
125     }
126     return MVT::INVALID_SIMPLE_VALUE_TYPE;
127   }
128   bool computeAddress(const Value *Obj, Address &Addr);
129   void materializeLoadStoreOperands(Address &Addr);
130   void addLoadStoreOperands(const Address &Addr, const MachineInstrBuilder &MIB,
131                             MachineMemOperand *MMO);
132   unsigned maskI1Value(unsigned Reg, const Value *V);
133   unsigned getRegForI1Value(const Value *V, bool &Not);
134   unsigned zeroExtendToI32(unsigned Reg, const Value *V,
135                            MVT::SimpleValueType From);
136   unsigned signExtendToI32(unsigned Reg, const Value *V,
137                            MVT::SimpleValueType From);
138   unsigned zeroExtend(unsigned Reg, const Value *V,
139                       MVT::SimpleValueType From,
140                       MVT::SimpleValueType To);
141   unsigned signExtend(unsigned Reg, const Value *V,
142                       MVT::SimpleValueType From,
143                       MVT::SimpleValueType To);
144   unsigned getRegForUnsignedValue(const Value *V);
145   unsigned getRegForSignedValue(const Value *V);
146   unsigned getRegForPromotedValue(const Value *V, bool IsSigned);
147   unsigned notValue(unsigned Reg);
148   unsigned copyValue(unsigned Reg);
149 
150   // Backend specific FastISel code.
151   unsigned fastMaterializeAlloca(const AllocaInst *AI) override;
152   unsigned fastMaterializeConstant(const Constant *C) override;
153   bool fastLowerArguments() override;
154 
155   // Selection routines.
156   bool selectCall(const Instruction *I);
157   bool selectSelect(const Instruction *I);
158   bool selectTrunc(const Instruction *I);
159   bool selectZExt(const Instruction *I);
160   bool selectSExt(const Instruction *I);
161   bool selectICmp(const Instruction *I);
162   bool selectFCmp(const Instruction *I);
163   bool selectBitCast(const Instruction *I);
164   bool selectLoad(const Instruction *I);
165   bool selectStore(const Instruction *I);
166   bool selectBr(const Instruction *I);
167   bool selectRet(const Instruction *I);
168   bool selectUnreachable(const Instruction *I);
169 
170 public:
171   // Backend specific FastISel code.
172   WebAssemblyFastISel(FunctionLoweringInfo &FuncInfo,
173                       const TargetLibraryInfo *LibInfo)
174       : FastISel(FuncInfo, LibInfo, /*SkipTargetIndependentISel=*/true) {
175     Subtarget = &FuncInfo.MF->getSubtarget<WebAssemblySubtarget>();
176     Context = &FuncInfo.Fn->getContext();
177   }
178 
179   bool fastSelectInstruction(const Instruction *I) override;
180 
181 #include "WebAssemblyGenFastISel.inc"
182 };
183 
184 } // end anonymous namespace
185 
186 bool WebAssemblyFastISel::computeAddress(const Value *Obj, Address &Addr) {
187 
188   const User *U = nullptr;
189   unsigned Opcode = Instruction::UserOp1;
190   if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
191     // Don't walk into other basic blocks unless the object is an alloca from
192     // another block, otherwise it may not have a virtual register assigned.
193     if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
194         FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
195       Opcode = I->getOpcode();
196       U = I;
197     }
198   } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
199     Opcode = C->getOpcode();
200     U = C;
201   }
202 
203   if (auto *Ty = dyn_cast<PointerType>(Obj->getType()))
204     if (Ty->getAddressSpace() > 255)
205       // Fast instruction selection doesn't support the special
206       // address spaces.
207       return false;
208 
209   if (const GlobalValue *GV = dyn_cast<GlobalValue>(Obj)) {
210     if (Addr.getGlobalValue())
211       return false;
212     Addr.setGlobalValue(GV);
213     return true;
214   }
215 
216   switch (Opcode) {
217   default:
218     break;
219   case Instruction::BitCast: {
220     // Look through bitcasts.
221     return computeAddress(U->getOperand(0), Addr);
222   }
223   case Instruction::IntToPtr: {
224     // Look past no-op inttoptrs.
225     if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==
226         TLI.getPointerTy(DL))
227       return computeAddress(U->getOperand(0), Addr);
228     break;
229   }
230   case Instruction::PtrToInt: {
231     // Look past no-op ptrtoints.
232     if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
233       return computeAddress(U->getOperand(0), Addr);
234     break;
235   }
236   case Instruction::GetElementPtr: {
237     Address SavedAddr = Addr;
238     uint64_t TmpOffset = Addr.getOffset();
239     // Iterate through the GEP folding the constants into offsets where
240     // we can.
241     for (gep_type_iterator GTI = gep_type_begin(U), E = gep_type_end(U);
242          GTI != E; ++GTI) {
243       const Value *Op = GTI.getOperand();
244       if (StructType *STy = dyn_cast<StructType>(*GTI)) {
245         const StructLayout *SL = DL.getStructLayout(STy);
246         unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
247         TmpOffset += SL->getElementOffset(Idx);
248       } else {
249         uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
250         for (;;) {
251           if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
252             // Constant-offset addressing.
253             TmpOffset += CI->getSExtValue() * S;
254             break;
255           }
256           if (S == 1 && Addr.isRegBase() && Addr.getReg() == 0) {
257             // An unscaled add of a register. Set it as the new base.
258             Addr.setReg(getRegForValue(Op));
259             break;
260           }
261           if (canFoldAddIntoGEP(U, Op)) {
262             // A compatible add with a constant operand. Fold the constant.
263             ConstantInt *CI =
264                 cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
265             TmpOffset += CI->getSExtValue() * S;
266             // Iterate on the other operand.
267             Op = cast<AddOperator>(Op)->getOperand(0);
268             continue;
269           }
270           // Unsupported
271           goto unsupported_gep;
272         }
273       }
274     }
275     // Try to grab the base operand now.
276     Addr.setOffset(TmpOffset);
277     if (computeAddress(U->getOperand(0), Addr))
278       return true;
279     // We failed, restore everything and try the other options.
280     Addr = SavedAddr;
281   unsupported_gep:
282     break;
283   }
284   case Instruction::Alloca: {
285     const AllocaInst *AI = cast<AllocaInst>(Obj);
286     DenseMap<const AllocaInst *, int>::iterator SI =
287         FuncInfo.StaticAllocaMap.find(AI);
288     if (SI != FuncInfo.StaticAllocaMap.end()) {
289       Addr.setKind(Address::FrameIndexBase);
290       Addr.setFI(SI->second);
291       return true;
292     }
293     break;
294   }
295   case Instruction::Add: {
296     // Adds of constants are common and easy enough.
297     const Value *LHS = U->getOperand(0);
298     const Value *RHS = U->getOperand(1);
299 
300     if (isa<ConstantInt>(LHS))
301       std::swap(LHS, RHS);
302 
303     if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
304       Addr.setOffset(Addr.getOffset() + CI->getSExtValue());
305       return computeAddress(LHS, Addr);
306     }
307 
308     Address Backup = Addr;
309     if (computeAddress(LHS, Addr) && computeAddress(RHS, Addr))
310       return true;
311     Addr = Backup;
312 
313     break;
314   }
315   case Instruction::Sub: {
316     // Subs of constants are common and easy enough.
317     const Value *LHS = U->getOperand(0);
318     const Value *RHS = U->getOperand(1);
319 
320     if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
321       Addr.setOffset(Addr.getOffset() - CI->getSExtValue());
322       return computeAddress(LHS, Addr);
323     }
324     break;
325   }
326   }
327   Addr.setReg(getRegForValue(Obj));
328   return Addr.getReg() != 0;
329 }
330 
331 void WebAssemblyFastISel::materializeLoadStoreOperands(Address &Addr) {
332   if (Addr.isRegBase()) {
333     unsigned Reg = Addr.getReg();
334     if (Reg == 0) {
335       Reg = createResultReg(Subtarget->hasAddr64() ?
336                             &WebAssembly::I64RegClass :
337                             &WebAssembly::I32RegClass);
338       unsigned Opc = Subtarget->hasAddr64() ?
339                      WebAssembly::CONST_I64 :
340                      WebAssembly::CONST_I32;
341       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), Reg)
342          .addImm(0);
343       Addr.setReg(Reg);
344     }
345   }
346 }
347 
348 void WebAssemblyFastISel::addLoadStoreOperands(const Address &Addr,
349                                                const MachineInstrBuilder &MIB,
350                                                MachineMemOperand *MMO) {
351   if (const GlobalValue *GV = Addr.getGlobalValue())
352     MIB.addGlobalAddress(GV, Addr.getOffset());
353   else
354     MIB.addImm(Addr.getOffset());
355 
356   if (Addr.isRegBase())
357     MIB.addReg(Addr.getReg());
358   else
359     MIB.addFrameIndex(Addr.getFI());
360 
361   // Set the alignment operand (this is rewritten in SetP2AlignOperands).
362   // TODO: Disable SetP2AlignOperands for FastISel and just do it here.
363   MIB.addImm(0);
364 
365   MIB.addMemOperand(MMO);
366 }
367 
368 unsigned WebAssemblyFastISel::maskI1Value(unsigned Reg, const Value *V) {
369   return zeroExtendToI32(Reg, V, MVT::i1);
370 }
371 
372 unsigned WebAssemblyFastISel::getRegForI1Value(const Value *V, bool &Not) {
373   if (const ICmpInst *ICmp = dyn_cast<ICmpInst>(V))
374     if (const ConstantInt *C = dyn_cast<ConstantInt>(ICmp->getOperand(1)))
375       if (ICmp->isEquality() && C->isZero() && C->getType()->isIntegerTy(32)) {
376         Not = ICmp->isTrueWhenEqual();
377         return getRegForValue(ICmp->getOperand(0));
378       }
379 
380   if (BinaryOperator::isNot(V)) {
381     Not = true;
382     return getRegForValue(BinaryOperator::getNotArgument(V));
383   }
384 
385   Not = false;
386   return maskI1Value(getRegForValue(V), V);
387 }
388 
389 unsigned WebAssemblyFastISel::zeroExtendToI32(unsigned Reg, const Value *V,
390                                               MVT::SimpleValueType From) {
391   switch (From) {
392   case MVT::i1:
393     // If the value is naturally an i1, we don't need to mask it.
394     // TODO: Recursively examine selects, phis, and, or, xor, constants.
395     if (From == MVT::i1 && V != nullptr) {
396       if (isa<CmpInst>(V) ||
397           (isa<Argument>(V) && cast<Argument>(V)->hasZExtAttr()))
398         return copyValue(Reg);
399     }
400   case MVT::i8:
401   case MVT::i16:
402     break;
403   case MVT::i32:
404     return copyValue(Reg);
405   default:
406     return 0;
407   }
408 
409   unsigned Imm = createResultReg(&WebAssembly::I32RegClass);
410   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
411           TII.get(WebAssembly::CONST_I32), Imm)
412     .addImm(~(~uint64_t(0) << MVT(From).getSizeInBits()));
413 
414   unsigned Result = createResultReg(&WebAssembly::I32RegClass);
415   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
416           TII.get(WebAssembly::AND_I32), Result)
417     .addReg(Reg)
418     .addReg(Imm);
419 
420   return Result;
421 }
422 
423 unsigned WebAssemblyFastISel::signExtendToI32(unsigned Reg, const Value *V,
424                                               MVT::SimpleValueType From) {
425   switch (From) {
426   case MVT::i1:
427   case MVT::i8:
428   case MVT::i16:
429     break;
430   case MVT::i32:
431     return copyValue(Reg);
432   default:
433     return 0;
434   }
435 
436   unsigned Imm = createResultReg(&WebAssembly::I32RegClass);
437   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
438           TII.get(WebAssembly::CONST_I32), Imm)
439     .addImm(32 - MVT(From).getSizeInBits());
440 
441   unsigned Left = createResultReg(&WebAssembly::I32RegClass);
442   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
443           TII.get(WebAssembly::SHL_I32), Left)
444     .addReg(Reg)
445     .addReg(Imm);
446 
447   unsigned Right = createResultReg(&WebAssembly::I32RegClass);
448   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
449           TII.get(WebAssembly::SHR_S_I32), Right)
450     .addReg(Left)
451     .addReg(Imm);
452 
453   return Right;
454 }
455 
456 unsigned WebAssemblyFastISel::zeroExtend(unsigned Reg, const Value *V,
457                                          MVT::SimpleValueType From,
458                                          MVT::SimpleValueType To) {
459   if (To == MVT::i64) {
460     if (From == MVT::i64)
461       return copyValue(Reg);
462 
463     Reg = zeroExtendToI32(Reg, V, From);
464 
465     unsigned Result = createResultReg(&WebAssembly::I64RegClass);
466     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
467             TII.get(WebAssembly::I64_EXTEND_U_I32), Result)
468         .addReg(Reg);
469     return Result;
470   }
471 
472   return zeroExtendToI32(Reg, V, From);
473 }
474 
475 unsigned WebAssemblyFastISel::signExtend(unsigned Reg, const Value *V,
476                                          MVT::SimpleValueType From,
477                                          MVT::SimpleValueType To) {
478   if (To == MVT::i64) {
479     if (From == MVT::i64)
480       return copyValue(Reg);
481 
482     Reg = signExtendToI32(Reg, V, From);
483 
484     unsigned Result = createResultReg(&WebAssembly::I64RegClass);
485     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
486             TII.get(WebAssembly::I64_EXTEND_S_I32), Result)
487         .addReg(Reg);
488     return Result;
489   }
490 
491   return signExtendToI32(Reg, V, From);
492 }
493 
494 unsigned WebAssemblyFastISel::getRegForUnsignedValue(const Value *V) {
495   MVT::SimpleValueType From = getSimpleType(V->getType());
496   MVT::SimpleValueType To = getLegalType(From);
497   return zeroExtend(getRegForValue(V), V, From, To);
498 }
499 
500 unsigned WebAssemblyFastISel::getRegForSignedValue(const Value *V) {
501   MVT::SimpleValueType From = getSimpleType(V->getType());
502   MVT::SimpleValueType To = getLegalType(From);
503   return zeroExtend(getRegForValue(V), V, From, To);
504 }
505 
506 unsigned WebAssemblyFastISel::getRegForPromotedValue(const Value *V,
507                                                      bool IsSigned) {
508   return IsSigned ? getRegForSignedValue(V) :
509                     getRegForUnsignedValue(V);
510 }
511 
512 unsigned WebAssemblyFastISel::notValue(unsigned Reg) {
513   assert(MRI.getRegClass(Reg) == &WebAssembly::I32RegClass);
514 
515   unsigned NotReg = createResultReg(&WebAssembly::I32RegClass);
516   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
517           TII.get(WebAssembly::EQZ_I32), NotReg)
518     .addReg(Reg);
519   return NotReg;
520 }
521 
522 unsigned WebAssemblyFastISel::copyValue(unsigned Reg) {
523   unsigned ResultReg = createResultReg(MRI.getRegClass(Reg));
524   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
525           TII.get(WebAssembly::COPY), ResultReg)
526     .addReg(Reg);
527   return ResultReg;
528 }
529 
530 unsigned WebAssemblyFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
531   DenseMap<const AllocaInst *, int>::iterator SI =
532       FuncInfo.StaticAllocaMap.find(AI);
533 
534   if (SI != FuncInfo.StaticAllocaMap.end()) {
535     unsigned ResultReg = createResultReg(Subtarget->hasAddr64() ?
536                                          &WebAssembly::I64RegClass :
537                                          &WebAssembly::I32RegClass);
538     unsigned Opc = Subtarget->hasAddr64() ?
539                    WebAssembly::COPY_LOCAL_I64 :
540                    WebAssembly::COPY_LOCAL_I32;
541     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
542         .addFrameIndex(SI->second);
543     return ResultReg;
544   }
545 
546   return 0;
547 }
548 
549 unsigned WebAssemblyFastISel::fastMaterializeConstant(const Constant *C) {
550   if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
551     unsigned ResultReg = createResultReg(Subtarget->hasAddr64() ?
552                                          &WebAssembly::I64RegClass :
553                                          &WebAssembly::I32RegClass);
554     unsigned Opc = Subtarget->hasAddr64() ?
555                    WebAssembly::CONST_I64 :
556                    WebAssembly::CONST_I32;
557     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
558        .addGlobalAddress(GV);
559     return ResultReg;
560   }
561 
562   // Let target-independent code handle it.
563   return 0;
564 }
565 
566 bool WebAssemblyFastISel::fastLowerArguments() {
567   if (!FuncInfo.CanLowerReturn)
568     return false;
569 
570   const Function *F = FuncInfo.Fn;
571   if (F->isVarArg())
572     return false;
573 
574   unsigned i = 0;
575   for (auto const &Arg : F->args()) {
576     const AttributeSet &Attrs = F->getAttributes();
577     if (Attrs.hasAttribute(i+1, Attribute::ByVal) ||
578         Attrs.hasAttribute(i+1, Attribute::SwiftSelf) ||
579         Attrs.hasAttribute(i+1, Attribute::SwiftError) ||
580         Attrs.hasAttribute(i+1, Attribute::InAlloca) ||
581         Attrs.hasAttribute(i+1, Attribute::Nest))
582       return false;
583 
584     Type *ArgTy = Arg.getType();
585     if (ArgTy->isStructTy() || ArgTy->isArrayTy())
586       return false;
587     if (!Subtarget->hasSIMD128() && ArgTy->isVectorTy())
588       return false;
589 
590     unsigned Opc;
591     const TargetRegisterClass *RC;
592     switch (getSimpleType(ArgTy)) {
593     case MVT::i1:
594     case MVT::i8:
595     case MVT::i16:
596     case MVT::i32:
597       Opc = WebAssembly::ARGUMENT_I32;
598       RC = &WebAssembly::I32RegClass;
599       break;
600     case MVT::i64:
601       Opc = WebAssembly::ARGUMENT_I64;
602       RC = &WebAssembly::I64RegClass;
603       break;
604     case MVT::f32:
605       Opc = WebAssembly::ARGUMENT_F32;
606       RC = &WebAssembly::F32RegClass;
607       break;
608     case MVT::f64:
609       Opc = WebAssembly::ARGUMENT_F64;
610       RC = &WebAssembly::F64RegClass;
611       break;
612     case MVT::v16i8:
613       Opc = WebAssembly::ARGUMENT_v16i8;
614       RC = &WebAssembly::V128RegClass;
615       break;
616     case MVT::v8i16:
617       Opc = WebAssembly::ARGUMENT_v8i16;
618       RC = &WebAssembly::V128RegClass;
619       break;
620     case MVT::v4i32:
621       Opc = WebAssembly::ARGUMENT_v4i32;
622       RC = &WebAssembly::V128RegClass;
623       break;
624     case MVT::v4f32:
625       Opc = WebAssembly::ARGUMENT_v4f32;
626       RC = &WebAssembly::V128RegClass;
627       break;
628     default:
629       return false;
630     }
631     unsigned ResultReg = createResultReg(RC);
632     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
633       .addImm(i);
634     updateValueMap(&Arg, ResultReg);
635 
636     ++i;
637   }
638 
639   MRI.addLiveIn(WebAssembly::ARGUMENTS);
640 
641   auto *MFI = MF->getInfo<WebAssemblyFunctionInfo>();
642   for (auto const &Arg : F->args())
643     MFI->addParam(getLegalType(getSimpleType(Arg.getType())));
644 
645   return true;
646 }
647 
648 bool WebAssemblyFastISel::selectCall(const Instruction *I) {
649   const CallInst *Call = cast<CallInst>(I);
650 
651   if (Call->isMustTailCall() || Call->isInlineAsm() ||
652       Call->getFunctionType()->isVarArg())
653     return false;
654 
655   Function *Func = Call->getCalledFunction();
656   if (Func && Func->isIntrinsic())
657     return false;
658 
659   FunctionType *FuncTy = Call->getFunctionType();
660   unsigned Opc;
661   bool IsDirect = Func != nullptr;
662   bool IsVoid = FuncTy->getReturnType()->isVoidTy();
663   unsigned ResultReg;
664   if (IsVoid) {
665     Opc = IsDirect ? WebAssembly::CALL_VOID : WebAssembly::CALL_INDIRECT_VOID;
666   } else {
667     if (!Subtarget->hasSIMD128() && Call->getType()->isVectorTy())
668       return false;
669 
670     MVT::SimpleValueType RetTy = getSimpleType(Call->getType());
671     switch (RetTy) {
672     case MVT::i1:
673     case MVT::i8:
674     case MVT::i16:
675     case MVT::i32:
676       Opc = IsDirect ? WebAssembly::CALL_I32 : WebAssembly::CALL_INDIRECT_I32;
677       ResultReg = createResultReg(&WebAssembly::I32RegClass);
678       break;
679     case MVT::i64:
680       Opc = IsDirect ? WebAssembly::CALL_I64 : WebAssembly::CALL_INDIRECT_I64;
681       ResultReg = createResultReg(&WebAssembly::I64RegClass);
682       break;
683     case MVT::f32:
684       Opc = IsDirect ? WebAssembly::CALL_F32 : WebAssembly::CALL_INDIRECT_F32;
685       ResultReg = createResultReg(&WebAssembly::F32RegClass);
686       break;
687     case MVT::f64:
688       Opc = IsDirect ? WebAssembly::CALL_F64 : WebAssembly::CALL_INDIRECT_F64;
689       ResultReg = createResultReg(&WebAssembly::F64RegClass);
690       break;
691     case MVT::v16i8:
692       Opc =
693           IsDirect ? WebAssembly::CALL_v16i8 : WebAssembly::CALL_INDIRECT_v16i8;
694       ResultReg = createResultReg(&WebAssembly::V128RegClass);
695       break;
696     case MVT::v8i16:
697       Opc =
698           IsDirect ? WebAssembly::CALL_v8i16 : WebAssembly::CALL_INDIRECT_v8i16;
699       ResultReg = createResultReg(&WebAssembly::V128RegClass);
700       break;
701     case MVT::v4i32:
702       Opc =
703           IsDirect ? WebAssembly::CALL_v4i32 : WebAssembly::CALL_INDIRECT_v4i32;
704       ResultReg = createResultReg(&WebAssembly::V128RegClass);
705       break;
706     case MVT::v4f32:
707       Opc =
708           IsDirect ? WebAssembly::CALL_v4f32 : WebAssembly::CALL_INDIRECT_v4f32;
709       ResultReg = createResultReg(&WebAssembly::V128RegClass);
710       break;
711     default:
712       return false;
713     }
714   }
715 
716   SmallVector<unsigned, 8> Args;
717   for (unsigned i = 0, e = Call->getNumArgOperands(); i < e; ++i) {
718     Value *V = Call->getArgOperand(i);
719     MVT::SimpleValueType ArgTy = getSimpleType(V->getType());
720     if (ArgTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
721       return false;
722 
723     const AttributeSet &Attrs = Call->getAttributes();
724     if (Attrs.hasAttribute(i+1, Attribute::ByVal) ||
725         Attrs.hasAttribute(i+1, Attribute::SwiftSelf) ||
726         Attrs.hasAttribute(i+1, Attribute::SwiftError) ||
727         Attrs.hasAttribute(i+1, Attribute::InAlloca) ||
728         Attrs.hasAttribute(i+1, Attribute::Nest))
729       return false;
730 
731     unsigned Reg;
732 
733     if (Attrs.hasAttribute(i+1, Attribute::SExt))
734       Reg = getRegForSignedValue(V);
735     else if (Attrs.hasAttribute(i+1, Attribute::ZExt))
736       Reg = getRegForUnsignedValue(V);
737     else
738       Reg = getRegForValue(V);
739 
740     if (Reg == 0)
741       return false;
742 
743     Args.push_back(Reg);
744   }
745 
746   auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
747 
748   if (!IsVoid)
749     MIB.addReg(ResultReg, RegState::Define);
750 
751   if (IsDirect)
752     MIB.addGlobalAddress(Func);
753   else
754     MIB.addReg(getRegForValue(Call->getCalledValue()));
755 
756   for (unsigned ArgReg : Args)
757     MIB.addReg(ArgReg);
758 
759   if (!IsVoid)
760     updateValueMap(Call, ResultReg);
761   return true;
762 }
763 
764 bool WebAssemblyFastISel::selectSelect(const Instruction *I) {
765   const SelectInst *Select = cast<SelectInst>(I);
766 
767   bool Not;
768   unsigned CondReg  = getRegForI1Value(Select->getCondition(), Not);
769   if (CondReg == 0)
770     return false;
771 
772   unsigned TrueReg  = getRegForValue(Select->getTrueValue());
773   if (TrueReg == 0)
774     return false;
775 
776   unsigned FalseReg = getRegForValue(Select->getFalseValue());
777   if (FalseReg == 0)
778     return false;
779 
780   if (Not)
781     std::swap(TrueReg, FalseReg);
782 
783   unsigned Opc;
784   const TargetRegisterClass *RC;
785   switch (getSimpleType(Select->getType())) {
786   case MVT::i1:
787   case MVT::i8:
788   case MVT::i16:
789   case MVT::i32:
790     Opc = WebAssembly::SELECT_I32;
791     RC = &WebAssembly::I32RegClass;
792     break;
793   case MVT::i64:
794     Opc = WebAssembly::SELECT_I64;
795     RC = &WebAssembly::I64RegClass;
796     break;
797   case MVT::f32:
798     Opc = WebAssembly::SELECT_F32;
799     RC = &WebAssembly::F32RegClass;
800     break;
801   case MVT::f64:
802     Opc = WebAssembly::SELECT_F64;
803     RC = &WebAssembly::F64RegClass;
804     break;
805   default:
806     return false;
807   }
808 
809   unsigned ResultReg = createResultReg(RC);
810   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
811     .addReg(TrueReg)
812     .addReg(FalseReg)
813     .addReg(CondReg);
814 
815   updateValueMap(Select, ResultReg);
816   return true;
817 }
818 
819 bool WebAssemblyFastISel::selectTrunc(const Instruction *I) {
820   const TruncInst *Trunc = cast<TruncInst>(I);
821 
822   unsigned Reg = getRegForValue(Trunc->getOperand(0));
823   if (Reg == 0)
824     return false;
825 
826   if (Trunc->getOperand(0)->getType()->isIntegerTy(64)) {
827     unsigned Result = createResultReg(&WebAssembly::I32RegClass);
828     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
829             TII.get(WebAssembly::I32_WRAP_I64), Result)
830         .addReg(Reg);
831     Reg = Result;
832   }
833 
834   updateValueMap(Trunc, Reg);
835   return true;
836 }
837 
838 bool WebAssemblyFastISel::selectZExt(const Instruction *I) {
839   const ZExtInst *ZExt = cast<ZExtInst>(I);
840 
841   const Value *Op = ZExt->getOperand(0);
842   MVT::SimpleValueType From = getSimpleType(Op->getType());
843   MVT::SimpleValueType To = getLegalType(getSimpleType(ZExt->getType()));
844   unsigned Reg = zeroExtend(getRegForValue(Op), Op, From, To);
845   if (Reg == 0)
846     return false;
847 
848   updateValueMap(ZExt, Reg);
849   return true;
850 }
851 
852 bool WebAssemblyFastISel::selectSExt(const Instruction *I) {
853   const SExtInst *SExt = cast<SExtInst>(I);
854 
855   const Value *Op = SExt->getOperand(0);
856   MVT::SimpleValueType From = getSimpleType(Op->getType());
857   MVT::SimpleValueType To = getLegalType(getSimpleType(SExt->getType()));
858   unsigned Reg = signExtend(getRegForValue(Op), Op, From, To);
859   if (Reg == 0)
860     return false;
861 
862   updateValueMap(SExt, Reg);
863   return true;
864 }
865 
866 bool WebAssemblyFastISel::selectICmp(const Instruction *I) {
867   const ICmpInst *ICmp = cast<ICmpInst>(I);
868 
869   bool I32 = getSimpleType(ICmp->getOperand(0)->getType()) != MVT::i64;
870   unsigned Opc;
871   bool isSigned = false;
872   switch (ICmp->getPredicate()) {
873   case ICmpInst::ICMP_EQ:
874     Opc = I32 ? WebAssembly::EQ_I32 : WebAssembly::EQ_I64;
875     break;
876   case ICmpInst::ICMP_NE:
877     Opc = I32 ? WebAssembly::NE_I32 : WebAssembly::NE_I64;
878     break;
879   case ICmpInst::ICMP_UGT:
880     Opc = I32 ? WebAssembly::GT_U_I32 : WebAssembly::GT_U_I64;
881     break;
882   case ICmpInst::ICMP_UGE:
883     Opc = I32 ? WebAssembly::GE_U_I32 : WebAssembly::GE_U_I64;
884     break;
885   case ICmpInst::ICMP_ULT:
886     Opc = I32 ? WebAssembly::LT_U_I32 : WebAssembly::LT_U_I64;
887     break;
888   case ICmpInst::ICMP_ULE:
889     Opc = I32 ? WebAssembly::LE_U_I32 : WebAssembly::LE_U_I64;
890     break;
891   case ICmpInst::ICMP_SGT:
892     Opc = I32 ? WebAssembly::GT_S_I32 : WebAssembly::GT_S_I64;
893     isSigned = true;
894     break;
895   case ICmpInst::ICMP_SGE:
896     Opc = I32 ? WebAssembly::GE_S_I32 : WebAssembly::GE_S_I64;
897     isSigned = true;
898     break;
899   case ICmpInst::ICMP_SLT:
900     Opc = I32 ? WebAssembly::LT_S_I32 : WebAssembly::LT_S_I64;
901     isSigned = true;
902     break;
903   case ICmpInst::ICMP_SLE:
904     Opc = I32 ? WebAssembly::LE_S_I32 : WebAssembly::LE_S_I64;
905     isSigned = true;
906     break;
907   default: return false;
908   }
909 
910   unsigned LHS = getRegForPromotedValue(ICmp->getOperand(0), isSigned);
911   if (LHS == 0)
912     return false;
913 
914   unsigned RHS = getRegForPromotedValue(ICmp->getOperand(1), isSigned);
915   if (RHS == 0)
916     return false;
917 
918   unsigned ResultReg = createResultReg(&WebAssembly::I32RegClass);
919   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
920       .addReg(LHS)
921       .addReg(RHS);
922   updateValueMap(ICmp, ResultReg);
923   return true;
924 }
925 
926 bool WebAssemblyFastISel::selectFCmp(const Instruction *I) {
927   const FCmpInst *FCmp = cast<FCmpInst>(I);
928 
929   unsigned LHS = getRegForValue(FCmp->getOperand(0));
930   if (LHS == 0)
931     return false;
932 
933   unsigned RHS = getRegForValue(FCmp->getOperand(1));
934   if (RHS == 0)
935     return false;
936 
937   bool F32 = getSimpleType(FCmp->getOperand(0)->getType()) != MVT::f64;
938   unsigned Opc;
939   bool Not = false;
940   switch (FCmp->getPredicate()) {
941   case FCmpInst::FCMP_OEQ:
942     Opc = F32 ? WebAssembly::EQ_F32 : WebAssembly::EQ_F64;
943     break;
944   case FCmpInst::FCMP_UNE:
945     Opc = F32 ? WebAssembly::NE_F32 : WebAssembly::NE_F64;
946     break;
947   case FCmpInst::FCMP_OGT:
948     Opc = F32 ? WebAssembly::GT_F32 : WebAssembly::GT_F64;
949     break;
950   case FCmpInst::FCMP_OGE:
951     Opc = F32 ? WebAssembly::GE_F32 : WebAssembly::GE_F64;
952     break;
953   case FCmpInst::FCMP_OLT:
954     Opc = F32 ? WebAssembly::LT_F32 : WebAssembly::LT_F64;
955     break;
956   case FCmpInst::FCMP_OLE:
957     Opc = F32 ? WebAssembly::LE_F32 : WebAssembly::LE_F64;
958     break;
959   case FCmpInst::FCMP_UGT:
960     Opc = F32 ? WebAssembly::LE_F32 : WebAssembly::LE_F64;
961     Not = true;
962     break;
963   case FCmpInst::FCMP_UGE:
964     Opc = F32 ? WebAssembly::LT_F32 : WebAssembly::LT_F64;
965     Not = true;
966     break;
967   case FCmpInst::FCMP_ULT:
968     Opc = F32 ? WebAssembly::GE_F32 : WebAssembly::GE_F64;
969     Not = true;
970     break;
971   case FCmpInst::FCMP_ULE:
972     Opc = F32 ? WebAssembly::GT_F32 : WebAssembly::GT_F64;
973     Not = true;
974     break;
975   default:
976     return false;
977   }
978 
979   unsigned ResultReg = createResultReg(&WebAssembly::I32RegClass);
980   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
981       .addReg(LHS)
982       .addReg(RHS);
983 
984   if (Not)
985     ResultReg = notValue(ResultReg);
986 
987   updateValueMap(FCmp, ResultReg);
988   return true;
989 }
990 
991 bool WebAssemblyFastISel::selectBitCast(const Instruction *I) {
992   // Target-independent code can handle this, except it doesn't set the dead
993   // flag on the ARGUMENTS clobber, so we have to do that manually in order
994   // to satisfy code that expects this of isBitcast() instructions.
995   EVT VT = TLI.getValueType(DL, I->getOperand(0)->getType());
996   EVT RetVT = TLI.getValueType(DL, I->getType());
997   if (!VT.isSimple() || !RetVT.isSimple())
998     return false;
999 
1000   if (VT == RetVT) {
1001     // No-op bitcast.
1002     updateValueMap(I, getRegForValue(I->getOperand(0)));
1003     return true;
1004   }
1005 
1006   unsigned Reg = fastEmit_ISD_BITCAST_r(VT.getSimpleVT(), RetVT.getSimpleVT(),
1007                                         getRegForValue(I->getOperand(0)),
1008                                         I->getOperand(0)->hasOneUse());
1009   if (!Reg)
1010     return false;
1011   MachineBasicBlock::iterator Iter = FuncInfo.InsertPt;
1012   --Iter;
1013   assert(Iter->isBitcast());
1014   Iter->setPhysRegsDeadExcept(ArrayRef<unsigned>(), TRI);
1015   updateValueMap(I, Reg);
1016   return true;
1017 }
1018 
1019 bool WebAssemblyFastISel::selectLoad(const Instruction *I) {
1020   const LoadInst *Load = cast<LoadInst>(I);
1021   if (Load->isAtomic())
1022     return false;
1023   if (!Subtarget->hasSIMD128() && Load->getType()->isVectorTy())
1024     return false;
1025 
1026   Address Addr;
1027   if (!computeAddress(Load->getPointerOperand(), Addr))
1028     return false;
1029 
1030   // TODO: Fold a following sign-/zero-extend into the load instruction.
1031 
1032   unsigned Opc;
1033   const TargetRegisterClass *RC;
1034   switch (getSimpleType(Load->getType())) {
1035   case MVT::i1:
1036   case MVT::i8:
1037     Opc = WebAssembly::LOAD8_U_I32;
1038     RC = &WebAssembly::I32RegClass;
1039     break;
1040   case MVT::i16:
1041     Opc = WebAssembly::LOAD16_U_I32;
1042     RC = &WebAssembly::I32RegClass;
1043     break;
1044   case MVT::i32:
1045     Opc = WebAssembly::LOAD_I32;
1046     RC = &WebAssembly::I32RegClass;
1047     break;
1048   case MVT::i64:
1049     Opc = WebAssembly::LOAD_I64;
1050     RC = &WebAssembly::I64RegClass;
1051     break;
1052   case MVT::f32:
1053     Opc = WebAssembly::LOAD_F32;
1054     RC = &WebAssembly::F32RegClass;
1055     break;
1056   case MVT::f64:
1057     Opc = WebAssembly::LOAD_F64;
1058     RC = &WebAssembly::F64RegClass;
1059     break;
1060   default:
1061     return false;
1062   }
1063 
1064   materializeLoadStoreOperands(Addr);
1065 
1066   unsigned ResultReg = createResultReg(RC);
1067   auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
1068                      ResultReg);
1069 
1070   addLoadStoreOperands(Addr, MIB, createMachineMemOperandFor(Load));
1071 
1072   updateValueMap(Load, ResultReg);
1073   return true;
1074 }
1075 
1076 bool WebAssemblyFastISel::selectStore(const Instruction *I) {
1077   const StoreInst *Store = cast<StoreInst>(I);
1078   if (Store->isAtomic())
1079     return false;
1080   if (!Subtarget->hasSIMD128() &&
1081       Store->getValueOperand()->getType()->isVectorTy())
1082     return false;
1083 
1084   Address Addr;
1085   if (!computeAddress(Store->getPointerOperand(), Addr))
1086     return false;
1087 
1088   unsigned Opc;
1089   const TargetRegisterClass *RC;
1090   bool VTIsi1 = false;
1091   switch (getSimpleType(Store->getValueOperand()->getType())) {
1092   case MVT::i1:
1093     VTIsi1 = true;
1094   case MVT::i8:
1095     Opc = WebAssembly::STORE8_I32;
1096     RC = &WebAssembly::I32RegClass;
1097     break;
1098   case MVT::i16:
1099     Opc = WebAssembly::STORE16_I32;
1100     RC = &WebAssembly::I32RegClass;
1101     break;
1102   case MVT::i32:
1103     Opc = WebAssembly::STORE_I32;
1104     RC = &WebAssembly::I32RegClass;
1105     break;
1106   case MVT::i64:
1107     Opc = WebAssembly::STORE_I64;
1108     RC = &WebAssembly::I64RegClass;
1109     break;
1110   case MVT::f32:
1111     Opc = WebAssembly::STORE_F32;
1112     RC = &WebAssembly::F32RegClass;
1113     break;
1114   case MVT::f64:
1115     Opc = WebAssembly::STORE_F64;
1116     RC = &WebAssembly::F64RegClass;
1117     break;
1118   default: return false;
1119   }
1120 
1121   materializeLoadStoreOperands(Addr);
1122 
1123   unsigned ValueReg = getRegForValue(Store->getValueOperand());
1124   if (VTIsi1)
1125     ValueReg = maskI1Value(ValueReg, Store->getValueOperand());
1126 
1127   unsigned ResultReg = createResultReg(RC);
1128   auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
1129                      ResultReg);
1130 
1131   addLoadStoreOperands(Addr, MIB, createMachineMemOperandFor(Store));
1132 
1133   MIB.addReg(ValueReg);
1134   return true;
1135 }
1136 
1137 bool WebAssemblyFastISel::selectBr(const Instruction *I) {
1138   const BranchInst *Br = cast<BranchInst>(I);
1139   if (Br->isUnconditional()) {
1140     MachineBasicBlock *MSucc = FuncInfo.MBBMap[Br->getSuccessor(0)];
1141     fastEmitBranch(MSucc, Br->getDebugLoc());
1142     return true;
1143   }
1144 
1145   MachineBasicBlock *TBB = FuncInfo.MBBMap[Br->getSuccessor(0)];
1146   MachineBasicBlock *FBB = FuncInfo.MBBMap[Br->getSuccessor(1)];
1147 
1148   bool Not;
1149   unsigned CondReg = getRegForI1Value(Br->getCondition(), Not);
1150 
1151   unsigned Opc = WebAssembly::BR_IF;
1152   if (Not)
1153     Opc = WebAssembly::BR_UNLESS;
1154 
1155   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc))
1156       .addMBB(TBB)
1157       .addReg(CondReg);
1158 
1159   finishCondBranch(Br->getParent(), TBB, FBB);
1160   return true;
1161 }
1162 
1163 bool WebAssemblyFastISel::selectRet(const Instruction *I) {
1164   if (!FuncInfo.CanLowerReturn)
1165     return false;
1166 
1167   const ReturnInst *Ret = cast<ReturnInst>(I);
1168 
1169   if (Ret->getNumOperands() == 0) {
1170     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1171             TII.get(WebAssembly::RETURN_VOID));
1172     return true;
1173   }
1174 
1175   Value *RV = Ret->getOperand(0);
1176   if (!Subtarget->hasSIMD128() && RV->getType()->isVectorTy())
1177     return false;
1178 
1179   unsigned Opc;
1180   switch (getSimpleType(RV->getType())) {
1181   case MVT::i1: case MVT::i8:
1182   case MVT::i16: case MVT::i32:
1183     Opc = WebAssembly::RETURN_I32;
1184     break;
1185   case MVT::i64:
1186     Opc = WebAssembly::RETURN_I64;
1187     break;
1188   case MVT::f32:
1189     Opc = WebAssembly::RETURN_F32;
1190     break;
1191   case MVT::f64:
1192     Opc = WebAssembly::RETURN_F64;
1193     break;
1194   case MVT::v16i8:
1195     Opc = WebAssembly::RETURN_v16i8;
1196     break;
1197   case MVT::v8i16:
1198     Opc = WebAssembly::RETURN_v8i16;
1199     break;
1200   case MVT::v4i32:
1201     Opc = WebAssembly::RETURN_v4i32;
1202     break;
1203   case MVT::v4f32:
1204     Opc = WebAssembly::RETURN_v4f32;
1205     break;
1206   default: return false;
1207   }
1208 
1209   unsigned Reg;
1210   if (FuncInfo.Fn->getAttributes().hasAttribute(0, Attribute::SExt))
1211     Reg = getRegForSignedValue(RV);
1212   else if (FuncInfo.Fn->getAttributes().hasAttribute(0, Attribute::ZExt))
1213     Reg = getRegForUnsignedValue(RV);
1214   else
1215     Reg = getRegForValue(RV);
1216 
1217   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)).addReg(Reg);
1218   return true;
1219 }
1220 
1221 bool WebAssemblyFastISel::selectUnreachable(const Instruction *I) {
1222   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1223           TII.get(WebAssembly::UNREACHABLE));
1224   return true;
1225 }
1226 
1227 bool WebAssemblyFastISel::fastSelectInstruction(const Instruction *I) {
1228   switch (I->getOpcode()) {
1229   case Instruction::Call:
1230     if (selectCall(I))
1231       return true;
1232     break;
1233   case Instruction::Select:      return selectSelect(I);
1234   case Instruction::Trunc:       return selectTrunc(I);
1235   case Instruction::ZExt:        return selectZExt(I);
1236   case Instruction::SExt:        return selectSExt(I);
1237   case Instruction::ICmp:        return selectICmp(I);
1238   case Instruction::FCmp:        return selectFCmp(I);
1239   case Instruction::BitCast:     return selectBitCast(I);
1240   case Instruction::Load:        return selectLoad(I);
1241   case Instruction::Store:       return selectStore(I);
1242   case Instruction::Br:          return selectBr(I);
1243   case Instruction::Ret:         return selectRet(I);
1244   case Instruction::Unreachable: return selectUnreachable(I);
1245   default: break;
1246   }
1247 
1248   // Fall back to target-independent instruction selection.
1249   return selectOperator(I, I->getOpcode());
1250 }
1251 
1252 FastISel *WebAssembly::createFastISel(FunctionLoweringInfo &FuncInfo,
1253                                       const TargetLibraryInfo *LibInfo) {
1254   return new WebAssemblyFastISel(FuncInfo, LibInfo);
1255 }
1256