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