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