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