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