LLVM  14.0.0git
WebAssemblyISelLowering.cpp
Go to the documentation of this file.
1 //=- WebAssemblyISelLowering.cpp - WebAssembly DAG Lowering 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 implements the WebAssemblyTargetLowering class.
11 ///
12 //===----------------------------------------------------------------------===//
13 
19 #include "WebAssemblySubtarget.h"
28 #include "llvm/IR/DiagnosticInfo.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/IR/Intrinsics.h"
32 #include "llvm/IR/IntrinsicsWebAssembly.h"
33 #include "llvm/Support/Debug.h"
35 #include "llvm/Support/KnownBits.h"
39 using namespace llvm;
40 
41 #define DEBUG_TYPE "wasm-lower"
42 
44  const TargetMachine &TM, const WebAssemblySubtarget &STI)
45  : TargetLowering(TM), Subtarget(&STI) {
46  auto MVTPtr = Subtarget->hasAddr64() ? MVT::i64 : MVT::i32;
47 
48  // Booleans always contain 0 or 1.
50  // Except in SIMD vectors
52  // We don't know the microarchitecture here, so just reduce register pressure.
54  // Tell ISel that we have a stack pointer.
56  Subtarget->hasAddr64() ? WebAssembly::SP64 : WebAssembly::SP32);
57  // Set up the register classes.
58  addRegisterClass(MVT::i32, &WebAssembly::I32RegClass);
59  addRegisterClass(MVT::i64, &WebAssembly::I64RegClass);
60  addRegisterClass(MVT::f32, &WebAssembly::F32RegClass);
61  addRegisterClass(MVT::f64, &WebAssembly::F64RegClass);
62  if (Subtarget->hasSIMD128()) {
63  addRegisterClass(MVT::v16i8, &WebAssembly::V128RegClass);
64  addRegisterClass(MVT::v8i16, &WebAssembly::V128RegClass);
65  addRegisterClass(MVT::v4i32, &WebAssembly::V128RegClass);
66  addRegisterClass(MVT::v4f32, &WebAssembly::V128RegClass);
67  addRegisterClass(MVT::v2i64, &WebAssembly::V128RegClass);
68  addRegisterClass(MVT::v2f64, &WebAssembly::V128RegClass);
69  }
70  if (Subtarget->hasReferenceTypes()) {
71  addRegisterClass(MVT::externref, &WebAssembly::EXTERNREFRegClass);
72  addRegisterClass(MVT::funcref, &WebAssembly::FUNCREFRegClass);
73  }
74  // Compute derived properties from the register classes.
76 
77  // Transform loads and stores to pointers in address space 1 to loads and
78  // stores to WebAssembly global variables, outside linear memory.
79  for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64}) {
82  }
83  if (Subtarget->hasSIMD128()) {
85  MVT::v2f64}) {
88  }
89  }
90  if (Subtarget->hasReferenceTypes()) {
91  // We need custom load and store lowering for both externref, funcref and
92  // Other. The MVT::Other here represents tables of reference types.
93  for (auto T : {MVT::externref, MVT::funcref, MVT::Other}) {
96  }
97  }
98 
105 
106  // Take the default expansion for va_arg, va_copy, and va_end. There is no
107  // default action for va_start, so we do that custom.
112 
113  for (auto T : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) {
114  // Don't expand the floating-point types to constant pools.
116  // Expand floating-point comparisons.
117  for (auto CC : {ISD::SETO, ISD::SETUO, ISD::SETUEQ, ISD::SETONE,
119  setCondCodeAction(CC, T, Expand);
120  // Expand floating-point library function operators.
121  for (auto Op :
124  // Note supported floating-point library function operators that otherwise
125  // default to expand.
126  for (auto Op :
129  // Support minimum and maximum, which otherwise default to expand.
132  // WebAssembly currently has no builtin f16 support.
137  }
138 
139  // Expand unavailable integer operations.
140  for (auto Op :
144  for (auto T : {MVT::i32, MVT::i64})
146  if (Subtarget->hasSIMD128())
147  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64})
149  }
150 
151  if (Subtarget->hasNontrappingFPToInt())
153  for (auto T : {MVT::i32, MVT::i64})
155 
156  // SIMD-specific configuration
157  if (Subtarget->hasSIMD128()) {
158  // Hoist bitcasts out of shuffles
160 
161  // Combine extends of extract_subvectors into widening ops
164 
165  // Combine int_to_fp or fp_extend of extract_vectors and vice versa into
166  // conversions ops
171 
172  // Combine fp_to_{s,u}int_sat or fp_round of concat_vectors or vice versa
173  // into conversion ops
178 
179  // Support saturating add for i8x16 and i16x8
180  for (auto Op : {ISD::SADDSAT, ISD::UADDSAT})
181  for (auto T : {MVT::v16i8, MVT::v8i16})
183 
184  // Support integer abs
185  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64})
187 
188  // Custom lower BUILD_VECTORs to minimize number of replace_lanes
190  MVT::v2f64})
192 
193  // We have custom shuffle lowering to expose the shuffle mask
195  MVT::v2f64})
197 
198  // Custom lowering since wasm shifts must have a scalar shift amount
199  for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL})
200  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64})
202 
203  // Custom lower lane accesses to expand out variable indices
206  MVT::v2f64})
208 
209  // There is no i8x16.mul instruction
211 
212  // There is no vector conditional select instruction
214  MVT::v2f64})
216 
217  // Expand integer operations supported for scalars but not SIMD
218  for (auto Op :
220  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64})
222 
223  // But we do have integer min and max operations
224  for (auto Op : {ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX})
225  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
227 
228  // And we have popcnt for i8x16. It can be used to expand ctlz/cttz.
232 
233  // Custom lower bit counting operations for other types to scalarize them.
234  for (auto Op : {ISD::CTLZ, ISD::CTTZ, ISD::CTPOP})
235  for (auto T : {MVT::v8i16, MVT::v4i32, MVT::v2i64})
237 
238  // Expand float operations supported for scalars but not SIMD
241  for (auto T : {MVT::v4f32, MVT::v2f64})
243 
244  // Unsigned comparison operations are unavailable for i64x2 vectors.
245  for (auto CC : {ISD::SETUGT, ISD::SETUGE, ISD::SETULT, ISD::SETULE})
247 
248  // 64x2 conversions are not in the spec
249  for (auto Op :
251  for (auto T : {MVT::v2i64, MVT::v2f64})
253 
254  // But saturating fp_to_int converstions are
257  }
258 
259  // As a special case, these operators use the type to mean the type to
260  // sign-extend from.
262  if (!Subtarget->hasSignExt()) {
263  // Sign extends are legal only when extending a vector extract
264  auto Action = Subtarget->hasSIMD128() ? Custom : Expand;
265  for (auto T : {MVT::i8, MVT::i16, MVT::i32})
267  }
270 
271  // Dynamic stack allocation: use the default expansion.
275 
279 
280  // Expand these forms; we pattern-match the forms that we can handle in isel.
281  for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64})
282  for (auto Op : {ISD::BR_CC, ISD::SELECT_CC})
284 
285  // We have custom switch handling.
287 
288  // WebAssembly doesn't have:
289  // - Floating-point extending loads.
290  // - Floating-point truncating stores.
291  // - i1 extending loads.
292  // - truncating SIMD stores and most extending loads
295  for (auto T : MVT::integer_valuetypes())
298  if (Subtarget->hasSIMD128()) {
300  MVT::v2f64}) {
301  for (auto MemT : MVT::fixedlen_vector_valuetypes()) {
302  if (MVT(T) != MemT) {
303  setTruncStoreAction(T, MemT, Expand);
305  setLoadExtAction(Ext, T, MemT, Expand);
306  }
307  }
308  }
309  // But some vector extending loads are legal
310  for (auto Ext : {ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}) {
314  }
316  }
317 
318  // Don't do anything clever with build_pairs
320 
321  // Trap lowers to wasm unreachable
324 
325  // Exception handling intrinsics
329 
331 
332  // Override the __gnu_f2h_ieee/__gnu_h2f_ieee names so that the f32 name is
333  // consistent with the f64 and f128 names.
334  setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2");
335  setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2");
336 
337  // Define the emscripten name for return address helper.
338  // TODO: when implementing other Wasm backends, make this generic or only do
339  // this on emscripten depending on what they end up doing.
340  setLibcallName(RTLIB::RETURN_ADDRESS, "emscripten_return_address");
341 
342  // Always convert switches to br_tables unless there is only one case, which
343  // is equivalent to a simple branch. This reduces code size for wasm, and we
344  // defer possible jump table optimizations to the VM.
346 }
347 
349  uint32_t AS) const {
351  return MVT::externref;
353  return MVT::funcref;
354  return TargetLowering::getPointerTy(DL, AS);
355 }
356 
358  uint32_t AS) const {
360  return MVT::externref;
362  return MVT::funcref;
364 }
365 
367 WebAssemblyTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
368  // We have wasm instructions for these
369  switch (AI->getOperation()) {
370  case AtomicRMWInst::Add:
371  case AtomicRMWInst::Sub:
372  case AtomicRMWInst::And:
373  case AtomicRMWInst::Or:
374  case AtomicRMWInst::Xor:
375  case AtomicRMWInst::Xchg:
377  default:
378  break;
379  }
381 }
382 
383 bool WebAssemblyTargetLowering::shouldScalarizeBinop(SDValue VecOp) const {
384  // Implementation copied from X86TargetLowering.
385  unsigned Opc = VecOp.getOpcode();
386 
387  // Assume target opcodes can't be scalarized.
388  // TODO - do we have any exceptions?
389  if (Opc >= ISD::BUILTIN_OP_END)
390  return false;
391 
392  // If the vector op is not supported, try to convert to scalar.
393  EVT VecVT = VecOp.getValueType();
394  if (!isOperationLegalOrCustomOrPromote(Opc, VecVT))
395  return true;
396 
397  // If the vector op is supported, but the scalar op is not, the transform may
398  // not be worthwhile.
399  EVT ScalarVT = VecVT.getScalarType();
400  return isOperationLegalOrCustomOrPromote(Opc, ScalarVT);
401 }
402 
403 FastISel *WebAssemblyTargetLowering::createFastISel(
404  FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const {
405  return WebAssembly::createFastISel(FuncInfo, LibInfo);
406 }
407 
408 MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/,
409  EVT VT) const {
410  unsigned BitWidth = NextPowerOf2(VT.getSizeInBits() - 1);
411  if (BitWidth > 1 && BitWidth < 8)
412  BitWidth = 8;
413 
414  if (BitWidth > 64) {
415  // The shift will be lowered to a libcall, and compiler-rt libcalls expect
416  // the count to be an i32.
417  BitWidth = 32;
419  "32-bit shift counts ought to be enough for anyone");
420  }
421 
424  "Unable to represent scalar shift amount type");
425  return Result;
426 }
427 
428 // Lower an fp-to-int conversion operator from the LLVM opcode, which has an
429 // undefined result on invalid/overflow, to the WebAssembly opcode, which
430 // traps on invalid/overflow.
433  const TargetInstrInfo &TII,
434  bool IsUnsigned, bool Int64,
435  bool Float64, unsigned LoweredOpcode) {
436  MachineRegisterInfo &MRI = BB->getParent()->getRegInfo();
437 
438  Register OutReg = MI.getOperand(0).getReg();
439  Register InReg = MI.getOperand(1).getReg();
440 
441  unsigned Abs = Float64 ? WebAssembly::ABS_F64 : WebAssembly::ABS_F32;
442  unsigned FConst = Float64 ? WebAssembly::CONST_F64 : WebAssembly::CONST_F32;
443  unsigned LT = Float64 ? WebAssembly::LT_F64 : WebAssembly::LT_F32;
444  unsigned GE = Float64 ? WebAssembly::GE_F64 : WebAssembly::GE_F32;
445  unsigned IConst = Int64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
446  unsigned Eqz = WebAssembly::EQZ_I32;
447  unsigned And = WebAssembly::AND_I32;
448  int64_t Limit = Int64 ? INT64_MIN : INT32_MIN;
449  int64_t Substitute = IsUnsigned ? 0 : Limit;
450  double CmpVal = IsUnsigned ? -(double)Limit * 2.0 : -(double)Limit;
451  auto &Context = BB->getParent()->getFunction().getContext();
453 
454  const BasicBlock *LLVMBB = BB->getBasicBlock();
455  MachineFunction *F = BB->getParent();
456  MachineBasicBlock *TrueMBB = F->CreateMachineBasicBlock(LLVMBB);
457  MachineBasicBlock *FalseMBB = F->CreateMachineBasicBlock(LLVMBB);
458  MachineBasicBlock *DoneMBB = F->CreateMachineBasicBlock(LLVMBB);
459 
460  MachineFunction::iterator It = ++BB->getIterator();
461  F->insert(It, FalseMBB);
462  F->insert(It, TrueMBB);
463  F->insert(It, DoneMBB);
464 
465  // Transfer the remainder of BB and its successor edges to DoneMBB.
466  DoneMBB->splice(DoneMBB->begin(), BB, std::next(MI.getIterator()), BB->end());
468 
469  BB->addSuccessor(TrueMBB);
470  BB->addSuccessor(FalseMBB);
471  TrueMBB->addSuccessor(DoneMBB);
472  FalseMBB->addSuccessor(DoneMBB);
473 
474  unsigned Tmp0, Tmp1, CmpReg, EqzReg, FalseReg, TrueReg;
475  Tmp0 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
476  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
477  CmpReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
478  EqzReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
479  FalseReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
480  TrueReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
481 
482  MI.eraseFromParent();
483  // For signed numbers, we can do a single comparison to determine whether
484  // fabs(x) is within range.
485  if (IsUnsigned) {
486  Tmp0 = InReg;
487  } else {
488  BuildMI(BB, DL, TII.get(Abs), Tmp0).addReg(InReg);
489  }
490  BuildMI(BB, DL, TII.get(FConst), Tmp1)
491  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, CmpVal)));
492  BuildMI(BB, DL, TII.get(LT), CmpReg).addReg(Tmp0).addReg(Tmp1);
493 
494  // For unsigned numbers, we have to do a separate comparison with zero.
495  if (IsUnsigned) {
496  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
497  Register SecondCmpReg =
498  MRI.createVirtualRegister(&WebAssembly::I32RegClass);
499  Register AndReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
500  BuildMI(BB, DL, TII.get(FConst), Tmp1)
501  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, 0.0)));
502  BuildMI(BB, DL, TII.get(GE), SecondCmpReg).addReg(Tmp0).addReg(Tmp1);
503  BuildMI(BB, DL, TII.get(And), AndReg).addReg(CmpReg).addReg(SecondCmpReg);
504  CmpReg = AndReg;
505  }
506 
507  BuildMI(BB, DL, TII.get(Eqz), EqzReg).addReg(CmpReg);
508 
509  // Create the CFG diamond to select between doing the conversion or using
510  // the substitute value.
511  BuildMI(BB, DL, TII.get(WebAssembly::BR_IF)).addMBB(TrueMBB).addReg(EqzReg);
512  BuildMI(FalseMBB, DL, TII.get(LoweredOpcode), FalseReg).addReg(InReg);
513  BuildMI(FalseMBB, DL, TII.get(WebAssembly::BR)).addMBB(DoneMBB);
514  BuildMI(TrueMBB, DL, TII.get(IConst), TrueReg).addImm(Substitute);
515  BuildMI(*DoneMBB, DoneMBB->begin(), DL, TII.get(TargetOpcode::PHI), OutReg)
516  .addReg(FalseReg)
517  .addMBB(FalseMBB)
518  .addReg(TrueReg)
519  .addMBB(TrueMBB);
520 
521  return DoneMBB;
522 }
523 
524 static MachineBasicBlock *
526  const WebAssemblySubtarget *Subtarget,
527  const TargetInstrInfo &TII) {
528  MachineInstr &CallParams = *CallResults.getPrevNode();
529  assert(CallParams.getOpcode() == WebAssembly::CALL_PARAMS);
530  assert(CallResults.getOpcode() == WebAssembly::CALL_RESULTS ||
531  CallResults.getOpcode() == WebAssembly::RET_CALL_RESULTS);
532 
533  bool IsIndirect = CallParams.getOperand(0).isReg();
534  bool IsRetCall = CallResults.getOpcode() == WebAssembly::RET_CALL_RESULTS;
535 
536  bool IsFuncrefCall = false;
537  if (IsIndirect) {
538  Register Reg = CallParams.getOperand(0).getReg();
539  const MachineFunction *MF = BB->getParent();
540  const MachineRegisterInfo &MRI = MF->getRegInfo();
541  const TargetRegisterClass *TRC = MRI.getRegClass(Reg);
542  IsFuncrefCall = (TRC == &WebAssembly::FUNCREFRegClass);
543  assert(!IsFuncrefCall || Subtarget->hasReferenceTypes());
544  }
545 
546  unsigned CallOp;
547  if (IsIndirect && IsRetCall) {
548  CallOp = WebAssembly::RET_CALL_INDIRECT;
549  } else if (IsIndirect) {
550  CallOp = WebAssembly::CALL_INDIRECT;
551  } else if (IsRetCall) {
552  CallOp = WebAssembly::RET_CALL;
553  } else {
554  CallOp = WebAssembly::CALL;
555  }
556 
557  MachineFunction &MF = *BB->getParent();
558  const MCInstrDesc &MCID = TII.get(CallOp);
559  MachineInstrBuilder MIB(MF, MF.CreateMachineInstr(MCID, DL));
560 
561  // See if we must truncate the function pointer.
562  // CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
563  // as 64-bit for uniformity with other pointer types.
564  // See also: WebAssemblyFastISel::selectCall
565  if (IsIndirect && MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()) {
566  Register Reg32 =
567  MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
568  auto &FnPtr = CallParams.getOperand(0);
569  BuildMI(*BB, CallResults.getIterator(), DL,
570  TII.get(WebAssembly::I32_WRAP_I64), Reg32)
571  .addReg(FnPtr.getReg());
572  FnPtr.setReg(Reg32);
573  }
574 
575  // Move the function pointer to the end of the arguments for indirect calls
576  if (IsIndirect) {
577  auto FnPtr = CallParams.getOperand(0);
578  CallParams.RemoveOperand(0);
579 
580  // For funcrefs, call_indirect is done through __funcref_call_table and the
581  // funcref is always installed in slot 0 of the table, therefore instead of having
582  // the function pointer added at the end of the params list, a zero (the index in
583  // __funcref_call_table is added).
584  if (IsFuncrefCall) {
585  Register RegZero =
586  MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
587  MachineInstrBuilder MIBC0 =
588  BuildMI(MF, DL, TII.get(WebAssembly::CONST_I32), RegZero).addImm(0);
589 
590  BB->insert(CallResults.getIterator(), MIBC0);
591  MachineInstrBuilder(MF, CallParams).addReg(RegZero);
592  } else
593  CallParams.addOperand(FnPtr);
594  }
595 
596  for (auto Def : CallResults.defs())
597  MIB.add(Def);
598 
599  if (IsIndirect) {
600  // Placeholder for the type index.
601  MIB.addImm(0);
602  // The table into which this call_indirect indexes.
603  MCSymbolWasm *Table = IsFuncrefCall
605  MF.getContext(), Subtarget)
607  MF.getContext(), Subtarget);
608  if (Subtarget->hasReferenceTypes()) {
609  MIB.addSym(Table);
610  } else {
611  // For the MVP there is at most one table whose number is 0, but we can't
612  // write a table symbol or issue relocations. Instead we just ensure the
613  // table is live and write a zero.
614  Table->setNoStrip();
615  MIB.addImm(0);
616  }
617  }
618 
619  for (auto Use : CallParams.uses())
620  MIB.add(Use);
621 
622  BB->insert(CallResults.getIterator(), MIB);
623  CallParams.eraseFromParent();
624  CallResults.eraseFromParent();
625 
626  // If this is a funcref call, to avoid hidden GC roots, we need to clear the
627  // table slot with ref.null upon call_indirect return.
628  //
629  // This generates the following code, which comes right after a call_indirect
630  // of a funcref:
631  //
632  // i32.const 0
633  // ref.null func
634  // table.set __funcref_call_table
635  if (IsIndirect && IsFuncrefCall) {
637  MF.getContext(), Subtarget);
638  Register RegZero =
639  MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
640  MachineInstr *Const0 =
641  BuildMI(MF, DL, TII.get(WebAssembly::CONST_I32), RegZero).addImm(0);
642  BB->insertAfter(MIB.getInstr()->getIterator(), Const0);
643 
644  Register RegFuncref =
645  MF.getRegInfo().createVirtualRegister(&WebAssembly::FUNCREFRegClass);
646  MachineInstr *RefNull =
647  BuildMI(MF, DL, TII.get(WebAssembly::REF_NULL_FUNCREF), RegFuncref)
648  .addImm(static_cast<int32_t>(WebAssembly::HeapType::Funcref));
649  BB->insertAfter(Const0->getIterator(), RefNull);
650 
651  MachineInstr *TableSet =
652  BuildMI(MF, DL, TII.get(WebAssembly::TABLE_SET_FUNCREF))
653  .addSym(Table)
654  .addReg(RegZero)
655  .addReg(RegFuncref);
656  BB->insertAfter(RefNull->getIterator(), TableSet);
657  }
658 
659  return BB;
660 }
661 
662 MachineBasicBlock *WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
663  MachineInstr &MI, MachineBasicBlock *BB) const {
664  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
665  DebugLoc DL = MI.getDebugLoc();
666 
667  switch (MI.getOpcode()) {
668  default:
669  llvm_unreachable("Unexpected instr type to insert");
670  case WebAssembly::FP_TO_SINT_I32_F32:
671  return LowerFPToInt(MI, DL, BB, TII, false, false, false,
672  WebAssembly::I32_TRUNC_S_F32);
673  case WebAssembly::FP_TO_UINT_I32_F32:
674  return LowerFPToInt(MI, DL, BB, TII, true, false, false,
675  WebAssembly::I32_TRUNC_U_F32);
676  case WebAssembly::FP_TO_SINT_I64_F32:
677  return LowerFPToInt(MI, DL, BB, TII, false, true, false,
678  WebAssembly::I64_TRUNC_S_F32);
679  case WebAssembly::FP_TO_UINT_I64_F32:
680  return LowerFPToInt(MI, DL, BB, TII, true, true, false,
681  WebAssembly::I64_TRUNC_U_F32);
682  case WebAssembly::FP_TO_SINT_I32_F64:
683  return LowerFPToInt(MI, DL, BB, TII, false, false, true,
684  WebAssembly::I32_TRUNC_S_F64);
685  case WebAssembly::FP_TO_UINT_I32_F64:
686  return LowerFPToInt(MI, DL, BB, TII, true, false, true,
687  WebAssembly::I32_TRUNC_U_F64);
688  case WebAssembly::FP_TO_SINT_I64_F64:
689  return LowerFPToInt(MI, DL, BB, TII, false, true, true,
690  WebAssembly::I64_TRUNC_S_F64);
691  case WebAssembly::FP_TO_UINT_I64_F64:
692  return LowerFPToInt(MI, DL, BB, TII, true, true, true,
693  WebAssembly::I64_TRUNC_U_F64);
694  case WebAssembly::CALL_RESULTS:
695  case WebAssembly::RET_CALL_RESULTS:
696  return LowerCallResults(MI, DL, BB, Subtarget, TII);
697  }
698 }
699 
700 const char *
701 WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {
702  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
705  break;
706 #define HANDLE_NODETYPE(NODE) \
707  case WebAssemblyISD::NODE: \
708  return "WebAssemblyISD::" #NODE;
709 #define HANDLE_MEM_NODETYPE(NODE) HANDLE_NODETYPE(NODE)
710 #include "WebAssemblyISD.def"
711 #undef HANDLE_MEM_NODETYPE
712 #undef HANDLE_NODETYPE
713  }
714  return nullptr;
715 }
716 
717 std::pair<unsigned, const TargetRegisterClass *>
718 WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
719  const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
720  // First, see if this is a constraint that directly corresponds to a
721  // WebAssembly register class.
722  if (Constraint.size() == 1) {
723  switch (Constraint[0]) {
724  case 'r':
725  assert(VT != MVT::iPTR && "Pointer MVT not expected here");
726  if (Subtarget->hasSIMD128() && VT.isVector()) {
727  if (VT.getSizeInBits() == 128)
728  return std::make_pair(0U, &WebAssembly::V128RegClass);
729  }
730  if (VT.isInteger() && !VT.isVector()) {
731  if (VT.getSizeInBits() <= 32)
732  return std::make_pair(0U, &WebAssembly::I32RegClass);
733  if (VT.getSizeInBits() <= 64)
734  return std::make_pair(0U, &WebAssembly::I64RegClass);
735  }
736  if (VT.isFloatingPoint() && !VT.isVector()) {
737  switch (VT.getSizeInBits()) {
738  case 32:
739  return std::make_pair(0U, &WebAssembly::F32RegClass);
740  case 64:
741  return std::make_pair(0U, &WebAssembly::F64RegClass);
742  default:
743  break;
744  }
745  }
746  break;
747  default:
748  break;
749  }
750  }
751 
752  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
753 }
754 
755 bool WebAssemblyTargetLowering::isCheapToSpeculateCttz() const {
756  // Assume ctz is a relatively cheap operation.
757  return true;
758 }
759 
760 bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const {
761  // Assume clz is a relatively cheap operation.
762  return true;
763 }
764 
765 bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL,
766  const AddrMode &AM,
767  Type *Ty, unsigned AS,
768  Instruction *I) const {
769  // WebAssembly offsets are added as unsigned without wrapping. The
770  // isLegalAddressingMode gives us no way to determine if wrapping could be
771  // happening, so we approximate this by accepting only non-negative offsets.
772  if (AM.BaseOffs < 0)
773  return false;
774 
775  // WebAssembly has no scale register operands.
776  if (AM.Scale != 0)
777  return false;
778 
779  // Everything else is legal.
780  return true;
781 }
782 
783 bool WebAssemblyTargetLowering::allowsMisalignedMemoryAccesses(
784  EVT /*VT*/, unsigned /*AddrSpace*/, Align /*Align*/,
785  MachineMemOperand::Flags /*Flags*/, bool *Fast) const {
786  // WebAssembly supports unaligned accesses, though it should be declared
787  // with the p2align attribute on loads and stores which do so, and there
788  // may be a performance impact. We tell LLVM they're "fast" because
789  // for the kinds of things that LLVM uses this for (merging adjacent stores
790  // of constants, etc.), WebAssembly implementations will either want the
791  // unaligned access or they'll split anyway.
792  if (Fast)
793  *Fast = true;
794  return true;
795 }
796 
797 bool WebAssemblyTargetLowering::isIntDivCheap(EVT VT,
798  AttributeList Attr) const {
799  // The current thinking is that wasm engines will perform this optimization,
800  // so we can save on code size.
801  return true;
802 }
803 
804 bool WebAssemblyTargetLowering::isVectorLoadExtDesirable(SDValue ExtVal) const {
805  EVT ExtT = ExtVal.getValueType();
806  EVT MemT = cast<LoadSDNode>(ExtVal->getOperand(0))->getValueType(0);
807  return (ExtT == MVT::v8i16 && MemT == MVT::v8i8) ||
808  (ExtT == MVT::v4i32 && MemT == MVT::v4i16) ||
809  (ExtT == MVT::v2i64 && MemT == MVT::v2i32);
810 }
811 
812 bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
813  const GlobalAddressSDNode *GA) const {
814  // Wasm doesn't support function addresses with offsets
815  const GlobalValue *GV = GA->getGlobal();
816  return isa<Function>(GV) ? false : TargetLowering::isOffsetFoldingLegal(GA);
817 }
818 
819 EVT WebAssemblyTargetLowering::getSetCCResultType(const DataLayout &DL,
820  LLVMContext &C,
821  EVT VT) const {
822  if (VT.isVector())
824 
825  // So far, all branch instructions in Wasm take an I32 condition.
826  // The default TargetLowering::getSetCCResultType returns the pointer size,
827  // which would be useful to reduce instruction counts when testing
828  // against 64-bit pointers/values if at some point Wasm supports that.
829  return EVT::getIntegerVT(C, 32);
830 }
831 
832 bool WebAssemblyTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
833  const CallInst &I,
834  MachineFunction &MF,
835  unsigned Intrinsic) const {
836  switch (Intrinsic) {
837  case Intrinsic::wasm_memory_atomic_notify:
839  Info.memVT = MVT::i32;
840  Info.ptrVal = I.getArgOperand(0);
841  Info.offset = 0;
842  Info.align = Align(4);
843  // atomic.notify instruction does not really load the memory specified with
844  // this argument, but MachineMemOperand should either be load or store, so
845  // we set this to a load.
846  // FIXME Volatile isn't really correct, but currently all LLVM atomic
847  // instructions are treated as volatiles in the backend, so we should be
848  // consistent. The same applies for wasm_atomic_wait intrinsics too.
850  return true;
851  case Intrinsic::wasm_memory_atomic_wait32:
853  Info.memVT = MVT::i32;
854  Info.ptrVal = I.getArgOperand(0);
855  Info.offset = 0;
856  Info.align = Align(4);
858  return true;
859  case Intrinsic::wasm_memory_atomic_wait64:
861  Info.memVT = MVT::i64;
862  Info.ptrVal = I.getArgOperand(0);
863  Info.offset = 0;
864  Info.align = Align(8);
866  return true;
867  default:
868  return false;
869  }
870 }
871 
872 void WebAssemblyTargetLowering::computeKnownBitsForTargetNode(
873  const SDValue Op, KnownBits &Known, const APInt &DemandedElts,
874  const SelectionDAG &DAG, unsigned Depth) const {
875  switch (Op.getOpcode()) {
876  default:
877  break;
879  unsigned IntNo = Op.getConstantOperandVal(0);
880  switch (IntNo) {
881  default:
882  break;
883  case Intrinsic::wasm_bitmask: {
884  unsigned BitWidth = Known.getBitWidth();
885  EVT VT = Op.getOperand(1).getSimpleValueType();
886  unsigned PossibleBits = VT.getVectorNumElements();
887  APInt ZeroMask = APInt::getHighBitsSet(BitWidth, BitWidth - PossibleBits);
888  Known.Zero |= ZeroMask;
889  break;
890  }
891  }
892  }
893  }
894 }
895 
897 WebAssemblyTargetLowering::getPreferredVectorAction(MVT VT) const {
898  if (VT.isFixedLengthVector()) {
899  MVT EltVT = VT.getVectorElementType();
900  // We have legal vector types with these lane types, so widening the
901  // vector would let us use some of the lanes directly without having to
902  // extend or truncate values.
903  if (EltVT == MVT::i8 || EltVT == MVT::i16 || EltVT == MVT::i32 ||
904  EltVT == MVT::i64 || EltVT == MVT::f32 || EltVT == MVT::f64)
905  return TypeWidenVector;
906  }
907 
909 }
910 
911 //===----------------------------------------------------------------------===//
912 // WebAssembly Lowering private implementation.
913 //===----------------------------------------------------------------------===//
914 
915 //===----------------------------------------------------------------------===//
916 // Lowering Code
917 //===----------------------------------------------------------------------===//
918 
919 static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *Msg) {
921  DAG.getContext()->diagnose(
922  DiagnosticInfoUnsupported(MF.getFunction(), Msg, DL.getDebugLoc()));
923 }
924 
925 // Test whether the given calling convention is supported.
926 static bool callingConvSupported(CallingConv::ID CallConv) {
927  // We currently support the language-independent target-independent
928  // conventions. We don't yet have a way to annotate calls with properties like
929  // "cold", and we don't have any call-clobbered registers, so these are mostly
930  // all handled the same.
931  return CallConv == CallingConv::C || CallConv == CallingConv::Fast ||
932  CallConv == CallingConv::Cold ||
933  CallConv == CallingConv::PreserveMost ||
934  CallConv == CallingConv::PreserveAll ||
935  CallConv == CallingConv::CXX_FAST_TLS ||
937  CallConv == CallingConv::Swift;
938 }
939 
940 SDValue
941 WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
942  SmallVectorImpl<SDValue> &InVals) const {
943  SelectionDAG &DAG = CLI.DAG;
944  SDLoc DL = CLI.DL;
945  SDValue Chain = CLI.Chain;
946  SDValue Callee = CLI.Callee;
948  auto Layout = MF.getDataLayout();
949 
950  CallingConv::ID CallConv = CLI.CallConv;
951  if (!callingConvSupported(CallConv))
952  fail(DL, DAG,
953  "WebAssembly doesn't support language-specific or target-specific "
954  "calling conventions yet");
955  if (CLI.IsPatchPoint)
956  fail(DL, DAG, "WebAssembly doesn't support patch point yet");
957 
958  if (CLI.IsTailCall) {
959  auto NoTail = [&](const char *Msg) {
960  if (CLI.CB && CLI.CB->isMustTailCall())
961  fail(DL, DAG, Msg);
962  CLI.IsTailCall = false;
963  };
964 
965  if (!Subtarget->hasTailCall())
966  NoTail("WebAssembly 'tail-call' feature not enabled");
967 
968  // Varargs calls cannot be tail calls because the buffer is on the stack
969  if (CLI.IsVarArg)
970  NoTail("WebAssembly does not support varargs tail calls");
971 
972  // Do not tail call unless caller and callee return types match
973  const Function &F = MF.getFunction();
974  const TargetMachine &TM = getTargetMachine();
975  Type *RetTy = F.getReturnType();
976  SmallVector<MVT, 4> CallerRetTys;
977  SmallVector<MVT, 4> CalleeRetTys;
978  computeLegalValueVTs(F, TM, RetTy, CallerRetTys);
979  computeLegalValueVTs(F, TM, CLI.RetTy, CalleeRetTys);
980  bool TypesMatch = CallerRetTys.size() == CalleeRetTys.size() &&
981  std::equal(CallerRetTys.begin(), CallerRetTys.end(),
982  CalleeRetTys.begin());
983  if (!TypesMatch)
984  NoTail("WebAssembly tail call requires caller and callee return types to "
985  "match");
986 
987  // If pointers to local stack values are passed, we cannot tail call
988  if (CLI.CB) {
989  for (auto &Arg : CLI.CB->args()) {
990  Value *Val = Arg.get();
991  // Trace the value back through pointer operations
992  while (true) {
993  Value *Src = Val->stripPointerCastsAndAliases();
994  if (auto *GEP = dyn_cast<GetElementPtrInst>(Src))
995  Src = GEP->getPointerOperand();
996  if (Val == Src)
997  break;
998  Val = Src;
999  }
1000  if (isa<AllocaInst>(Val)) {
1001  NoTail(
1002  "WebAssembly does not support tail calling with stack arguments");
1003  break;
1004  }
1005  }
1006  }
1007  }
1008 
1010  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
1011  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
1012 
1013  // The generic code may have added an sret argument. If we're lowering an
1014  // invoke function, the ABI requires that the function pointer be the first
1015  // argument, so we may have to swap the arguments.
1016  if (CallConv == CallingConv::WASM_EmscriptenInvoke && Outs.size() >= 2 &&
1017  Outs[0].Flags.isSRet()) {
1018  std::swap(Outs[0], Outs[1]);
1019  std::swap(OutVals[0], OutVals[1]);
1020  }
1021 
1022  bool HasSwiftSelfArg = false;
1023  bool HasSwiftErrorArg = false;
1024  unsigned NumFixedArgs = 0;
1025  for (unsigned I = 0; I < Outs.size(); ++I) {
1026  const ISD::OutputArg &Out = Outs[I];
1027  SDValue &OutVal = OutVals[I];
1028  HasSwiftSelfArg |= Out.Flags.isSwiftSelf();
1029  HasSwiftErrorArg |= Out.Flags.isSwiftError();
1030  if (Out.Flags.isNest())
1031  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
1032  if (Out.Flags.isInAlloca())
1033  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
1034  if (Out.Flags.isInConsecutiveRegs())
1035  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
1036  if (Out.Flags.isInConsecutiveRegsLast())
1037  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
1038  if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
1039  auto &MFI = MF.getFrameInfo();
1040  int FI = MFI.CreateStackObject(Out.Flags.getByValSize(),
1042  /*isSS=*/false);
1043  SDValue SizeNode =
1044  DAG.getConstant(Out.Flags.getByValSize(), DL, MVT::i32);
1045  SDValue FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
1046  Chain = DAG.getMemcpy(
1047  Chain, DL, FINode, OutVal, SizeNode, Out.Flags.getNonZeroByValAlign(),
1048  /*isVolatile*/ false, /*AlwaysInline=*/false,
1049  /*isTailCall*/ false, MachinePointerInfo(), MachinePointerInfo());
1050  OutVal = FINode;
1051  }
1052  // Count the number of fixed args *after* legalization.
1053  NumFixedArgs += Out.IsFixed;
1054  }
1055 
1056  bool IsVarArg = CLI.IsVarArg;
1057  auto PtrVT = getPointerTy(Layout);
1058 
1059  // For swiftcc, emit additional swiftself and swifterror arguments
1060  // if there aren't. These additional arguments are also added for callee
1061  // signature They are necessary to match callee and caller signature for
1062  // indirect call.
1063  if (CallConv == CallingConv::Swift) {
1064  if (!HasSwiftSelfArg) {
1065  NumFixedArgs++;
1067  Arg.Flags.setSwiftSelf();
1068  CLI.Outs.push_back(Arg);
1069  SDValue ArgVal = DAG.getUNDEF(PtrVT);
1070  CLI.OutVals.push_back(ArgVal);
1071  }
1072  if (!HasSwiftErrorArg) {
1073  NumFixedArgs++;
1075  Arg.Flags.setSwiftError();
1076  CLI.Outs.push_back(Arg);
1077  SDValue ArgVal = DAG.getUNDEF(PtrVT);
1078  CLI.OutVals.push_back(ArgVal);
1079  }
1080  }
1081 
1082  // Analyze operands of the call, assigning locations to each operand.
1084  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
1085 
1086  if (IsVarArg) {
1087  // Outgoing non-fixed arguments are placed in a buffer. First
1088  // compute their offsets and the total amount of buffer space needed.
1089  for (unsigned I = NumFixedArgs; I < Outs.size(); ++I) {
1090  const ISD::OutputArg &Out = Outs[I];
1091  SDValue &Arg = OutVals[I];
1092  EVT VT = Arg.getValueType();
1093  assert(VT != MVT::iPTR && "Legalized args should be concrete");
1094  Type *Ty = VT.getTypeForEVT(*DAG.getContext());
1095  Align Alignment =
1096  std::max(Out.Flags.getNonZeroOrigAlign(), Layout.getABITypeAlign(Ty));
1097  unsigned Offset =
1098  CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty), Alignment);
1099  CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(),
1100  Offset, VT.getSimpleVT(),
1102  }
1103  }
1104 
1105  unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
1106 
1107  SDValue FINode;
1108  if (IsVarArg && NumBytes) {
1109  // For non-fixed arguments, next emit stores to store the argument values
1110  // to the stack buffer at the offsets computed above.
1111  int FI = MF.getFrameInfo().CreateStackObject(NumBytes,
1112  Layout.getStackAlignment(),
1113  /*isSS=*/false);
1114  unsigned ValNo = 0;
1115  SmallVector<SDValue, 8> Chains;
1116  for (SDValue Arg : drop_begin(OutVals, NumFixedArgs)) {
1117  assert(ArgLocs[ValNo].getValNo() == ValNo &&
1118  "ArgLocs should remain in order and only hold varargs args");
1119  unsigned Offset = ArgLocs[ValNo++].getLocMemOffset();
1120  FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
1121  SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, FINode,
1122  DAG.getConstant(Offset, DL, PtrVT));
1123  Chains.push_back(
1124  DAG.getStore(Chain, DL, Arg, Add,
1126  }
1127  if (!Chains.empty())
1128  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
1129  } else if (IsVarArg) {
1130  FINode = DAG.getIntPtrConstant(0, DL);
1131  }
1132 
1133  if (Callee->getOpcode() == ISD::GlobalAddress) {
1134  // If the callee is a GlobalAddress node (quite common, every direct call
1135  // is) turn it into a TargetGlobalAddress node so that LowerGlobalAddress
1136  // doesn't at MO_GOT which is not needed for direct calls.
1137  GlobalAddressSDNode* GA = cast<GlobalAddressSDNode>(Callee);
1139  getPointerTy(DAG.getDataLayout()),
1140  GA->getOffset());
1142  getPointerTy(DAG.getDataLayout()), Callee);
1143  }
1144 
1145  // Compute the operands for the CALLn node.
1147  Ops.push_back(Chain);
1148  Ops.push_back(Callee);
1149 
1150  // Add all fixed arguments. Note that for non-varargs calls, NumFixedArgs
1151  // isn't reliable.
1152  Ops.append(OutVals.begin(),
1153  IsVarArg ? OutVals.begin() + NumFixedArgs : OutVals.end());
1154  // Add a pointer to the vararg buffer.
1155  if (IsVarArg)
1156  Ops.push_back(FINode);
1157 
1158  SmallVector<EVT, 8> InTys;
1159  for (const auto &In : Ins) {
1160  assert(!In.Flags.isByVal() && "byval is not valid for return values");
1161  assert(!In.Flags.isNest() && "nest is not valid for return values");
1162  if (In.Flags.isInAlloca())
1163  fail(DL, DAG, "WebAssembly hasn't implemented inalloca return values");
1164  if (In.Flags.isInConsecutiveRegs())
1165  fail(DL, DAG, "WebAssembly hasn't implemented cons regs return values");
1166  if (In.Flags.isInConsecutiveRegsLast())
1167  fail(DL, DAG,
1168  "WebAssembly hasn't implemented cons regs last return values");
1169  // Ignore In.getNonZeroOrigAlign() because all our arguments are passed in
1170  // registers.
1171  InTys.push_back(In.VT);
1172  }
1173 
1174  // Lastly, if this is a call to a funcref we need to add an instruction
1175  // table.set to the chain and transform the call.
1176  if (CLI.CB &&
1177  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
1178  // In the absence of function references proposal where a funcref call is
1179  // lowered to call_ref, using reference types we generate a table.set to set
1180  // the funcref to a special table used solely for this purpose, followed by
1181  // a call_indirect. Here we just generate the table set, and return the
1182  // SDValue of the table.set so that LowerCall can finalize the lowering by
1183  // generating the call_indirect.
1184  SDValue Chain = Ops[0];
1185 
1187  MF.getContext(), Subtarget);
1188  SDValue Sym = DAG.getMCSymbol(Table, PtrVT);
1189  SDValue TableSlot = DAG.getConstant(0, DL, MVT::i32);
1190  SDValue TableSetOps[] = {Chain, Sym, TableSlot, Callee};
1191  SDValue TableSet = DAG.getMemIntrinsicNode(
1192  WebAssemblyISD::TABLE_SET, DL, DAG.getVTList(MVT::Other), TableSetOps,
1193  MVT::funcref,
1194  // Machine Mem Operand args
1197  CLI.CB->getCalledOperand()->getPointerAlignment(DAG.getDataLayout()),
1199 
1200  Ops[0] = TableSet; // The new chain is the TableSet itself
1201  }
1202 
1203  if (CLI.IsTailCall) {
1204  // ret_calls do not return values to the current frame
1205  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1206  return DAG.getNode(WebAssemblyISD::RET_CALL, DL, NodeTys, Ops);
1207  }
1208 
1209  InTys.push_back(MVT::Other);
1210  SDVTList InTyList = DAG.getVTList(InTys);
1211  SDValue Res = DAG.getNode(WebAssemblyISD::CALL, DL, InTyList, Ops);
1212 
1213  for (size_t I = 0; I < Ins.size(); ++I)
1214  InVals.push_back(Res.getValue(I));
1215 
1216  // Return the chain
1217  return Res.getValue(Ins.size());
1218 }
1219 
1220 bool WebAssemblyTargetLowering::CanLowerReturn(
1221  CallingConv::ID /*CallConv*/, MachineFunction & /*MF*/, bool /*IsVarArg*/,
1222  const SmallVectorImpl<ISD::OutputArg> &Outs,
1223  LLVMContext & /*Context*/) const {
1224  // WebAssembly can only handle returning tuples with multivalue enabled
1225  return Subtarget->hasMultivalue() || Outs.size() <= 1;
1226 }
1227 
1228 SDValue WebAssemblyTargetLowering::LowerReturn(
1229  SDValue Chain, CallingConv::ID CallConv, bool /*IsVarArg*/,
1230  const SmallVectorImpl<ISD::OutputArg> &Outs,
1231  const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
1232  SelectionDAG &DAG) const {
1233  assert((Subtarget->hasMultivalue() || Outs.size() <= 1) &&
1234  "MVP WebAssembly can only return up to one value");
1235  if (!callingConvSupported(CallConv))
1236  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
1237 
1238  SmallVector<SDValue, 4> RetOps(1, Chain);
1239  RetOps.append(OutVals.begin(), OutVals.end());
1240  Chain = DAG.getNode(WebAssemblyISD::RETURN, DL, MVT::Other, RetOps);
1241 
1242  // Record the number and types of the return values.
1243  for (const ISD::OutputArg &Out : Outs) {
1244  assert(!Out.Flags.isByVal() && "byval is not valid for return values");
1245  assert(!Out.Flags.isNest() && "nest is not valid for return values");
1246  assert(Out.IsFixed && "non-fixed return value is not valid");
1247  if (Out.Flags.isInAlloca())
1248  fail(DL, DAG, "WebAssembly hasn't implemented inalloca results");
1249  if (Out.Flags.isInConsecutiveRegs())
1250  fail(DL, DAG, "WebAssembly hasn't implemented cons regs results");
1251  if (Out.Flags.isInConsecutiveRegsLast())
1252  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results");
1253  }
1254 
1255  return Chain;
1256 }
1257 
1258 SDValue WebAssemblyTargetLowering::LowerFormalArguments(
1259  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
1260  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
1261  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
1262  if (!callingConvSupported(CallConv))
1263  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
1264 
1265  MachineFunction &MF = DAG.getMachineFunction();
1266  auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
1267 
1268  // Set up the incoming ARGUMENTS value, which serves to represent the liveness
1269  // of the incoming values before they're represented by virtual registers.
1270  MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
1271 
1272  bool HasSwiftErrorArg = false;
1273  bool HasSwiftSelfArg = false;
1274  for (const ISD::InputArg &In : Ins) {
1275  HasSwiftSelfArg |= In.Flags.isSwiftSelf();
1276  HasSwiftErrorArg |= In.Flags.isSwiftError();
1277  if (In.Flags.isInAlloca())
1278  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
1279  if (In.Flags.isNest())
1280  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
1281  if (In.Flags.isInConsecutiveRegs())
1282  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
1283  if (In.Flags.isInConsecutiveRegsLast())
1284  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
1285  // Ignore In.getNonZeroOrigAlign() because all our arguments are passed in
1286  // registers.
1287  InVals.push_back(In.Used ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
1288  DAG.getTargetConstant(InVals.size(),
1289  DL, MVT::i32))
1290  : DAG.getUNDEF(In.VT));
1291 
1292  // Record the number and types of arguments.
1293  MFI->addParam(In.VT);
1294  }
1295 
1296  // For swiftcc, emit additional swiftself and swifterror arguments
1297  // if there aren't. These additional arguments are also added for callee
1298  // signature They are necessary to match callee and caller signature for
1299  // indirect call.
1300  auto PtrVT = getPointerTy(MF.getDataLayout());
1301  if (CallConv == CallingConv::Swift) {
1302  if (!HasSwiftSelfArg) {
1303  MFI->addParam(PtrVT);
1304  }
1305  if (!HasSwiftErrorArg) {
1306  MFI->addParam(PtrVT);
1307  }
1308  }
1309  // Varargs are copied into a buffer allocated by the caller, and a pointer to
1310  // the buffer is passed as an argument.
1311  if (IsVarArg) {
1312  MVT PtrVT = getPointerTy(MF.getDataLayout());
1313  Register VarargVreg =
1315  MFI->setVarargBufferVreg(VarargVreg);
1316  Chain = DAG.getCopyToReg(
1317  Chain, DL, VarargVreg,
1318  DAG.getNode(WebAssemblyISD::ARGUMENT, DL, PtrVT,
1319  DAG.getTargetConstant(Ins.size(), DL, MVT::i32)));
1320  MFI->addParam(PtrVT);
1321  }
1322 
1323  // Record the number and types of arguments and results.
1324  SmallVector<MVT, 4> Params;
1327  MF.getFunction(), DAG.getTarget(), Params, Results);
1328  for (MVT VT : Results)
1329  MFI->addResult(VT);
1330  // TODO: Use signatures in WebAssemblyMachineFunctionInfo too and unify
1331  // the param logic here with ComputeSignatureVTs
1332  assert(MFI->getParams().size() == Params.size() &&
1333  std::equal(MFI->getParams().begin(), MFI->getParams().end(),
1334  Params.begin()));
1335 
1336  return Chain;
1337 }
1338 
1339 void WebAssemblyTargetLowering::ReplaceNodeResults(
1341  switch (N->getOpcode()) {
1343  // Do not add any results, signifying that N should not be custom lowered
1344  // after all. This happens because simd128 turns on custom lowering for
1345  // SIGN_EXTEND_INREG, but for non-vector sign extends the result might be an
1346  // illegal type.
1347  break;
1348  default:
1350  "ReplaceNodeResults not implemented for this op for WebAssembly!");
1351  }
1352 }
1353 
1354 //===----------------------------------------------------------------------===//
1355 // Custom lowering hooks.
1356 //===----------------------------------------------------------------------===//
1357 
1358 SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
1359  SelectionDAG &DAG) const {
1360  SDLoc DL(Op);
1361  switch (Op.getOpcode()) {
1362  default:
1363  llvm_unreachable("unimplemented operation lowering");
1364  return SDValue();
1365  case ISD::FrameIndex:
1366  return LowerFrameIndex(Op, DAG);
1367  case ISD::GlobalAddress:
1368  return LowerGlobalAddress(Op, DAG);
1369  case ISD::GlobalTLSAddress:
1370  return LowerGlobalTLSAddress(Op, DAG);
1371  case ISD::ExternalSymbol:
1372  return LowerExternalSymbol(Op, DAG);
1373  case ISD::JumpTable:
1374  return LowerJumpTable(Op, DAG);
1375  case ISD::BR_JT:
1376  return LowerBR_JT(Op, DAG);
1377  case ISD::VASTART:
1378  return LowerVASTART(Op, DAG);
1379  case ISD::BlockAddress:
1380  case ISD::BRIND:
1381  fail(DL, DAG, "WebAssembly hasn't implemented computed gotos");
1382  return SDValue();
1383  case ISD::RETURNADDR:
1384  return LowerRETURNADDR(Op, DAG);
1385  case ISD::FRAMEADDR:
1386  return LowerFRAMEADDR(Op, DAG);
1387  case ISD::CopyToReg:
1388  return LowerCopyToReg(Op, DAG);
1391  return LowerAccessVectorElement(Op, DAG);
1392  case ISD::INTRINSIC_VOID:
1395  return LowerIntrinsic(Op, DAG);
1397  return LowerSIGN_EXTEND_INREG(Op, DAG);
1398  case ISD::BUILD_VECTOR:
1399  return LowerBUILD_VECTOR(Op, DAG);
1400  case ISD::VECTOR_SHUFFLE:
1401  return LowerVECTOR_SHUFFLE(Op, DAG);
1402  case ISD::SETCC:
1403  return LowerSETCC(Op, DAG);
1404  case ISD::SHL:
1405  case ISD::SRA:
1406  case ISD::SRL:
1407  return LowerShift(Op, DAG);
1408  case ISD::FP_TO_SINT_SAT:
1409  case ISD::FP_TO_UINT_SAT:
1410  return LowerFP_TO_INT_SAT(Op, DAG);
1411  case ISD::LOAD:
1412  return LowerLoad(Op, DAG);
1413  case ISD::STORE:
1414  return LowerStore(Op, DAG);
1415  case ISD::CTPOP:
1416  case ISD::CTLZ:
1417  case ISD::CTTZ:
1418  return DAG.UnrollVectorOp(Op.getNode());
1419  }
1420 }
1421 
1423  if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op))
1425 
1426  return false;
1427 }
1428 
1430  const FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op);
1431  if (!FI)
1432  return None;
1433 
1434  auto &MF = DAG.getMachineFunction();
1436 }
1437 
1439  const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op);
1441  const GlobalValue *Value = GA->getGlobal();
1442  const Type *Ty = Value->getValueType();
1443 
1445  return true;
1446  }
1447  return false;
1448 }
1449 
1450 // This function will accept as Op any access to a table, so Op can
1451 // be the actual table or an offset into the table.
1453  if (Op->getOpcode() == ISD::ADD && Op->getNumOperands() == 2)
1454  return (Op->getOperand(1).getSimpleValueType() == MVT::i32 &&
1455  IsWebAssemblyTableWithOffset(Op->getOperand(0))) ||
1456  (Op->getOperand(0).getSimpleValueType() == MVT::i32 &&
1457  IsWebAssemblyTableWithOffset(Op->getOperand(1)));
1458 
1459  return IsWebAssemblyTable(Op);
1460 }
1461 
1462 // Helper for table pattern matching used in LowerStore and LowerLoad
1463 bool WebAssemblyTargetLowering::MatchTableForLowering(SelectionDAG &DAG,
1464  const SDLoc &DL,
1465  const SDValue &Base,
1466  GlobalAddressSDNode *&GA,
1467  SDValue &Idx) const {
1468  // We expect the following graph for a load of the form:
1469  // table[<var> + <constant offset>]
1470  //
1471  // Case 1:
1472  // externref = load t1
1473  // t1: i32 = add t2, i32:<constant offset>
1474  // t2: i32 = add tX, table
1475  //
1476  // This is in some cases simplified to just:
1477  // Case 2:
1478  // externref = load t1
1479  // t1: i32 = add t2, i32:tX
1480  //
1481  // So, unfortunately we need to check for both cases and if we are in the
1482  // first case extract the table GlobalAddressNode and build a new node tY
1483  // that's tY: i32 = add i32:<constant offset>, i32:tX
1484  //
1485  if (IsWebAssemblyTable(Base)) {
1486  GA = cast<GlobalAddressSDNode>(Base);
1487  Idx = DAG.getConstant(0, DL, MVT::i32);
1488  } else {
1489  GA = dyn_cast<GlobalAddressSDNode>(Base->getOperand(0));
1490  if (GA) {
1491  // We are in Case 2 above.
1492  Idx = Base->getOperand(1);
1493  if (!Idx || GA->getNumValues() != 1 || Idx->getNumValues() != 1)
1494  return false;
1495  } else {
1496  // This might be Case 1 above (or an error)
1497  SDValue V = Base->getOperand(0);
1498  GA = dyn_cast<GlobalAddressSDNode>(V->getOperand(1));
1499 
1500  if (V->getOpcode() != ISD::ADD || V->getNumOperands() != 2 || !GA)
1501  return false;
1502 
1503  SDValue IdxV = DAG.getNode(ISD::ADD, DL, MVT::i32, Base->getOperand(1),
1504  V->getOperand(0));
1505  Idx = IdxV;
1506  }
1507  }
1508 
1509  return true;
1510 }
1511 
1512 SDValue WebAssemblyTargetLowering::LowerStore(SDValue Op,
1513  SelectionDAG &DAG) const {
1514  SDLoc DL(Op);
1515  StoreSDNode *SN = cast<StoreSDNode>(Op.getNode());
1516  const SDValue &Value = SN->getValue();
1517  const SDValue &Base = SN->getBasePtr();
1518  const SDValue &Offset = SN->getOffset();
1519 
1521  if (!Offset->isUndef())
1523  "unexpected offset when loading from webassembly table", false);
1524 
1525  SDValue Idx;
1526  GlobalAddressSDNode *GA;
1527 
1528  if (!MatchTableForLowering(DAG, DL, Base, GA, Idx))
1529  report_fatal_error("failed pattern matching for lowering table store",
1530  false);
1531 
1532  SDVTList Tys = DAG.getVTList(MVT::Other);
1533  SDValue TableSetOps[] = {SN->getChain(), SDValue(GA, 0), Idx, Value};
1534  SDValue TableSet =
1535  DAG.getMemIntrinsicNode(WebAssemblyISD::TABLE_SET, DL, Tys, TableSetOps,
1536  SN->getMemoryVT(), SN->getMemOperand());
1537  return TableSet;
1538  }
1539 
1540  if (IsWebAssemblyGlobal(Base)) {
1541  if (!Offset->isUndef())
1542  report_fatal_error("unexpected offset when storing to webassembly global",
1543  false);
1544 
1545  SDVTList Tys = DAG.getVTList(MVT::Other);
1546  SDValue Ops[] = {SN->getChain(), Value, Base};
1547  return DAG.getMemIntrinsicNode(WebAssemblyISD::GLOBAL_SET, DL, Tys, Ops,
1548  SN->getMemoryVT(), SN->getMemOperand());
1549  }
1550 
1551  if (Optional<unsigned> Local = IsWebAssemblyLocal(Base, DAG)) {
1552  if (!Offset->isUndef())
1553  report_fatal_error("unexpected offset when storing to webassembly local",
1554  false);
1555 
1556  SDValue Idx = DAG.getTargetConstant(*Local, Base, MVT::i32);
1557  SDVTList Tys = DAG.getVTList(MVT::Other); // The chain.
1558  SDValue Ops[] = {SN->getChain(), Idx, Value};
1559  return DAG.getNode(WebAssemblyISD::LOCAL_SET, DL, Tys, Ops);
1560  }
1561 
1562  return Op;
1563 }
1564 
1565 SDValue WebAssemblyTargetLowering::LowerLoad(SDValue Op,
1566  SelectionDAG &DAG) const {
1567  SDLoc DL(Op);
1568  LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
1569  const SDValue &Base = LN->getBasePtr();
1570  const SDValue &Offset = LN->getOffset();
1571 
1573  if (!Offset->isUndef())
1575  "unexpected offset when loading from webassembly table", false);
1576 
1577  GlobalAddressSDNode *GA;
1578  SDValue Idx;
1579 
1580  if (!MatchTableForLowering(DAG, DL, Base, GA, Idx))
1581  report_fatal_error("failed pattern matching for lowering table load",
1582  false);
1583 
1584  SDVTList Tys = DAG.getVTList(LN->getValueType(0), MVT::Other);
1585  SDValue TableGetOps[] = {LN->getChain(), SDValue(GA, 0), Idx};
1586  SDValue TableGet =
1587  DAG.getMemIntrinsicNode(WebAssemblyISD::TABLE_GET, DL, Tys, TableGetOps,
1588  LN->getMemoryVT(), LN->getMemOperand());
1589  return TableGet;
1590  }
1591 
1592  if (IsWebAssemblyGlobal(Base)) {
1593  if (!Offset->isUndef())
1595  "unexpected offset when loading from webassembly global", false);
1596 
1597  SDVTList Tys = DAG.getVTList(LN->getValueType(0), MVT::Other);
1598  SDValue Ops[] = {LN->getChain(), Base};
1599  return DAG.getMemIntrinsicNode(WebAssemblyISD::GLOBAL_GET, DL, Tys, Ops,
1600  LN->getMemoryVT(), LN->getMemOperand());
1601  }
1602 
1603  if (Optional<unsigned> Local = IsWebAssemblyLocal(Base, DAG)) {
1604  if (!Offset->isUndef())
1606  "unexpected offset when loading from webassembly local", false);
1607 
1608  SDValue Idx = DAG.getTargetConstant(*Local, Base, MVT::i32);
1609  EVT LocalVT = LN->getValueType(0);
1610  SDValue LocalGet = DAG.getNode(WebAssemblyISD::LOCAL_GET, DL, LocalVT,
1611  {LN->getChain(), Idx});
1612  SDValue Result = DAG.getMergeValues({LocalGet, LN->getChain()}, DL);
1613  assert(Result->getNumValues() == 2 && "Loads must carry a chain!");
1614  return Result;
1615  }
1616 
1617  return Op;
1618 }
1619 
1620 SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op,
1621  SelectionDAG &DAG) const {
1622  SDValue Src = Op.getOperand(2);
1623  if (isa<FrameIndexSDNode>(Src.getNode())) {
1624  // CopyToReg nodes don't support FrameIndex operands. Other targets select
1625  // the FI to some LEA-like instruction, but since we don't have that, we
1626  // need to insert some kind of instruction that can take an FI operand and
1627  // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
1628  // local.copy between Op and its FI operand.
1629  SDValue Chain = Op.getOperand(0);
1630  SDLoc DL(Op);
1631  unsigned Reg = cast<RegisterSDNode>(Op.getOperand(1))->getReg();
1632  EVT VT = Src.getValueType();
1633  SDValue Copy(DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_I32
1634  : WebAssembly::COPY_I64,
1635  DL, VT, Src),
1636  0);
1637  return Op.getNode()->getNumValues() == 1
1638  ? DAG.getCopyToReg(Chain, DL, Reg, Copy)
1639  : DAG.getCopyToReg(Chain, DL, Reg, Copy,
1640  Op.getNumOperands() == 4 ? Op.getOperand(3)
1641  : SDValue());
1642  }
1643  return SDValue();
1644 }
1645 
1646 SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op,
1647  SelectionDAG &DAG) const {
1648  int FI = cast<FrameIndexSDNode>(Op)->getIndex();
1649  return DAG.getTargetFrameIndex(FI, Op.getValueType());
1650 }
1651 
1652 SDValue WebAssemblyTargetLowering::LowerRETURNADDR(SDValue Op,
1653  SelectionDAG &DAG) const {
1654  SDLoc DL(Op);
1655 
1656  if (!Subtarget->getTargetTriple().isOSEmscripten()) {
1657  fail(DL, DAG,
1658  "Non-Emscripten WebAssembly hasn't implemented "
1659  "__builtin_return_address");
1660  return SDValue();
1661  }
1662 
1664  return SDValue();
1665 
1666  unsigned Depth = Op.getConstantOperandVal(0);
1667  MakeLibCallOptions CallOptions;
1668  return makeLibCall(DAG, RTLIB::RETURN_ADDRESS, Op.getValueType(),
1669  {DAG.getConstant(Depth, DL, MVT::i32)}, CallOptions, DL)
1670  .first;
1671 }
1672 
1673 SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op,
1674  SelectionDAG &DAG) const {
1675  // Non-zero depths are not supported by WebAssembly currently. Use the
1676  // legalizer's default expansion, which is to return 0 (what this function is
1677  // documented to do).
1678  if (Op.getConstantOperandVal(0) > 0)
1679  return SDValue();
1680 
1682  EVT VT = Op.getValueType();
1683  Register FP =
1685  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT);
1686 }
1687 
1688 SDValue
1689 WebAssemblyTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1690  SelectionDAG &DAG) const {
1691  SDLoc DL(Op);
1692  const auto *GA = cast<GlobalAddressSDNode>(Op);
1693 
1694  MachineFunction &MF = DAG.getMachineFunction();
1696  report_fatal_error("cannot use thread-local storage without bulk memory",
1697  false);
1698 
1699  const GlobalValue *GV = GA->getGlobal();
1700 
1701  // Currently Emscripten does not support dynamic linking with threads.
1702  // Therefore, if we have thread-local storage, only the local-exec model
1703  // is possible.
1704  // TODO: remove this and implement proper TLS models once Emscripten
1705  // supports dynamic linking with threads.
1707  !Subtarget->getTargetTriple().isOSEmscripten()) {
1708  report_fatal_error("only -ftls-model=local-exec is supported for now on "
1709  "non-Emscripten OSes: variable " +
1710  GV->getName(),
1711  false);
1712  }
1713 
1714  auto model = GV->getThreadLocalMode();
1715 
1716  // Unsupported TLS modes
1719 
1723  getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))) {
1724  // For DSO-local TLS variables we use offset from __tls_base
1725 
1726  MVT PtrVT = getPointerTy(DAG.getDataLayout());
1727  auto GlobalGet = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64
1728  : WebAssembly::GLOBAL_GET_I32;
1729  const char *BaseName = MF.createExternalSymbolName("__tls_base");
1730 
1731  SDValue BaseAddr(
1732  DAG.getMachineNode(GlobalGet, DL, PtrVT,
1733  DAG.getTargetExternalSymbol(BaseName, PtrVT)),
1734  0);
1735 
1736  SDValue TLSOffset = DAG.getTargetGlobalAddress(
1737  GV, DL, PtrVT, GA->getOffset(), WebAssemblyII::MO_TLS_BASE_REL);
1738  SDValue SymOffset =
1739  DAG.getNode(WebAssemblyISD::WrapperREL, DL, PtrVT, TLSOffset);
1740 
1741  return DAG.getNode(ISD::ADD, DL, PtrVT, BaseAddr, SymOffset);
1742  }
1743 
1745 
1746  EVT VT = Op.getValueType();
1747  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1748  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
1749  GA->getOffset(),
1751 }
1752 
1753 SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
1754  SelectionDAG &DAG) const {
1755  SDLoc DL(Op);
1756  const auto *GA = cast<GlobalAddressSDNode>(Op);
1757  EVT VT = Op.getValueType();
1758  assert(GA->getTargetFlags() == 0 &&
1759  "Unexpected target flags on generic GlobalAddressSDNode");
1761  fail(DL, DAG, "Invalid address space for WebAssembly target");
1762 
1763  unsigned OperandFlags = 0;
1764  if (isPositionIndependent()) {
1765  const GlobalValue *GV = GA->getGlobal();
1766  if (getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV)) {
1767  MachineFunction &MF = DAG.getMachineFunction();
1768  MVT PtrVT = getPointerTy(MF.getDataLayout());
1769  const char *BaseName;
1770  if (GV->getValueType()->isFunctionTy()) {
1771  BaseName = MF.createExternalSymbolName("__table_base");
1773  }
1774  else {
1775  BaseName = MF.createExternalSymbolName("__memory_base");
1777  }
1778  SDValue BaseAddr =
1779  DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
1780  DAG.getTargetExternalSymbol(BaseName, PtrVT));
1781 
1782  SDValue SymAddr = DAG.getNode(
1783  WebAssemblyISD::WrapperREL, DL, VT,
1784  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset(),
1785  OperandFlags));
1786 
1787  return DAG.getNode(ISD::ADD, DL, VT, BaseAddr, SymAddr);
1788  }
1790  }
1791 
1792  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1793  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
1794  GA->getOffset(), OperandFlags));
1795 }
1796 
1797 SDValue
1798 WebAssemblyTargetLowering::LowerExternalSymbol(SDValue Op,
1799  SelectionDAG &DAG) const {
1800  SDLoc DL(Op);
1801  const auto *ES = cast<ExternalSymbolSDNode>(Op);
1802  EVT VT = Op.getValueType();
1803  assert(ES->getTargetFlags() == 0 &&
1804  "Unexpected target flags on generic ExternalSymbolSDNode");
1805  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1806  DAG.getTargetExternalSymbol(ES->getSymbol(), VT));
1807 }
1808 
1809 SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
1810  SelectionDAG &DAG) const {
1811  // There's no need for a Wrapper node because we always incorporate a jump
1812  // table operand into a BR_TABLE instruction, rather than ever
1813  // materializing it in a register.
1814  const JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1815  return DAG.getTargetJumpTable(JT->getIndex(), Op.getValueType(),
1816  JT->getTargetFlags());
1817 }
1818 
1819 SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op,
1820  SelectionDAG &DAG) const {
1821  SDLoc DL(Op);
1822  SDValue Chain = Op.getOperand(0);
1823  const auto *JT = cast<JumpTableSDNode>(Op.getOperand(1));
1824  SDValue Index = Op.getOperand(2);
1825  assert(JT->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
1826 
1828  Ops.push_back(Chain);
1829  Ops.push_back(Index);
1830 
1832  const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs;
1833 
1834  // Add an operand for each case.
1835  for (auto MBB : MBBs)
1836  Ops.push_back(DAG.getBasicBlock(MBB));
1837 
1838  // Add the first MBB as a dummy default target for now. This will be replaced
1839  // with the proper default target (and the preceding range check eliminated)
1840  // if possible by WebAssemblyFixBrTableDefaults.
1841  Ops.push_back(DAG.getBasicBlock(*MBBs.begin()));
1842  return DAG.getNode(WebAssemblyISD::BR_TABLE, DL, MVT::Other, Ops);
1843 }
1844 
1845 SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op,
1846  SelectionDAG &DAG) const {
1847  SDLoc DL(Op);
1849 
1850  auto *MFI = DAG.getMachineFunction().getInfo<WebAssemblyFunctionInfo>();
1851  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1852 
1853  SDValue ArgN = DAG.getCopyFromReg(DAG.getEntryNode(), DL,
1854  MFI->getVarargBufferVreg(), PtrVT);
1855  return DAG.getStore(Op.getOperand(0), DL, ArgN, Op.getOperand(1),
1856  MachinePointerInfo(SV));
1857 }
1858 
1859 SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
1860  SelectionDAG &DAG) const {
1861  MachineFunction &MF = DAG.getMachineFunction();
1862  unsigned IntNo;
1863  switch (Op.getOpcode()) {
1864  case ISD::INTRINSIC_VOID:
1866  IntNo = Op.getConstantOperandVal(1);
1867  break;
1869  IntNo = Op.getConstantOperandVal(0);
1870  break;
1871  default:
1872  llvm_unreachable("Invalid intrinsic");
1873  }
1874  SDLoc DL(Op);
1875 
1876  switch (IntNo) {
1877  default:
1878  return SDValue(); // Don't custom lower most intrinsics.
1879 
1880  case Intrinsic::wasm_lsda: {
1881  auto PtrVT = getPointerTy(MF.getDataLayout());
1882  const char *SymName = MF.createExternalSymbolName(
1883  "GCC_except_table" + std::to_string(MF.getFunctionNumber()));
1884  if (isPositionIndependent()) {
1885  SDValue Node = DAG.getTargetExternalSymbol(
1886  SymName, PtrVT, WebAssemblyII::MO_MEMORY_BASE_REL);
1887  const char *BaseName = MF.createExternalSymbolName("__memory_base");
1888  SDValue BaseAddr =
1889  DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
1890  DAG.getTargetExternalSymbol(BaseName, PtrVT));
1891  SDValue SymAddr =
1892  DAG.getNode(WebAssemblyISD::WrapperREL, DL, PtrVT, Node);
1893  return DAG.getNode(ISD::ADD, DL, PtrVT, BaseAddr, SymAddr);
1894  }
1895  SDValue Node = DAG.getTargetExternalSymbol(SymName, PtrVT);
1896  return DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT, Node);
1897  }
1898 
1899  case Intrinsic::wasm_shuffle: {
1900  // Drop in-chain and replace undefs, but otherwise pass through unchanged
1901  SDValue Ops[18];
1902  size_t OpIdx = 0;
1903  Ops[OpIdx++] = Op.getOperand(1);
1904  Ops[OpIdx++] = Op.getOperand(2);
1905  while (OpIdx < 18) {
1906  const SDValue &MaskIdx = Op.getOperand(OpIdx + 1);
1907  if (MaskIdx.isUndef() ||
1908  cast<ConstantSDNode>(MaskIdx.getNode())->getZExtValue() >= 32) {
1909  Ops[OpIdx++] = DAG.getConstant(0, DL, MVT::i32);
1910  } else {
1911  Ops[OpIdx++] = MaskIdx;
1912  }
1913  }
1914  return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
1915  }
1916  }
1917 }
1918 
1919 SDValue
1920 WebAssemblyTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
1921  SelectionDAG &DAG) const {
1922  SDLoc DL(Op);
1923  // If sign extension operations are disabled, allow sext_inreg only if operand
1924  // is a vector extract of an i8 or i16 lane. SIMD does not depend on sign
1925  // extension operations, but allowing sext_inreg in this context lets us have
1926  // simple patterns to select extract_lane_s instructions. Expanding sext_inreg
1927  // everywhere would be simpler in this file, but would necessitate large and
1928  // brittle patterns to undo the expansion and select extract_lane_s
1929  // instructions.
1930  assert(!Subtarget->hasSignExt() && Subtarget->hasSIMD128());
1931  if (Op.getOperand(0).getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1932  return SDValue();
1933 
1934  const SDValue &Extract = Op.getOperand(0);
1935  MVT VecT = Extract.getOperand(0).getSimpleValueType();
1936  if (VecT.getVectorElementType().getSizeInBits() > 32)
1937  return SDValue();
1938  MVT ExtractedLaneT =
1939  cast<VTSDNode>(Op.getOperand(1).getNode())->getVT().getSimpleVT();
1940  MVT ExtractedVecT =
1941  MVT::getVectorVT(ExtractedLaneT, 128 / ExtractedLaneT.getSizeInBits());
1942  if (ExtractedVecT == VecT)
1943  return Op;
1944 
1945  // Bitcast vector to appropriate type to ensure ISel pattern coverage
1946  const SDNode *Index = Extract.getOperand(1).getNode();
1947  if (!isa<ConstantSDNode>(Index))
1948  return SDValue();
1949  unsigned IndexVal = cast<ConstantSDNode>(Index)->getZExtValue();
1950  unsigned Scale =
1951  ExtractedVecT.getVectorNumElements() / VecT.getVectorNumElements();
1952  assert(Scale > 1);
1953  SDValue NewIndex =
1954  DAG.getConstant(IndexVal * Scale, DL, Index->getValueType(0));
1955  SDValue NewExtract = DAG.getNode(
1957  DAG.getBitcast(ExtractedVecT, Extract.getOperand(0)), NewIndex);
1958  return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Op.getValueType(), NewExtract,
1959  Op.getOperand(1));
1960 }
1961 
1963  SDLoc DL(Op);
1964  if (Op.getValueType() != MVT::v2f64)
1965  return SDValue();
1966 
1967  auto GetConvertedLane = [](SDValue Op, unsigned &Opcode, SDValue &SrcVec,
1968  unsigned &Index) -> bool {
1969  switch (Op.getOpcode()) {
1970  case ISD::SINT_TO_FP:
1971  Opcode = WebAssemblyISD::CONVERT_LOW_S;
1972  break;
1973  case ISD::UINT_TO_FP:
1974  Opcode = WebAssemblyISD::CONVERT_LOW_U;
1975  break;
1976  case ISD::FP_EXTEND:
1977  Opcode = WebAssemblyISD::PROMOTE_LOW;
1978  break;
1979  default:
1980  return false;
1981  }
1982 
1983  auto ExtractVector = Op.getOperand(0);
1984  if (ExtractVector.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1985  return false;
1986 
1987  if (!isa<ConstantSDNode>(ExtractVector.getOperand(1).getNode()))
1988  return false;
1989 
1990  SrcVec = ExtractVector.getOperand(0);
1991  Index = ExtractVector.getConstantOperandVal(1);
1992  return true;
1993  };
1994 
1995  unsigned LHSOpcode, RHSOpcode, LHSIndex, RHSIndex;
1996  SDValue LHSSrcVec, RHSSrcVec;
1997  if (!GetConvertedLane(Op.getOperand(0), LHSOpcode, LHSSrcVec, LHSIndex) ||
1998  !GetConvertedLane(Op.getOperand(1), RHSOpcode, RHSSrcVec, RHSIndex))
1999  return SDValue();
2000 
2001  if (LHSOpcode != RHSOpcode)
2002  return SDValue();
2003 
2004  MVT ExpectedSrcVT;
2005  switch (LHSOpcode) {
2006  case WebAssemblyISD::CONVERT_LOW_S:
2007  case WebAssemblyISD::CONVERT_LOW_U:
2008  ExpectedSrcVT = MVT::v4i32;
2009  break;
2010  case WebAssemblyISD::PROMOTE_LOW:
2011  ExpectedSrcVT = MVT::v4f32;
2012  break;
2013  }
2014  if (LHSSrcVec.getValueType() != ExpectedSrcVT)
2015  return SDValue();
2016 
2017  auto Src = LHSSrcVec;
2018  if (LHSIndex != 0 || RHSIndex != 1 || LHSSrcVec != RHSSrcVec) {
2019  // Shuffle the source vector so that the converted lanes are the low lanes.
2020  Src = DAG.getVectorShuffle(
2021  ExpectedSrcVT, DL, LHSSrcVec, RHSSrcVec,
2022  {static_cast<int>(LHSIndex), static_cast<int>(RHSIndex) + 4, -1, -1});
2023  }
2024  return DAG.getNode(LHSOpcode, DL, MVT::v2f64, Src);
2025 }
2026 
2027 SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
2028  SelectionDAG &DAG) const {
2029  if (auto ConvertLow = LowerConvertLow(Op, DAG))
2030  return ConvertLow;
2031 
2032  SDLoc DL(Op);
2033  const EVT VecT = Op.getValueType();
2034  const EVT LaneT = Op.getOperand(0).getValueType();
2035  const size_t Lanes = Op.getNumOperands();
2036  bool CanSwizzle = VecT == MVT::v16i8;
2037 
2038  // BUILD_VECTORs are lowered to the instruction that initializes the highest
2039  // possible number of lanes at once followed by a sequence of replace_lane
2040  // instructions to individually initialize any remaining lanes.
2041 
2042  // TODO: Tune this. For example, lanewise swizzling is very expensive, so
2043  // swizzled lanes should be given greater weight.
2044 
2045  // TODO: Investigate looping rather than always extracting/replacing specific
2046  // lanes to fill gaps.
2047 
2048  auto IsConstant = [](const SDValue &V) {
2049  return V.getOpcode() == ISD::Constant || V.getOpcode() == ISD::ConstantFP;
2050  };
2051 
2052  // Returns the source vector and index vector pair if they exist. Checks for:
2053  // (extract_vector_elt
2054  // $src,
2055  // (sign_extend_inreg (extract_vector_elt $indices, $i))
2056  // )
2057  auto GetSwizzleSrcs = [](size_t I, const SDValue &Lane) {
2058  auto Bail = std::make_pair(SDValue(), SDValue());
2059  if (Lane->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
2060  return Bail;
2061  const SDValue &SwizzleSrc = Lane->getOperand(0);
2062  const SDValue &IndexExt = Lane->getOperand(1);
2063  if (IndexExt->getOpcode() != ISD::SIGN_EXTEND_INREG)
2064  return Bail;
2065  const SDValue &Index = IndexExt->getOperand(0);
2066  if (Index->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
2067  return Bail;
2068  const SDValue &SwizzleIndices = Index->getOperand(0);
2069  if (SwizzleSrc.getValueType() != MVT::v16i8 ||
2070  SwizzleIndices.getValueType() != MVT::v16i8 ||
2071  Index->getOperand(1)->getOpcode() != ISD::Constant ||
2072  Index->getConstantOperandVal(1) != I)
2073  return Bail;
2074  return std::make_pair(SwizzleSrc, SwizzleIndices);
2075  };
2076 
2077  // If the lane is extracted from another vector at a constant index, return
2078  // that vector. The source vector must not have more lanes than the dest
2079  // because the shufflevector indices are in terms of the destination lanes and
2080  // would not be able to address the smaller individual source lanes.
2081  auto GetShuffleSrc = [&](const SDValue &Lane) {
2082  if (Lane->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
2083  return SDValue();
2084  if (!isa<ConstantSDNode>(Lane->getOperand(1).getNode()))
2085  return SDValue();
2086  if (Lane->getOperand(0).getValueType().getVectorNumElements() >
2087  VecT.getVectorNumElements())
2088  return SDValue();
2089  return Lane->getOperand(0);
2090  };
2091 
2092  using ValueEntry = std::pair<SDValue, size_t>;
2093  SmallVector<ValueEntry, 16> SplatValueCounts;
2094 
2095  using SwizzleEntry = std::pair<std::pair<SDValue, SDValue>, size_t>;
2096  SmallVector<SwizzleEntry, 16> SwizzleCounts;
2097 
2098  using ShuffleEntry = std::pair<SDValue, size_t>;
2099  SmallVector<ShuffleEntry, 16> ShuffleCounts;
2100 
2101  auto AddCount = [](auto &Counts, const auto &Val) {
2102  auto CountIt =
2103  llvm::find_if(Counts, [&Val](auto E) { return E.first == Val; });
2104  if (CountIt == Counts.end()) {
2105  Counts.emplace_back(Val, 1);
2106  } else {
2107  CountIt->second++;
2108  }
2109  };
2110 
2111  auto GetMostCommon = [](auto &Counts) {
2112  auto CommonIt =
2113  std::max_element(Counts.begin(), Counts.end(),
2114  [](auto A, auto B) { return A.second < B.second; });
2115  assert(CommonIt != Counts.end() && "Unexpected all-undef build_vector");
2116  return *CommonIt;
2117  };
2118 
2119  size_t NumConstantLanes = 0;
2120 
2121  // Count eligible lanes for each type of vector creation op
2122  for (size_t I = 0; I < Lanes; ++I) {
2123  const SDValue &Lane = Op->getOperand(I);
2124  if (Lane.isUndef())
2125  continue;
2126 
2127  AddCount(SplatValueCounts, Lane);
2128 
2129  if (IsConstant(Lane))
2130  NumConstantLanes++;
2131  if (auto ShuffleSrc = GetShuffleSrc(Lane))
2132  AddCount(ShuffleCounts, ShuffleSrc);
2133  if (CanSwizzle) {
2134  auto SwizzleSrcs = GetSwizzleSrcs(I, Lane);
2135  if (SwizzleSrcs.first)
2136  AddCount(SwizzleCounts, SwizzleSrcs);
2137  }
2138  }
2139 
2140  SDValue SplatValue;
2141  size_t NumSplatLanes;
2142  std::tie(SplatValue, NumSplatLanes) = GetMostCommon(SplatValueCounts);
2143 
2144  SDValue SwizzleSrc;
2145  SDValue SwizzleIndices;
2146  size_t NumSwizzleLanes = 0;
2147  if (SwizzleCounts.size())
2148  std::forward_as_tuple(std::tie(SwizzleSrc, SwizzleIndices),
2149  NumSwizzleLanes) = GetMostCommon(SwizzleCounts);
2150 
2151  // Shuffles can draw from up to two vectors, so find the two most common
2152  // sources.
2153  SDValue ShuffleSrc1, ShuffleSrc2;
2154  size_t NumShuffleLanes = 0;
2155  if (ShuffleCounts.size()) {
2156  std::tie(ShuffleSrc1, NumShuffleLanes) = GetMostCommon(ShuffleCounts);
2157  llvm::erase_if(ShuffleCounts,
2158  [&](const auto &Pair) { return Pair.first == ShuffleSrc1; });
2159  }
2160  if (ShuffleCounts.size()) {
2161  size_t AdditionalShuffleLanes;
2162  std::tie(ShuffleSrc2, AdditionalShuffleLanes) =
2163  GetMostCommon(ShuffleCounts);
2164  NumShuffleLanes += AdditionalShuffleLanes;
2165  }
2166 
2167  // Predicate returning true if the lane is properly initialized by the
2168  // original instruction
2169  std::function<bool(size_t, const SDValue &)> IsLaneConstructed;
2170  SDValue Result;
2171  // Prefer swizzles over shuffles over vector consts over splats
2172  if (NumSwizzleLanes >= NumShuffleLanes &&
2173  NumSwizzleLanes >= NumConstantLanes && NumSwizzleLanes >= NumSplatLanes) {
2174  Result = DAG.getNode(WebAssemblyISD::SWIZZLE, DL, VecT, SwizzleSrc,
2175  SwizzleIndices);
2176  auto Swizzled = std::make_pair(SwizzleSrc, SwizzleIndices);
2177  IsLaneConstructed = [&, Swizzled](size_t I, const SDValue &Lane) {
2178  return Swizzled == GetSwizzleSrcs(I, Lane);
2179  };
2180  } else if (NumShuffleLanes >= NumConstantLanes &&
2181  NumShuffleLanes >= NumSplatLanes) {
2182  size_t DestLaneSize = VecT.getVectorElementType().getFixedSizeInBits() / 8;
2183  size_t DestLaneCount = VecT.getVectorNumElements();
2184  size_t Scale1 = 1;
2185  size_t Scale2 = 1;
2186  SDValue Src1 = ShuffleSrc1;
2187  SDValue Src2 = ShuffleSrc2 ? ShuffleSrc2 : DAG.getUNDEF(VecT);
2188  if (Src1.getValueType() != VecT) {
2189  size_t LaneSize =
2191  assert(LaneSize > DestLaneSize);
2192  Scale1 = LaneSize / DestLaneSize;
2193  Src1 = DAG.getBitcast(VecT, Src1);
2194  }
2195  if (Src2.getValueType() != VecT) {
2196  size_t LaneSize =
2198  assert(LaneSize > DestLaneSize);
2199  Scale2 = LaneSize / DestLaneSize;
2200  Src2 = DAG.getBitcast(VecT, Src2);
2201  }
2202 
2203  int Mask[16];
2204  assert(DestLaneCount <= 16);
2205  for (size_t I = 0; I < DestLaneCount; ++I) {
2206  const SDValue &Lane = Op->getOperand(I);
2207  SDValue Src = GetShuffleSrc(Lane);
2208  if (Src == ShuffleSrc1) {
2209  Mask[I] = Lane->getConstantOperandVal(1) * Scale1;
2210  } else if (Src && Src == ShuffleSrc2) {
2211  Mask[I] = DestLaneCount + Lane->getConstantOperandVal(1) * Scale2;
2212  } else {
2213  Mask[I] = -1;
2214  }
2215  }
2216  ArrayRef<int> MaskRef(Mask, DestLaneCount);
2217  Result = DAG.getVectorShuffle(VecT, DL, Src1, Src2, MaskRef);
2218  IsLaneConstructed = [&](size_t, const SDValue &Lane) {
2219  auto Src = GetShuffleSrc(Lane);
2220  return Src == ShuffleSrc1 || (Src && Src == ShuffleSrc2);
2221  };
2222  } else if (NumConstantLanes >= NumSplatLanes) {
2223  SmallVector<SDValue, 16> ConstLanes;
2224  for (const SDValue &Lane : Op->op_values()) {
2225  if (IsConstant(Lane)) {
2226  // Values may need to be fixed so that they will sign extend to be
2227  // within the expected range during ISel. Check whether the value is in
2228  // bounds based on the lane bit width and if it is out of bounds, lop
2229  // off the extra bits and subtract 2^n to reflect giving the high bit
2230  // value -2^(n-1) rather than +2^(n-1). Skip the i64 case because it
2231  // cannot possibly be out of range.
2232  auto *Const = dyn_cast<ConstantSDNode>(Lane.getNode());
2233  int64_t Val = Const ? Const->getSExtValue() : 0;
2234  uint64_t LaneBits = 128 / Lanes;
2235  assert((LaneBits == 64 || Val >= -(1ll << (LaneBits - 1))) &&
2236  "Unexpected out of bounds negative value");
2237  if (Const && LaneBits != 64 && Val > (1ll << (LaneBits - 1)) - 1) {
2238  auto NewVal = ((uint64_t)Val % (1ll << LaneBits)) - (1ll << LaneBits);
2239  ConstLanes.push_back(DAG.getConstant(NewVal, SDLoc(Lane), LaneT));
2240  } else {
2241  ConstLanes.push_back(Lane);
2242  }
2243  } else if (LaneT.isFloatingPoint()) {
2244  ConstLanes.push_back(DAG.getConstantFP(0, DL, LaneT));
2245  } else {
2246  ConstLanes.push_back(DAG.getConstant(0, DL, LaneT));
2247  }
2248  }
2249  Result = DAG.getBuildVector(VecT, DL, ConstLanes);
2250  IsLaneConstructed = [&IsConstant](size_t _, const SDValue &Lane) {
2251  return IsConstant(Lane);
2252  };
2253  } else {
2254  // Use a splat, but possibly a load_splat
2255  LoadSDNode *SplattedLoad;
2256  if ((SplattedLoad = dyn_cast<LoadSDNode>(SplatValue)) &&
2257  SplattedLoad->getMemoryVT() == VecT.getVectorElementType()) {
2259  WebAssemblyISD::LOAD_SPLAT, DL, DAG.getVTList(VecT),
2260  {SplattedLoad->getChain(), SplattedLoad->getBasePtr(),
2261  SplattedLoad->getOffset()},
2262  SplattedLoad->getMemoryVT(), SplattedLoad->getMemOperand());
2263  } else {
2264  Result = DAG.getSplatBuildVector(VecT, DL, SplatValue);
2265  }
2266  IsLaneConstructed = [&SplatValue](size_t _, const SDValue &Lane) {
2267  return Lane == SplatValue;
2268  };
2269  }
2270 
2271  assert(Result);
2272  assert(IsLaneConstructed);
2273 
2274  // Add replace_lane instructions for any unhandled values
2275  for (size_t I = 0; I < Lanes; ++I) {
2276  const SDValue &Lane = Op->getOperand(I);
2277  if (!Lane.isUndef() && !IsLaneConstructed(I, Lane))
2278  Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VecT, Result, Lane,
2279  DAG.getConstant(I, DL, MVT::i32));
2280  }
2281 
2282  return Result;
2283 }
2284 
2285 SDValue
2286 WebAssemblyTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
2287  SelectionDAG &DAG) const {
2288  SDLoc DL(Op);
2289  ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Op.getNode())->getMask();
2290  MVT VecType = Op.getOperand(0).getSimpleValueType();
2291  assert(VecType.is128BitVector() && "Unexpected shuffle vector type");
2292  size_t LaneBytes = VecType.getVectorElementType().getSizeInBits() / 8;
2293 
2294  // Space for two vector args and sixteen mask indices
2295  SDValue Ops[18];
2296  size_t OpIdx = 0;
2297  Ops[OpIdx++] = Op.getOperand(0);
2298  Ops[OpIdx++] = Op.getOperand(1);
2299 
2300  // Expand mask indices to byte indices and materialize them as operands
2301  for (int M : Mask) {
2302  for (size_t J = 0; J < LaneBytes; ++J) {
2303  // Lower undefs (represented by -1 in mask) to zero
2304  uint64_t ByteIndex = M == -1 ? 0 : (uint64_t)M * LaneBytes + J;
2305  Ops[OpIdx++] = DAG.getConstant(ByteIndex, DL, MVT::i32);
2306  }
2307  }
2308 
2309  return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
2310 }
2311 
2312 SDValue WebAssemblyTargetLowering::LowerSETCC(SDValue Op,
2313  SelectionDAG &DAG) const {
2314  SDLoc DL(Op);
2315  // The legalizer does not know how to expand the unsupported comparison modes
2316  // of i64x2 vectors, so we manually unroll them here.
2317  assert(Op->getOperand(0)->getSimpleValueType(0) == MVT::v2i64);
2318  SmallVector<SDValue, 2> LHS, RHS;
2319  DAG.ExtractVectorElements(Op->getOperand(0), LHS);
2320  DAG.ExtractVectorElements(Op->getOperand(1), RHS);
2321  const SDValue &CC = Op->getOperand(2);
2322  auto MakeLane = [&](unsigned I) {
2323  return DAG.getNode(ISD::SELECT_CC, DL, MVT::i64, LHS[I], RHS[I],
2324  DAG.getConstant(uint64_t(-1), DL, MVT::i64),
2325  DAG.getConstant(uint64_t(0), DL, MVT::i64), CC);
2326  };
2327  return DAG.getBuildVector(Op->getValueType(0), DL,
2328  {MakeLane(0), MakeLane(1)});
2329 }
2330 
2331 SDValue
2332 WebAssemblyTargetLowering::LowerAccessVectorElement(SDValue Op,
2333  SelectionDAG &DAG) const {
2334  // Allow constant lane indices, expand variable lane indices
2335  SDNode *IdxNode = Op.getOperand(Op.getNumOperands() - 1).getNode();
2336  if (isa<ConstantSDNode>(IdxNode) || IdxNode->isUndef())
2337  return Op;
2338  else
2339  // Perform default expansion
2340  return SDValue();
2341 }
2342 
2344  EVT LaneT = Op.getSimpleValueType().getVectorElementType();
2345  // 32-bit and 64-bit unrolled shifts will have proper semantics
2346  if (LaneT.bitsGE(MVT::i32))
2347  return DAG.UnrollVectorOp(Op.getNode());
2348  // Otherwise mask the shift value to get proper semantics from 32-bit shift
2349  SDLoc DL(Op);
2350  size_t NumLanes = Op.getSimpleValueType().getVectorNumElements();
2351  SDValue Mask = DAG.getConstant(LaneT.getSizeInBits() - 1, DL, MVT::i32);
2352  unsigned ShiftOpcode = Op.getOpcode();
2353  SmallVector<SDValue, 16> ShiftedElements;
2354  DAG.ExtractVectorElements(Op.getOperand(0), ShiftedElements, 0, 0, MVT::i32);
2355  SmallVector<SDValue, 16> ShiftElements;
2356  DAG.ExtractVectorElements(Op.getOperand(1), ShiftElements, 0, 0, MVT::i32);
2357  SmallVector<SDValue, 16> UnrolledOps;
2358  for (size_t i = 0; i < NumLanes; ++i) {
2359  SDValue MaskedShiftValue =
2360  DAG.getNode(ISD::AND, DL, MVT::i32, ShiftElements[i], Mask);
2361  SDValue ShiftedValue = ShiftedElements[i];
2362  if (ShiftOpcode == ISD::SRA)
2363  ShiftedValue = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32,
2364  ShiftedValue, DAG.getValueType(LaneT));
2365  UnrolledOps.push_back(
2366  DAG.getNode(ShiftOpcode, DL, MVT::i32, ShiftedValue, MaskedShiftValue));
2367  }
2368  return DAG.getBuildVector(Op.getValueType(), DL, UnrolledOps);
2369 }
2370 
2371 SDValue WebAssemblyTargetLowering::LowerShift(SDValue Op,
2372  SelectionDAG &DAG) const {
2373  SDLoc DL(Op);
2374 
2375  // Only manually lower vector shifts
2376  assert(Op.getSimpleValueType().isVector());
2377 
2378  auto ShiftVal = DAG.getSplatValue(Op.getOperand(1));
2379  if (!ShiftVal)
2380  return unrollVectorShift(Op, DAG);
2381 
2382  // Use anyext because none of the high bits can affect the shift
2383  ShiftVal = DAG.getAnyExtOrTrunc(ShiftVal, DL, MVT::i32);
2384 
2385  unsigned Opcode;
2386  switch (Op.getOpcode()) {
2387  case ISD::SHL:
2388  Opcode = WebAssemblyISD::VEC_SHL;
2389  break;
2390  case ISD::SRA:
2391  Opcode = WebAssemblyISD::VEC_SHR_S;
2392  break;
2393  case ISD::SRL:
2394  Opcode = WebAssemblyISD::VEC_SHR_U;
2395  break;
2396  default:
2397  llvm_unreachable("unexpected opcode");
2398  }
2399 
2400  return DAG.getNode(Opcode, DL, Op.getValueType(), Op.getOperand(0), ShiftVal);
2401 }
2402 
2403 SDValue WebAssemblyTargetLowering::LowerFP_TO_INT_SAT(SDValue Op,
2404  SelectionDAG &DAG) const {
2405  SDLoc DL(Op);
2406  EVT ResT = Op.getValueType();
2407  EVT SatVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
2408 
2409  if ((ResT == MVT::i32 || ResT == MVT::i64) &&
2410  (SatVT == MVT::i32 || SatVT == MVT::i64))
2411  return Op;
2412 
2413  if (ResT == MVT::v4i32 && SatVT == MVT::i32)
2414  return Op;
2415 
2416  return SDValue();
2417 }
2418 
2419 //===----------------------------------------------------------------------===//
2420 // Custom DAG combine hooks
2421 //===----------------------------------------------------------------------===//
2422 static SDValue
2424  auto &DAG = DCI.DAG;
2425  auto Shuffle = cast<ShuffleVectorSDNode>(N);
2426 
2427  // Hoist vector bitcasts that don't change the number of lanes out of unary
2428  // shuffles, where they are less likely to get in the way of other combines.
2429  // (shuffle (vNxT1 (bitcast (vNxT0 x))), undef, mask) ->
2430  // (vNxT1 (bitcast (vNxT0 (shuffle x, undef, mask))))
2431  SDValue Bitcast = N->getOperand(0);
2432  if (Bitcast.getOpcode() != ISD::BITCAST)
2433  return SDValue();
2434  if (!N->getOperand(1).isUndef())
2435  return SDValue();
2436  SDValue CastOp = Bitcast.getOperand(0);
2437  MVT SrcType = CastOp.getSimpleValueType();
2438  MVT DstType = Bitcast.getSimpleValueType();
2439  if (!SrcType.is128BitVector() ||
2440  SrcType.getVectorNumElements() != DstType.getVectorNumElements())
2441  return SDValue();
2442  SDValue NewShuffle = DAG.getVectorShuffle(
2443  SrcType, SDLoc(N), CastOp, DAG.getUNDEF(SrcType), Shuffle->getMask());
2444  return DAG.getBitcast(DstType, NewShuffle);
2445 }
2446 
2447 static SDValue
2449  auto &DAG = DCI.DAG;
2450  assert(N->getOpcode() == ISD::SIGN_EXTEND ||
2451  N->getOpcode() == ISD::ZERO_EXTEND);
2452 
2453  // Combine ({s,z}ext (extract_subvector src, i)) into a widening operation if
2454  // possible before the extract_subvector can be expanded.
2455  auto Extract = N->getOperand(0);
2456  if (Extract.getOpcode() != ISD::EXTRACT_SUBVECTOR)
2457  return SDValue();
2458  auto Source = Extract.getOperand(0);
2459  auto *IndexNode = dyn_cast<ConstantSDNode>(Extract.getOperand(1));
2460  if (IndexNode == nullptr)
2461  return SDValue();
2462  auto Index = IndexNode->getZExtValue();
2463 
2464  // Only v8i8, v4i16, and v2i32 extracts can be widened, and only if the
2465  // extracted subvector is the low or high half of its source.
2466  EVT ResVT = N->getValueType(0);
2467  if (ResVT == MVT::v8i16) {
2468  if (Extract.getValueType() != MVT::v8i8 ||
2469  Source.getValueType() != MVT::v16i8 || (Index != 0 && Index != 8))
2470  return SDValue();
2471  } else if (ResVT == MVT::v4i32) {
2472  if (Extract.getValueType() != MVT::v4i16 ||
2473  Source.getValueType() != MVT::v8i16 || (Index != 0 && Index != 4))
2474  return SDValue();
2475  } else if (ResVT == MVT::v2i64) {
2476  if (Extract.getValueType() != MVT::v2i32 ||
2477  Source.getValueType() != MVT::v4i32 || (Index != 0 && Index != 2))
2478  return SDValue();
2479  } else {
2480  return SDValue();
2481  }
2482 
2483  bool IsSext = N->getOpcode() == ISD::SIGN_EXTEND;
2484  bool IsLow = Index == 0;
2485 
2486  unsigned Op = IsSext ? (IsLow ? WebAssemblyISD::EXTEND_LOW_S
2487  : WebAssemblyISD::EXTEND_HIGH_S)
2488  : (IsLow ? WebAssemblyISD::EXTEND_LOW_U
2489  : WebAssemblyISD::EXTEND_HIGH_U);
2490 
2491  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2492 }
2493 
2494 static SDValue
2496  auto &DAG = DCI.DAG;
2497 
2498  auto GetWasmConversionOp = [](unsigned Op) {
2499  switch (Op) {
2500  case ISD::FP_TO_SINT_SAT:
2501  return WebAssemblyISD::TRUNC_SAT_ZERO_S;
2502  case ISD::FP_TO_UINT_SAT:
2503  return WebAssemblyISD::TRUNC_SAT_ZERO_U;
2504  case ISD::FP_ROUND:
2505  return WebAssemblyISD::DEMOTE_ZERO;
2506  }
2507  llvm_unreachable("unexpected op");
2508  };
2509 
2510  auto IsZeroSplat = [](SDValue SplatVal) {
2511  auto *Splat = dyn_cast<BuildVectorSDNode>(SplatVal.getNode());
2512  APInt SplatValue, SplatUndef;
2513  unsigned SplatBitSize;
2514  bool HasAnyUndefs;
2515  return Splat &&
2516  Splat->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
2517  HasAnyUndefs) &&
2518  SplatValue == 0;
2519  };
2520 
2521  if (N->getOpcode() == ISD::CONCAT_VECTORS) {
2522  // Combine this:
2523  //
2524  // (concat_vectors (v2i32 (fp_to_{s,u}int_sat $x, 32)), (v2i32 (splat 0)))
2525  //
2526  // into (i32x4.trunc_sat_f64x2_zero_{s,u} $x).
2527  //
2528  // Or this:
2529  //
2530  // (concat_vectors (v2f32 (fp_round (v2f64 $x))), (v2f32 (splat 0)))
2531  //
2532  // into (f32x4.demote_zero_f64x2 $x).
2533  EVT ResVT;
2534  EVT ExpectedConversionType;
2535  auto Conversion = N->getOperand(0);
2536  auto ConversionOp = Conversion.getOpcode();
2537  switch (ConversionOp) {
2538  case ISD::FP_TO_SINT_SAT:
2539  case ISD::FP_TO_UINT_SAT:
2540  ResVT = MVT::v4i32;
2541  ExpectedConversionType = MVT::v2i32;
2542  break;
2543  case ISD::FP_ROUND:
2544  ResVT = MVT::v4f32;
2545  ExpectedConversionType = MVT::v2f32;
2546  break;
2547  default:
2548  return SDValue();
2549  }
2550 
2551  if (N->getValueType(0) != ResVT)
2552  return SDValue();
2553 
2554  if (Conversion.getValueType() != ExpectedConversionType)
2555  return SDValue();
2556 
2557  auto Source = Conversion.getOperand(0);
2558  if (Source.getValueType() != MVT::v2f64)
2559  return SDValue();
2560 
2561  if (!IsZeroSplat(N->getOperand(1)) ||
2562  N->getOperand(1).getValueType() != ExpectedConversionType)
2563  return SDValue();
2564 
2565  unsigned Op = GetWasmConversionOp(ConversionOp);
2566  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2567  }
2568 
2569  // Combine this:
2570  //
2571  // (fp_to_{s,u}int_sat (concat_vectors $x, (v2f64 (splat 0))), 32)
2572  //
2573  // into (i32x4.trunc_sat_f64x2_zero_{s,u} $x).
2574  //
2575  // Or this:
2576  //
2577  // (v4f32 (fp_round (concat_vectors $x, (v2f64 (splat 0)))))
2578  //
2579  // into (f32x4.demote_zero_f64x2 $x).
2580  EVT ResVT;
2581  auto ConversionOp = N->getOpcode();
2582  switch (ConversionOp) {
2583  case ISD::FP_TO_SINT_SAT:
2584  case ISD::FP_TO_UINT_SAT:
2585  ResVT = MVT::v4i32;
2586  break;
2587  case ISD::FP_ROUND:
2588  ResVT = MVT::v4f32;
2589  break;
2590  default:
2591  llvm_unreachable("unexpected op");
2592  }
2593 
2594  if (N->getValueType(0) != ResVT)
2595  return SDValue();
2596 
2597  auto Concat = N->getOperand(0);
2598  if (Concat.getValueType() != MVT::v4f64)
2599  return SDValue();
2600 
2601  auto Source = Concat.getOperand(0);
2602  if (Source.getValueType() != MVT::v2f64)
2603  return SDValue();
2604 
2605  if (!IsZeroSplat(Concat.getOperand(1)) ||
2606  Concat.getOperand(1).getValueType() != MVT::v2f64)
2607  return SDValue();
2608 
2609  unsigned Op = GetWasmConversionOp(ConversionOp);
2610  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2611 }
2612 
2613 SDValue
2614 WebAssemblyTargetLowering::PerformDAGCombine(SDNode *N,
2615  DAGCombinerInfo &DCI) const {
2616  switch (N->getOpcode()) {
2617  default:
2618  return SDValue();
2619  case ISD::VECTOR_SHUFFLE:
2620  return performVECTOR_SHUFFLECombine(N, DCI);
2621  case ISD::SIGN_EXTEND:
2622  case ISD::ZERO_EXTEND:
2623  return performVectorExtendCombine(N, DCI);
2624  case ISD::FP_TO_SINT_SAT:
2625  case ISD::FP_TO_UINT_SAT:
2626  case ISD::FP_ROUND:
2627  case ISD::CONCAT_VECTORS:
2628  return performVectorTruncZeroCombine(N, DCI);
2629  }
2630 }
llvm::TargetLoweringBase::getPreferredVectorAction
virtual TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const
Return the preferred vector type legalization action.
Definition: TargetLowering.h:446
IsWebAssemblyLocal
static Optional< unsigned > IsWebAssemblyLocal(SDValue Op, SelectionDAG &DAG)
Definition: WebAssemblyISelLowering.cpp:1429
llvm::MachineRegisterInfo::addLiveIn
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Definition: MachineRegisterInfo.h:957
llvm::SDNode::getConstantOperandVal
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
Definition: SelectionDAGNodes.h:1596
i
i
Definition: README.txt:29
llvm::NextPowerOf2
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition: MathExtras.h:683
llvm::ISD::ExternalSymbol
@ ExternalSymbol
Definition: ISDOpcodes.h:83
llvm::ISD::ArgFlagsTy::isInAlloca
bool isInAlloca() const
Definition: TargetCallingConv.h:91
llvm::ISD::SETUGE
@ SETUGE
Definition: ISDOpcodes.h:1379
performVectorExtendCombine
static SDValue performVectorExtendCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2448
llvm::LoadSDNode::getOffset
const SDValue & getOffset() const
Definition: SelectionDAGNodes.h:2317
llvm::WebAssemblySubtarget::getRegisterInfo
const WebAssemblyRegisterInfo * getRegisterInfo() const override
Definition: WebAssemblySubtarget.h:81
CmpMode::FP
@ FP
llvm::TargetLoweringBase::getPointerMemTy
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
Definition: TargetLowering.h:353
llvm::StoreSDNode::getBasePtr
const SDValue & getBasePtr() const
Definition: SelectionDAGNodes.h:2347
llvm::TargetLoweringBase::setSchedulingPreference
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
Definition: TargetLowering.h:2142
llvm::ISD::VECTOR_SHUFFLE
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition: ISDOpcodes.h:563
llvm::WebAssemblySubtarget::getTargetTriple
const Triple & getTargetTriple() const
Definition: WebAssemblySubtarget.h:84
llvm::MVT::getVectorElementType
MVT getVectorElementType() const
Definition: MachineValueType.h:519
llvm::ISD::INTRINSIC_VOID
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition: ISDOpcodes.h:199
llvm::MachineInstr::uses
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
Definition: MachineInstr.h:666
llvm::ISD::SETO
@ SETO
Definition: ISDOpcodes.h:1375
llvm::Value::stripPointerCastsAndAliases
const Value * stripPointerCastsAndAliases() const
Strip off pointer casts, all-zero GEPs, address space casts, and aliases.
Definition: Value.cpp:689
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
MathExtras.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
Reg
unsigned Reg
Definition: MachineSink.cpp:1558
llvm::ISD::JumpTable
@ JumpTable
Definition: ISDOpcodes.h:81
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::SDNode::getValueType
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Definition: SelectionDAGNodes.h:965
llvm::MachineInstrBuilder::addFPImm
const MachineInstrBuilder & addFPImm(const ConstantFP *Val) const
Definition: MachineInstrBuilder.h:141
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:266
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1085
llvm::MVT::isFixedLengthVector
bool isFixedLengthVector() const
Definition: MachineValueType.h:378
llvm::CCValAssign::Full
@ Full
Definition: CallingConvLower.h:36
llvm::TargetLoweringBase::Legal
@ Legal
Definition: TargetLowering.h:197
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::MVT::isInteger
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: MachineValueType.h:350
llvm::ISD::BITCAST
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:848
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:158
WebAssemblyISelLowering.h
llvm::ISD::BR_JT
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:946
llvm::WebAssemblySubtarget::hasTailCall
bool hasTailCall() const
Definition: WebAssemblySubtarget.h:101
llvm::DiagnosticInfoUnsupported
Diagnostic information for unsupported feature in backend.
Definition: DiagnosticInfo.h:1004
llvm::CCState
CCState - This class holds information needed while lowering arguments and return values.
Definition: CallingConvLower.h:191
llvm::SelectionDAG::getCopyToReg
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:735
llvm::GlobalValue::LocalDynamicTLSModel
@ LocalDynamicTLSModel
Definition: GlobalValue.h:181
llvm::EVT::getFixedSizeInBits
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition: ValueTypes.h:349
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::HexagonISD::JT
@ JT
Definition: HexagonISelLowering.h:52
T
llvm::SDValue::getNode
SDNode * getNode() const
get the SDNode which holds the desired result
Definition: SelectionDAGNodes.h:151
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
llvm::Function
Definition: Function.h:62
llvm::ISD::ConstantFP
@ ConstantFP
Definition: ISDOpcodes.h:77
llvm::MachineFunction::getContext
MCContext & getContext() const
Definition: MachineFunction.h:586
llvm::ISD::CONCAT_VECTORS
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition: ISDOpcodes.h:519
llvm::ISD::ArgFlagsTy::isInConsecutiveRegsLast
bool isInConsecutiveRegsLast() const
Definition: TargetCallingConv.h:127
llvm::ISD::BSWAP
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:666
llvm::ISD::UDIV
@ UDIV
Definition: ISDOpcodes.h:243
llvm::ISD::DYNAMIC_STACKALLOC
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:931
llvm::AtomicRMWInst::Xor
@ Xor
*p = old ^ v
Definition: Instructions.h:752
llvm::SDNode::isUndef
bool isUndef() const
Return true if the type of the node type undefined.
Definition: SelectionDAGNodes.h:651
llvm::SelectionDAG::getValueType
SDValue getValueType(EVT)
Definition: SelectionDAG.cpp:1747
llvm::MachineInstr::RemoveOperand
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
Definition: MachineInstr.cpp:306
llvm::ISD::ADDC
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:269
llvm::WebAssembly::WASM_ADDRESS_SPACE_FUNCREF
@ WASM_ADDRESS_SPACE_FUNCREF
Definition: WebAssemblyUtilities.h:44
llvm::KnownBits::Zero
APInt Zero
Definition: KnownBits.h:24
llvm::WebAssembly::getOrCreateFunctionTableSymbol
MCSymbolWasm * getOrCreateFunctionTableSymbol(MCContext &Ctx, const WebAssemblySubtarget *Subtarget)
Returns the __indirect_function_table, for use in call_indirect and in function bitcasts.
Definition: WebAssemblyUtilities.cpp:100
llvm::WebAssemblySubtarget::hasMultivalue
bool hasMultivalue() const
Definition: WebAssemblySubtarget.h:99
double
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double
Definition: README-SSE.txt:85
llvm::GlobalValue::NotThreadLocal
@ NotThreadLocal
Definition: GlobalValue.h:179
llvm::AtomicRMWInst::getOperation
BinOp getOperation() const
Definition: Instructions.h:804
llvm::CallingConv::Cold
@ Cold
Definition: CallingConv.h:48
llvm::SelectionDAG::getFrameIndex
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
Definition: SelectionDAG.cpp:1628
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::ISD::FP_TO_UINT_SAT
@ FP_TO_UINT_SAT
Definition: ISDOpcodes.h:801
Wrapper
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
Definition: AMDGPUAliasAnalysis.cpp:31
llvm::MVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: MachineValueType.h:366
llvm::ISD::STACKRESTORE
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1012
llvm::SelectionDAG::getVTList
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
Definition: SelectionDAG.cpp:8519
performVectorTruncZeroCombine
static SDValue performVectorTruncZeroCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2495
llvm::LegacyLegalizeActions::Bitcast
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Definition: LegacyLegalizerInfo.h:54
llvm::WebAssembly::isFuncrefType
bool isFuncrefType(const Type *Ty)
Definition: WebAssemblyUtilities.h:56
ErrorHandling.h
llvm::erase_if
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:1762
llvm::MemSDNode::getMemoryVT
EVT getMemoryVT() const
Return the type of the in-memory value.
Definition: SelectionDAGNodes.h:1335
llvm::MachineFunction::getFunctionNumber
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
Definition: MachineFunction.h:609
llvm::ISD::FLOG2
@ FLOG2
Definition: ISDOpcodes.h:875
llvm::MemSDNode::getChain
const SDValue & getChain() const
Definition: SelectionDAGNodes.h:1358
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:454
llvm::WebAssembly::HeapType::Funcref
@ Funcref
llvm::GlobalAddressSDNode::getTargetFlags
unsigned getTargetFlags() const
Definition: SelectionDAGNodes.h:1731
llvm::ISD::FMA
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition: ISDOpcodes.h:466
llvm::ISD::FP_TO_SINT
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:785
llvm::TargetLowering::DAGCombinerInfo::DAG
SelectionDAG & DAG
Definition: TargetLowering.h:3556
llvm::LoadSDNode
This class is used to represent ISD::LOAD nodes.
Definition: SelectionDAGNodes.h:2297
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:262
llvm::MachineInstr::defs
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
Definition: MachineInstr.h:655
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:233
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::TargetLowering::isPositionIndependent
bool isPositionIndependent() const
Definition: TargetLowering.cpp:46
llvm::ISD::SETULE
@ SETULE
Definition: ISDOpcodes.h:1381
llvm::WebAssemblyISD::NodeType
NodeType
Definition: WebAssemblyISelLowering.h:24
MachineJumpTableInfo.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::NVPTXISD::RETURN
@ RETURN
Definition: NVPTXISelLowering.h:49
llvm::ISD::SHL_PARTS
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:715
llvm::AttributeList
Definition: Attributes.h:398
llvm::WebAssembly::WASM_ADDRESS_SPACE_EXTERNREF
@ WASM_ADDRESS_SPACE_EXTERNREF
Definition: WebAssemblyUtilities.h:42
llvm::SelectionDAG::getStore
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
Definition: SelectionDAG.cpp:7480
llvm::SelectionDAG::ExtractVectorElements
void ExtractVectorElements(SDValue Op, SmallVectorImpl< SDValue > &Args, unsigned Start=0, unsigned Count=0, EVT EltVT=EVT())
Append the extracted elements from Start to Count out of the vector Op in Args.
Definition: SelectionDAG.cpp:10627
llvm::WebAssemblySubtarget::hasAddr64
bool hasAddr64() const
Definition: WebAssemblySubtarget.h:91
llvm::ISD::SETCC
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:702
llvm::AArch64ISD::CALL
@ CALL
Definition: AArch64ISelLowering.h:52
llvm::SelectionDAG::getSplatBuildVector
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
Definition: SelectionDAG.h:807
llvm::Optional< unsigned >
performVECTOR_SHUFFLECombine
static SDValue performVECTOR_SHUFFLECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2423
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
Results
Function Alias Analysis Results
Definition: AliasAnalysis.cpp:847
WebAssemblyTargetMachine.h
llvm::ISD::VAEND
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1041
llvm::ISD::EXTLOAD
@ EXTLOAD
Definition: ISDOpcodes.h:1346
llvm::MVT::v2f64
@ v2f64
Definition: MachineValueType.h:172
llvm::Sched::Fast
@ Fast
Definition: TargetLowering.h:105
llvm::Triple::isOSEmscripten
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition: Triple.h:618
SelectionDAG.h
llvm::BitmaskEnumDetail::Mask
std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1559
LowerCallResults
static MachineBasicBlock * LowerCallResults(MachineInstr &CallResults, DebugLoc DL, MachineBasicBlock *BB, const WebAssemblySubtarget *Subtarget, const TargetInstrInfo &TII)
Definition: WebAssemblyISelLowering.cpp:525
llvm::ISD::SETUEQ
@ SETUEQ
Definition: ISDOpcodes.h:1377
llvm::ISD::SMAX
@ SMAX
Definition: ISDOpcodes.h:627
llvm::SelectionDAG::getContext
LLVMContext * getContext() const
Definition: SelectionDAG.h:447
llvm::NVPTX::PTXLdStInstCode::VecType
VecType
Definition: NVPTX.h:121
IsWebAssemblyTable
static bool IsWebAssemblyTable(SDValue Op)
Definition: WebAssemblyISelLowering.cpp:1438
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::ISD::ArgFlagsTy::isSwiftSelf
bool isSwiftSelf() const
Definition: TargetCallingConv.h:97
MachineRegisterInfo.h
KnownBits.h
Context
ManagedStatic< detail::RecordContext > Context
Definition: Record.cpp:96
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::lltok::equal
@ equal
Definition: LLToken.h:25
IsWebAssemblyTableWithOffset
static bool IsWebAssemblyTableWithOffset(SDValue Op)
Definition: WebAssemblyISelLowering.cpp:1452
llvm::WebAssemblyTargetLowering::WebAssemblyTargetLowering
WebAssemblyTargetLowering(const TargetMachine &TM, const WebAssemblySubtarget &STI)
Definition: WebAssemblyISelLowering.cpp:43
llvm::ISD::BRIND
@ BRIND
BRIND - Indirect branch.
Definition: ISDOpcodes.h:942
llvm::ISD::ROTL
@ ROTL
Definition: ISDOpcodes.h:660
llvm::AArch64CC::LT
@ LT
Definition: AArch64BaseInfo.h:266
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:206
llvm::MVT::integer_valuetypes
static auto integer_valuetypes()
Definition: MachineValueType.h:1412
llvm::MachineBasicBlock::addSuccessor
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Definition: MachineBasicBlock.cpp:750
llvm::ISD::FFLOOR
@ FFLOOR
Definition: ISDOpcodes.h:885
llvm::MVT::funcref
@ funcref
Definition: MachineValueType.h:270
llvm::ISD::BR_CC
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:963
llvm::Type::isArrayTy
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition: Type.h:214
llvm::WebAssemblyII::MO_TLS_BASE_REL
@ MO_TLS_BASE_REL
Definition: WebAssemblyMCTargetDesc.h:109
llvm::MVT::i1
@ i1
Definition: MachineValueType.h:43
llvm::SDNode::getOpcode
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Definition: SelectionDAGNodes.h:628
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:644
llvm::WebAssembly::createFastISel
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
Definition: WebAssemblyFastISel.cpp:1431
llvm::ISD::GlobalAddress
@ GlobalAddress
Definition: ISDOpcodes.h:78
llvm::ISD::SELECT_CC
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:694
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::SelectionDAG::getTargetFrameIndex
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:688
llvm::RecurKind::And
@ And
Bitwise or logical AND of integers.
llvm::SDValue::getValueType
EVT getValueType() const
Return the ValueType of the referenced return value.
Definition: SelectionDAGNodes.h:1120
llvm::ISD::CTLZ
@ CTLZ
Definition: ISDOpcodes.h:668
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
llvm::SelectionDAG
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:216
SelectionDAGNodes.h
llvm::ISD::Constant
@ Constant
Definition: ISDOpcodes.h:76
llvm::ISD::ZERO_EXTEND
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:729
llvm::ISD::ArgFlagsTy::isByVal
bool isByVal() const
Definition: TargetCallingConv.h:85
llvm::ISD::ABS
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition: ISDOpcodes.h:640
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::SmallVectorImpl::append
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:648
llvm::WebAssemblyII::MO_GOT_TLS
@ MO_GOT_TLS
Definition: WebAssemblyMCTargetDesc.h:99
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:732
llvm::MCOI::OperandFlags
OperandFlags
These are flags set on operands, but should be considered private, all access should go through the M...
Definition: MCInstrDesc.h:48
llvm::codeview::ExportFlags::IsConstant
@ IsConstant
llvm::SelectionDAG::getUNDEF
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
Definition: SelectionDAG.h:951
llvm::ISD::CopyToReg
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition: ISDOpcodes.h:203
llvm::ISD::SIGN_EXTEND_INREG
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:747
LowerConvertLow
static SDValue LowerConvertLow(SDValue Op, SelectionDAG &DAG)
Definition: WebAssemblyISelLowering.cpp:1962
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:35
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::Type::getDoubleTy
static Type * getDoubleTy(LLVMContext &C)
Definition: Type.cpp:229
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:499
llvm::MVT::f64
@ f64
Definition: MachineValueType.h:56
llvm::SelectionDAG::getConstant
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
Definition: SelectionDAG.cpp:1398
llvm::GlobalValue::getThreadLocalMode
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:252
llvm::JumpTableSDNode
Definition: SelectionDAGNodes.h:1820
llvm::EVT::getVectorNumElements
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:309
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition: TargetLowering.h:3195
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::TargetLowering::DAGCombinerInfo
Definition: TargetLowering.h:3550
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::ISD::SRA
@ SRA
Definition: ISDOpcodes.h:658
llvm::TargetLoweringBase::ZeroOrNegativeOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
Definition: TargetLowering.h:234
unrollVectorShift
static SDValue unrollVectorShift(SDValue Op, SelectionDAG &DAG)
Definition: WebAssemblyISelLowering.cpp:2343
llvm::ISD::UDIVREM
@ UDIVREM
Definition: ISDOpcodes.h:256
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::TargetLoweringBase::addRegisterClass
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
Definition: TargetLowering.h:2189
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:195
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MVT::v4f64
@ v4f64
Definition: MachineValueType.h:174
llvm::StoreSDNode::getOffset
const SDValue & getOffset() const
Definition: SelectionDAGNodes.h:2348
ll
Analysis the ScalarEvolution expression for r is< loop > Outside the this could be evaluated simply however ScalarEvolution currently evaluates it it involves i65 which is very inefficient when expanded into code In formatValue in test CodeGen X86 lsr delayed fold ll
Definition: README.txt:20
llvm::Instruction
Definition: Instruction.h:45
Concat
static constexpr int Concat[]
Definition: X86InterleavedAccess.cpp:239
WebAssemblyTypeUtilities.h
llvm::ISD::SINT_TO_FP
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:739
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::APInt::getHighBitsSet
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition: APInt.h:279
llvm::ISD::FNEARBYINT
@ FNEARBYINT
Definition: ISDOpcodes.h:882
llvm::ISD::FP16_TO_FP
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition: ISDOpcodes.h:858
llvm::ISD::FRINT
@ FRINT
Definition: ISDOpcodes.h:881
llvm::FrameIndexSDNode
Definition: SelectionDAGNodes.h:1743
llvm::SelectionDAG::getMemIntrinsicNode
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, uint64_t Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
Definition: SelectionDAG.cpp:7207
llvm::MVT::INVALID_SIMPLE_VALUE_TYPE
@ INVALID_SIMPLE_VALUE_TYPE
Definition: MachineValueType.h:38
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::ISD::AND
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:632
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
llvm::GlobalAddressSDNode::getGlobal
const GlobalValue * getGlobal() const
Definition: SelectionDAGNodes.h:1729
llvm::ISD::FSINCOS
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:915
llvm::TargetLoweringBase::TypeWidenVector
@ TypeWidenVector
Definition: TargetLowering.h:214
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::TargetLoweringBase::setBooleanVectorContents
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
Definition: TargetLowering.h:2137
llvm::Type::isFunctionTy
bool isFunctionTy() const
True if this is an instance of FunctionType.
Definition: Type.h:208
llvm::AtomicRMWInst::Xchg
@ Xchg
*p = v
Definition: Instructions.h:740
llvm::EVT::changeVectorElementTypeToInteger
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition: ValueTypes.h:94
llvm::WebAssemblyRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: WebAssemblyRegisterInfo.cpp:139
llvm::None
const NoneType None
Definition: None.h:23
llvm::AtomicRMWInst::Add
@ Add
*p = old + v
Definition: Instructions.h:742
llvm::MVT::v4i16
@ v4i16
Definition: MachineValueType.h:91
llvm::EVT::getTypeForEVT
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:181
llvm::TargetLowering::makeLibCall
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Definition: TargetLowering.cpp:140
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::ISD::SETUGT
@ SETUGT
Definition: ISDOpcodes.h:1378
llvm::ISD::ArgFlagsTy::getNonZeroOrigAlign
Align getNonZeroOrigAlign() const
Definition: TargetCallingConv.h:160
WebAssemblyUtilities.h
llvm::Log2_32_Ceil
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition: MathExtras.h:609
llvm::Sched::RegPressure
@ RegPressure
Definition: TargetLowering.h:101
llvm::SelectionDAG::getTargetGlobalAddress
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:683
WebAssemblyMCTargetDesc.h
llvm::TargetLowering::isOffsetFoldingLegal
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const
Return true if folding a constant offset with the given GlobalAddress is legal.
Definition: TargetLowering.cpp:471
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:634
llvm::MVT::isFloatingPoint
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: MachineValueType.h:340
llvm::ISD::FPOW
@ FPOW
Definition: ISDOpcodes.h:873
llvm::ISD::BlockAddress
@ BlockAddress
Definition: ISDOpcodes.h:84
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:634
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::TargetLoweringBase::setOperationAction
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
Definition: TargetLowering.h:2206
llvm::Type::getArrayElementType
Type * getArrayElementType() const
Definition: Type.h:364
llvm::ISD::SMIN
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition: ISDOpcodes.h:626
llvm::ISD::FMINIMUM
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
Definition: ISDOpcodes.h:911
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::MachineJumpTableInfo::getJumpTables
const std::vector< MachineJumpTableEntry > & getJumpTables() const
Definition: MachineJumpTableInfo.h:99
llvm::MipsISD::Ext
@ Ext
Definition: MipsISelLowering.h:156
llvm::MVT::v16i8
@ v16i8
Definition: MachineValueType.h:80
llvm::ISD::FLOG10
@ FLOG10
Definition: ISDOpcodes.h:876
llvm::WebAssemblySubtarget::hasReferenceTypes
bool hasReferenceTypes() const
Definition: WebAssemblySubtarget.h:102
llvm::EVT::getSizeInBits
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:341
llvm::AtomicRMWInst::Sub
@ Sub
*p = old - v
Definition: Instructions.h:744
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
llvm::MVT::v2i64
@ v2i64
Definition: MachineValueType.h:118
uint64_t
llvm::ISD::FP_TO_UINT
@ FP_TO_UINT
Definition: ISDOpcodes.h:786
llvm::MemSDNode::getMemOperand
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
Definition: SelectionDAGNodes.h:1339
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:578
llvm::GlobalValue::GeneralDynamicTLSModel
@ GeneralDynamicTLSModel
Definition: GlobalValue.h:180
llvm::TargetLowering::verifyReturnAddressArgumentIsConstant
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
Definition: TargetLowering.cpp:6041
llvm::ISD::LOAD
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:921
llvm::MVT::externref
@ externref
Definition: MachineValueType.h:271
llvm::SelectionDAG::getIntPtrConstant
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Definition: SelectionDAG.cpp:1521
llvm::CallingConv::Fast
@ Fast
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:42
llvm::TargetLoweringBase::Promote
@ Promote
Definition: TargetLowering.h:198
llvm::MCSymbolWasm
Definition: MCSymbolWasm.h:16
llvm::WebAssemblySubtarget::hasNontrappingFPToInt
bool hasNontrappingFPToInt() const
Definition: WebAssemblySubtarget.h:95
llvm::ISD::TRAP
@ TRAP
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:1088
llvm::MachinePointerInfo
This class contains a discriminated union of information about pointers in memory operands,...
Definition: MachineMemOperand.h:38
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::WebAssemblyISD::FIRST_NUMBER
@ FIRST_NUMBER
Definition: WebAssemblyISelLowering.h:25
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:761
llvm::codeview::FrameCookieKind::Copy
@ Copy
llvm::ISD::OutputArg
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
Definition: TargetCallingConv.h:233
llvm::ISD::EXTRACT_VECTOR_ELT
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition: ISDOpcodes.h:511
llvm::TargetLoweringBase::setStackPointerRegisterToSaveRestore
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
Definition: TargetLowering.h:2155
llvm::CallingConv::PreserveMost
@ PreserveMost
Definition: CallingConv.h:66
llvm::SDNode::getOperand
const SDValue & getOperand(unsigned Num) const
Definition: SelectionDAGNodes.h:903
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::FrameIndexSDNode::getIndex
int getIndex() const
Definition: SelectionDAGNodes.h:1754
llvm::SelectionDAG::getNode
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
Definition: SelectionDAG.cpp:8284
llvm::ISD::FP_TO_FP16
@ FP_TO_FP16
Definition: ISDOpcodes.h:859
llvm::ISD::UADDSAT
@ UADDSAT
Definition: ISDOpcodes.h:328
llvm::ISD::FCOPYSIGN
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition: ISDOpcodes.h:476
llvm::AtomicRMWInst::Or
@ Or
*p = old | v
Definition: Instructions.h:750
llvm::SelectionDAG::getAnyExtOrTrunc
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
Definition: SelectionDAG.cpp:1316
llvm::CCValAssign::getMem
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
Definition: CallingConvLower.h:102
llvm::WebAssemblySubtarget::getInstrInfo
const WebAssemblyInstrInfo * getInstrInfo() const override
Definition: WebAssemblySubtarget.h:78
llvm::GlobalAddressSDNode::getOffset
int64_t getOffset() const
Definition: SelectionDAGNodes.h:1730
llvm::MVT::v4f32
@ v4f32
Definition: MachineValueType.h:157
llvm::MachineMemOperand::Flags
Flags
Flags values. These may be or'd together.
Definition: MachineMemOperand.h:131
llvm::MVT::getVectorNumElements
unsigned getVectorNumElements() const
Definition: MachineValueType.h:850
llvm::ISD::InputArg
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
Definition: TargetCallingConv.h:195
llvm::StoreSDNode
This class is used to represent ISD::STORE nodes.
Definition: SelectionDAGNodes.h:2325
llvm::ISD::ZEXTLOAD
@ ZEXTLOAD
Definition: ISDOpcodes.h:1346
llvm::SDValue::getValue
SDValue getValue(unsigned R) const
Definition: SelectionDAGNodes.h:171
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:44
llvm::ilist_node_with_parent::getPrevNode
NodeTy * getPrevNode()
Definition: ilist_node.h:274
llvm::ISD::ArgFlagsTy::isNest
bool isNest() const
Definition: TargetCallingConv.h:118
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::SelectionDAG::getVectorShuffle
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
Definition: SelectionDAG.cpp:1827
llvm::EVT::getIntegerVT
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition: ValueTypes.h:65
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:80
llvm::ISD::MULHS
@ MULHS
Definition: ISDOpcodes.h:615
llvm::FunctionLoweringInfo
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Definition: FunctionLoweringInfo.h:52
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:42
llvm::MVT::getSizeInBits
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
Definition: MachineValueType.h:860
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:650
llvm::ISD::SETULT
@ SETULT
Definition: ISDOpcodes.h:1380
llvm::ISD::DEBUGTRAP
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
Definition: ISDOpcodes.h:1091
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::SelectionDAG::getMachineNode
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
Definition: SelectionDAG.cpp:8957
MachineModuleInfo.h
llvm::SelectionDAG::getBitcast
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
Definition: SelectionDAG.cpp:2113
llvm::WebAssemblyFunctionInfo
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
Definition: WebAssemblyMachineFunctionInfo.h:33
llvm::ISD::RETURNADDR
@ RETURNADDR
Definition: ISDOpcodes.h:95
llvm::MVT
Machine Value Type.
Definition: MachineValueType.h:31
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::FastISel
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Definition: FastISel.h:65
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::StoreSDNode::getValue
const SDValue & getValue() const
Definition: SelectionDAGNodes.h:2346
llvm::ISD::SRA_PARTS
@ SRA_PARTS
Definition: ISDOpcodes.h:716
llvm::ISD::VASTART
@ VASTART
Definition: ISDOpcodes.h:1042
WebAssemblyMachineFunctionInfo.h
llvm::WebAssembly::isRefType
bool isRefType(const Type *Ty)
Definition: WebAssemblyUtilities.h:66
llvm::CallingConv::C
@ C
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
_
#define _
Definition: HexagonMCCodeEmitter.cpp:47
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm::MachineFunction
Definition: MachineFunction.h:234
llvm::WebAssemblyII::MO_MEMORY_BASE_REL
@ MO_MEMORY_BASE_REL
Definition: WebAssemblyMCTargetDesc.h:104
llvm::MVT::getVectorVT
static MVT getVectorVT(MVT VT, unsigned NumElements)
Definition: MachineValueType.h:1177
TargetOptions.h
llvm::ISD::FMAXIMUM
@ FMAXIMUM
Definition: ISDOpcodes.h:912
llvm::ISD::GlobalTLSAddress
@ GlobalTLSAddress
Definition: ISDOpcodes.h:79
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:100
llvm::AArch64CC::GE
@ GE
Definition: AArch64BaseInfo.h:265
llvm::MVT::fixedlen_vector_valuetypes
static auto fixedlen_vector_valuetypes()
Definition: MachineValueType.h:1429
llvm::ArrayRef< int >
llvm::computeLegalValueVTs
void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, SmallVectorImpl< MVT > &ValueVTs)
Definition: WebAssemblyMachineFunctionInfo.cpp:33
llvm::EVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:155
llvm::ISD::UMAX
@ UMAX
Definition: ISDOpcodes.h:629
llvm::MCSymbolWasm::setNoStrip
void setNoStrip() const
Definition: MCSymbolWasm.h:65
llvm::MVT::i64
@ i64
Definition: MachineValueType.h:47
llvm::MachineFrameInfo::CreateStackObject
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
Definition: MachineFrameInfo.cpp:51
llvm::MVT::v2i32
@ v2i32
Definition: MachineValueType.h:101
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::MachineBasicBlock::splice
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
Definition: MachineBasicBlock.h:950
llvm::WebAssemblyII::MO_GOT
@ MO_GOT
Definition: WebAssemblyMCTargetDesc.h:96
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:489
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::ISD::SREM
@ SREM
Definition: ISDOpcodes.h:244
LowerFPToInt
static MachineBasicBlock * LowerFPToInt(MachineInstr &MI, DebugLoc DL, MachineBasicBlock *BB, const TargetInstrInfo &TII, bool IsUnsigned, bool Int64, bool Float64, unsigned LoweredOpcode)
Definition: WebAssemblyISelLowering.cpp:431
llvm::ISD::UMUL_LOHI
@ UMUL_LOHI
Definition: ISDOpcodes.h:251
llvm::ISD::OutputArg::Flags
ArgFlagsTy Flags
Definition: TargetCallingConv.h:234
llvm::MVT::v2f32
@ v2f32
Definition: MachineValueType.h:155
llvm::WebAssemblyTargetLowering::getPointerTy
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const override
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Definition: WebAssemblyISelLowering.cpp:348
uint32_t
llvm::WebAssemblySubtarget::hasBulkMemory
bool hasBulkMemory() const
Definition: WebAssemblySubtarget.h:98
llvm::MVT::is128BitVector
bool is128BitVector() const
Return true if this is a 128-bit vector type.
Definition: MachineValueType.h:407
llvm::SDValue::getOperand
const SDValue & getOperand(unsigned i) const
Definition: SelectionDAGNodes.h:1128
llvm::ilist_node_impl::getIterator
self_iterator getIterator()
Definition: ilist_node.h:81
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
AddrMode
AddrMode
Definition: MSP430Disassembler.cpp:142
llvm::CallingConv::Swift
@ Swift
Definition: CallingConv.h:73
llvm::WebAssemblySubtarget
Definition: WebAssemblySubtarget.h:35
llvm::ISD::FEXP
@ FEXP
Definition: ISDOpcodes.h:877
llvm::ISD::SMUL_LOHI
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
llvm::ISD::BUILTIN_OP_END
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
Definition: ISDOpcodes.h:1249
llvm::TargetLowering::getRegForInlineAsmConstraint
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
Definition: TargetLowering.cpp:4652
llvm::TargetLoweringBase::setCondCodeAction
void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
Definition: TargetLowering.h:2270
llvm::TargetLoweringBase::setTruncStoreAction
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
Definition: TargetLowering.h:2225
llvm::SDValue::getSimpleValueType
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
Definition: SelectionDAGNodes.h:182
llvm::MVT::v4i32
@ v4i32
Definition: MachineValueType.h:103
llvm::ISD::FEXP2
@ FEXP2
Definition: ISDOpcodes.h:878
llvm::SelectionDAG::getBasicBlock
SDValue getBasicBlock(MachineBasicBlock *MBB)
Definition: SelectionDAG.cpp:1733
llvm::MVT::iPTR
@ iPTR
Definition: MachineValueType.h:312
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
llvm::SDVTList
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
Definition: SelectionDAGNodes.h:78
llvm::MachineMemOperand::MOVolatile
@ MOVolatile
The memory access is volatile.
Definition: MachineMemOperand.h:139
llvm::MachineInstrBuilder::getInstr
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Definition: MachineInstrBuilder.h:89
llvm::ISD::SEXTLOAD
@ SEXTLOAD
Definition: ISDOpcodes.h:1346
llvm::SelectionDAG::getBuildVector
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
Definition: SelectionDAG.h:790
llvm::SelectionDAG::getConstantFP
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
Definition: SelectionDAG.cpp:1577
llvm::GlobalValue::LocalExecTLSModel
@ LocalExecTLSModel
Definition: GlobalValue.h:183
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:726
llvm::MachineMemOperand::MOLoad
@ MOLoad
The memory access reads data.
Definition: MachineMemOperand.h:135
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ISD::INTRINSIC_WO_CHAIN
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition: ISDOpcodes.h:184
llvm::LoadSDNode::getBasePtr
const SDValue & getBasePtr() const
Definition: SelectionDAGNodes.h:2316
llvm::SelectionDAG::getTargetJumpTable
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:693
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1608
NumFixedArgs
static unsigned NumFixedArgs
Definition: LanaiISelLowering.cpp:368
llvm::ISD::FRAMEADDR
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:94
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:206
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::TargetLoweringBase::getTargetMachine
const TargetMachine & getTargetMachine() const
Definition: TargetLowering.h:339
callingConvSupported
static bool callingConvSupported(CallingConv::ID CallConv)
Definition: WebAssemblyISelLowering.cpp:926
llvm::CallingConv::WASM_EmscriptenInvoke
@ WASM_EmscriptenInvoke
Calling convention for emscripten __invoke_* functions.
Definition: CallingConv.h:247
llvm::LLVMContext::diagnose
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Definition: LLVMContext.cpp:228
llvm::computeSignatureVTs
void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, const Function &ContextFunc, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
Definition: WebAssemblyMachineFunctionInfo.cpp:49
llvm::ISD::ArgFlagsTy::getByValSize
unsigned getByValSize() const
Definition: TargetCallingConv.h:169
llvm::CallingConv::PreserveAll
@ PreserveAll
Definition: CallingConv.h:70
llvm::CallingConv::CXX_FAST_TLS
@ CXX_FAST_TLS
Definition: CallingConv.h:76
llvm::TargetLoweringBase::setLoadExtAction
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
Definition: TargetLowering.h:2213
llvm::GlobalAddressSDNode
Definition: SelectionDAGNodes.h:1717
llvm::KnownBits
Definition: KnownBits.h:23
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:600
llvm::ISD::EXTRACT_SUBVECTOR
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition: ISDOpcodes.h:549
llvm::ISD::FP_TO_SINT_SAT
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
Definition: ISDOpcodes.h:800
llvm::SDNode::getNumOperands
unsigned getNumOperands() const
Return the number of values used by this operation.
Definition: SelectionDAGNodes.h:890
llvm::SelectionDAG::UnrollVectorOp
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
Definition: SelectionDAG.cpp:10370
llvm::TargetLoweringBase::AtomicExpansionKind
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
Definition: TargetLowering.h:250
CallingConvLower.h
llvm::EVT::getScalarType
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition: ValueTypes.h:296
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:324
llvm::ISD::BR
@ BR
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:937
llvm::WebAssembly::getOrCreateFuncrefCallTableSymbol
MCSymbolWasm * getOrCreateFuncrefCallTableSymbol(MCContext &Ctx, const WebAssemblySubtarget *Subtarget)
Returns the __funcref_call_table, for use in funcref calls when lowered to table.set + call_indirect.
Definition: WebAssemblyUtilities.cpp:119
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
llvm::ISD::FCOS
@ FCOS
Definition: ISDOpcodes.h:871
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:516
llvm::ISD::FCEIL
@ FCEIL
Definition: ISDOpcodes.h:879
IsWebAssemblyGlobal
static bool IsWebAssemblyGlobal(SDValue Op)
Definition: WebAssemblyISelLowering.cpp:1422
llvm::ISD::FSIN
@ FSIN
Definition: ISDOpcodes.h:870
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:440
llvm::MVT::v8i16
@ v8i16
Definition: MachineValueType.h:92
llvm::AtomicRMWInst::And
@ And
*p = old & v
Definition: Instructions.h:746
llvm::ConstantFP::get
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
Definition: Constants.cpp:972
llvm::ISD::BUILD_VECTOR
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:491
DiagnosticInfo.h
Function.h
llvm::TargetLoweringBase::Custom
@ Custom
Definition: TargetLowering.h:201
WebAssemblySubtarget.h
llvm::ISD::SUBC
@ SUBC
Definition: ISDOpcodes.h:270
llvm::BitWidth
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:147
llvm::SelectionDAG::getTargetExternalSymbol
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.cpp:1778
llvm::SelectionDAG::getMCSymbol
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
Definition: SelectionDAG.cpp:1769
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:46
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::TargetLoweringBase::LegalizeTypeAction
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
Definition: TargetLowering.h:206
llvm::ISD::SETUO
@ SETUO
Definition: ISDOpcodes.h:1376
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:221
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:137
llvm::ISD::SDIV
@ SDIV
Definition: ISDOpcodes.h:242
llvm::SDNode::getNumValues
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
Definition: SelectionDAGNodes.h:962
llvm::Function::getFunctionType
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:177
Conversion
X86 cmov Conversion
Definition: X86CmovConversion.cpp:861
llvm::TargetLoweringBase::ZeroOrOneBooleanContent
@ ZeroOrOneBooleanContent
Definition: TargetLowering.h:233
llvm::WebAssemblyTargetLowering::getPointerMemTy
MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const override
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
Definition: WebAssemblyISelLowering.cpp:357
llvm::WebAssemblySubtarget::hasSIMD128
bool hasSIMD128() const
Definition: WebAssemblySubtarget.h:92
llvm::MCID::Add
@ Add
Definition: MCInstrDesc.h:183
llvm::TargetLoweringBase::setLibcallName
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
Definition: TargetLowering.h:2860
llvm::ISD::STORE
@ STORE
Definition: ISDOpcodes.h:922
llvm::ISD::VACOPY
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1037
llvm::MachineMemOperand::MOStore
@ MOStore
The memory access writes data.
Definition: MachineMemOperand.h:137
llvm::ISD::SRL_PARTS
@ SRL_PARTS
Definition: ISDOpcodes.h:717
llvm::ISD::UINT_TO_FP
@ UINT_TO_FP
Definition: ISDOpcodes.h:740
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
llvm::TargetLoweringBase::isOperationLegalOrCustomOrPromote
bool isOperationLegalOrCustomOrPromote(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
Definition: TargetLowering.h:1150
llvm::SDValue::isUndef
bool isUndef() const
Definition: SelectionDAGNodes.h:1156
llvm::codeview::ModifierOptions::Const
@ Const
llvm::EVT::getVectorElementType
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:301
llvm::TargetLoweringBase::setBooleanContents
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
Definition: TargetLowering.h:2123
false
Function Alias Analysis false
Definition: AliasAnalysis.cpp:847
llvm::ISD::FP_EXTEND
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition: ISDOpcodes.h:833
llvm::MachineInstrBuilder::addSym
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
Definition: MachineInstrBuilder.h:267
llvm::ISD::SHL
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:657
llvm::ISD::FREM
@ FREM
Definition: ISDOpcodes.h:381
llvm::MachinePointerInfo::getFixedStack
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Definition: MachineOperand.cpp:1008
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
llvm::ISD::ArgFlagsTy::getNonZeroByValAlign
Align getNonZeroByValAlign() const
Definition: TargetCallingConv.h:153
llvm::ISD::MUL
@ MUL
Definition: ISDOpcodes.h:241
llvm::ISD::UREM
@ UREM
Definition: ISDOpcodes.h:245
llvm::TargetLoweringBase::Expand
@ Expand
Definition: TargetLowering.h:199
llvm::TargetLoweringBase::setTargetDAGCombine
void setTargetDAGCombine(ISD::NodeType NT)
Targets should invoke this method for each target independent node that they want to provide a custom...
Definition: TargetLowering.h:2301
llvm::MVT::f16
@ f16
Definition: MachineValueType.h:54
llvm::WebAssembly::isWasmVarAddressSpace
bool isWasmVarAddressSpace(unsigned AS)
Definition: WebAssemblyUtilities.h:50
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
N
#define N
llvm::TargetLoweringBase::computeRegisterProperties
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
Definition: TargetLoweringBase.cpp:1292
llvm::TargetLoweringBase::setMaxAtomicSizeInBitsSupported
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Definition: TargetLowering.h:2331
llvm::ISD::SUBE
@ SUBE
Definition: ISDOpcodes.h:280
llvm::TargetLoweringBase::setMinimumJumpTableEntries
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
Definition: TargetLoweringBase.cpp:2017
llvm::ISD::SRL
@ SRL
Definition: ISDOpcodes.h:659
llvm::MachineInstr::addOperand
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
Definition: MachineInstr.cpp:207
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:63
llvm::ISD::ArgFlagsTy::isInConsecutiveRegs
bool isInConsecutiveRegs() const
Definition: TargetCallingConv.h:124
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::MVT::getVT
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:526
llvm::GlobalAddressSDNode::getAddressSpace
unsigned getAddressSpace() const
Definition: SelectionDAG.cpp:10644
llvm::ISD::CTTZ
@ CTTZ
Definition: ISDOpcodes.h:667
llvm::TargetLoweringBase::getRegClassFor
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
Definition: TargetLowering.h:860
llvm::MachineFunction::getDataLayout
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Definition: MachineFunction.cpp:261
llvm::WebAssemblyII::MO_TABLE_BASE_REL
@ MO_TABLE_BASE_REL
Definition: WebAssemblyMCTargetDesc.h:114
llvm::TargetLoweringBase::AtomicExpansionKind::None
@ None
llvm::ISD::UMIN
@ UMIN
Definition: ISDOpcodes.h:628
llvm::MipsISD::Ins
@ Ins
Definition: MipsISelLowering.h:157
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::ISD::MULHU
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:614
llvm::MachineBasicBlock::transferSuccessorsAndUpdatePHIs
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
Definition: MachineBasicBlock.cpp:889
llvm::SDValue::getOpcode
unsigned getOpcode() const
Definition: SelectionDAGNodes.h:1116
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:637
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition: GlobalValue.h:273
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::ISD::SETONE
@ SETONE
Definition: ISDOpcodes.h:1374
llvm::MVT::i16
@ i16
Definition: MachineValueType.h:45
llvm::ISD::INTRINSIC_W_CHAIN
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition: ISDOpcodes.h:192
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1487
llvm::SelectionDAG::getMachineFunction
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:437
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::ISD::ArgFlagsTy::isSwiftError
bool isSwiftError() const
Definition: TargetCallingConv.h:103
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:172
llvm::MachineFunction::createExternalSymbolName
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
Definition: MachineFunction.cpp:515
llvm::ISD::BUILD_PAIR
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition: ISDOpcodes.h:229
llvm::ISD::VAARG
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1032
llvm::WebAssemblyISD::FIRST_MEM_OPCODE
@ FIRST_MEM_OPCODE
Definition: WebAssemblyISelLowering.h:29
llvm::KnownBits::getBitWidth
unsigned getBitWidth() const
Get the bit width of this value.
Definition: KnownBits.h:40
llvm::ISD::SDIVREM
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:255
llvm::MachineFunction::getJumpTableInfo
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
Definition: MachineFunction.h:657
llvm::MachineFunction::CreateMachineInstr
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, const DebugLoc &DL, bool NoImplicit=false)
CreateMachineInstr - Allocate a new MachineInstr.
Definition: MachineFunction.cpp:349
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineFrameInfo::setFrameAddressIsTaken
void setFrameAddressIsTaken(bool T)
Definition: MachineFrameInfo.h:369
llvm::EVT::bitsGE
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
Definition: ValueTypes.h:265
llvm::MachineJumpTableInfo
Definition: MachineJumpTableInfo.h:42
llvm::ISD::SIGN_EXTEND
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:726
raw_ostream.h
llvm::SelectionDAG::getMemcpy
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes())
Definition: SelectionDAG.cpp:6805
llvm::MVT::v8i8
@ v8i8
Definition: MachineValueType.h:79
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:156
llvm::GlobalValue::InitialExecTLSModel
@ InitialExecTLSModel
Definition: GlobalValue.h:182
llvm::ISD::FTRUNC
@ FTRUNC
Definition: ISDOpcodes.h:880
model
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from where P can be anything The alignment inference code cannot handle loads from globals in static non mode because it doesn t look through the extra dyld stub load If you try vec_align ll without relocation model
Definition: README-SSE.txt:414
llvm::WebAssemblyFrameLowering::getLocalForStackObject
static Optional< unsigned > getLocalForStackObject(MachineFunction &MF, int FrameIndex)
Definition: WebAssemblyFrameLowering.cpp:54
llvm::TargetLoweringBase::AtomicExpansionKind::CmpXChg
@ CmpXChg
DiagnosticPrinter.h
llvm::MachineInstr::eraseFromParent
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Definition: MachineInstr.cpp:680
llvm::SelectionDAG::getSplatValue
SDValue getSplatValue(SDValue V, bool LegalTypes=false)
If V is a splat vector, return its scalar source operand by extracting that element from the source v...
Definition: SelectionDAG.cpp:2676
llvm::ISD::INSERT_VECTOR_ELT
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition: ISDOpcodes.h:500
llvm::ISD::STACKSAVE
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1008
llvm::ISD::FLOG
@ FLOG
Definition: ISDOpcodes.h:874
llvm::ISD::ADDE
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:279
llvm::ISD::FP_ROUND
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition: ISDOpcodes.h:814
llvm::MVT::f32
@ f32
Definition: MachineValueType.h:55
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::ISD::ROTR
@ ROTR
Definition: ISDOpcodes.h:661
llvm::SelectionDAG::getTarget
const TargetMachine & getTarget() const
Definition: SelectionDAG.h:441
Debug.h
llvm::EVT::isFloatingPoint
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: ValueTypes.h:140
llvm::WebAssembly::isValidAddressSpace
bool isValidAddressSpace(unsigned AS)
Definition: WebAssemblyUtilities.h:53
llvm::Type::getFloatTy
static Type * getFloatTy(LLVMContext &C)
Definition: Type.cpp:228
llvm::WebAssemblySubtarget::hasSignExt
bool hasSignExt() const
Definition: WebAssemblySubtarget.h:96
llvm::TargetLoweringBase::getPointerTy
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Definition: TargetLowering.h:346
llvm::ISD::CTPOP
@ CTPOP
Definition: ISDOpcodes.h:669
llvm::ISD::SADDSAT
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition: ISDOpcodes.h:327
llvm::ISD::TokenFactor
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
llvm::SelectionDAG::getMergeValues
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
Definition: SelectionDAG.cpp:7196
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
fail
static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *Msg)
Definition: WebAssemblyISelLowering.cpp:919
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:289
llvm::MVT::getIntegerVT
static MVT getIntegerVT(unsigned BitWidth)
Definition: MachineValueType.h:1158
llvm::MVT::integer_fixedlen_vector_valuetypes
static auto integer_fixedlen_vector_valuetypes()
Definition: MachineValueType.h:1441
llvm::ISD::OutputArg::IsFixed
bool IsFixed
IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
Definition: TargetCallingConv.h:239
INT64_MIN
#define INT64_MIN
Definition: DataTypes.h:74