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