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