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