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