OSDN Git Service

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