LLVM  13.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 
17 #include "WebAssemblySubtarget.h"
19 #include "WebAssemblyUtilities.h"
20 #include "llvm/CodeGen/Analysis.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"
38 using namespace llvm;
39 
40 #define DEBUG_TYPE "wasm-lower"
41 
43  const TargetMachine &TM, const WebAssemblySubtarget &STI)
44  : TargetLowering(TM), Subtarget(&STI) {
45  auto MVTPtr = Subtarget->hasAddr64() ? MVT::i64 : MVT::i32;
46 
47  // Booleans always contain 0 or 1.
49  // Except in SIMD vectors
51  // We don't know the microarchitecture here, so just reduce register pressure.
53  // Tell ISel that we have a stack pointer.
55  Subtarget->hasAddr64() ? WebAssembly::SP64 : WebAssembly::SP32);
56  // Set up the register classes.
57  addRegisterClass(MVT::i32, &WebAssembly::I32RegClass);
58  addRegisterClass(MVT::i64, &WebAssembly::I64RegClass);
59  addRegisterClass(MVT::f32, &WebAssembly::F32RegClass);
60  addRegisterClass(MVT::f64, &WebAssembly::F64RegClass);
61  if (Subtarget->hasSIMD128()) {
62  addRegisterClass(MVT::v16i8, &WebAssembly::V128RegClass);
63  addRegisterClass(MVT::v8i16, &WebAssembly::V128RegClass);
64  addRegisterClass(MVT::v4i32, &WebAssembly::V128RegClass);
65  addRegisterClass(MVT::v4f32, &WebAssembly::V128RegClass);
66  addRegisterClass(MVT::v2i64, &WebAssembly::V128RegClass);
67  addRegisterClass(MVT::v2f64, &WebAssembly::V128RegClass);
68  }
69  // Compute derived properties from the register classes.
71 
78 
79  // Take the default expansion for va_arg, va_copy, and va_end. There is no
80  // default action for va_start, so we do that custom.
85 
86  for (auto T : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) {
87  // Don't expand the floating-point types to constant pools.
89  // Expand floating-point comparisons.
90  for (auto CC : {ISD::SETO, ISD::SETUO, ISD::SETUEQ, ISD::SETONE,
93  // Expand floating-point library function operators.
94  for (auto Op :
97  // Note supported floating-point library function operators that otherwise
98  // default to expand.
99  for (auto Op :
102  // Support minimum and maximum, which otherwise default to expand.
105  // WebAssembly currently has no builtin f16 support.
110  }
111 
112  // Expand unavailable integer operations.
113  for (auto Op :
117  for (auto T : {MVT::i32, MVT::i64})
119  if (Subtarget->hasSIMD128())
120  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64})
122  }
123 
124  if (Subtarget->hasNontrappingFPToInt())
126  for (auto T : {MVT::i32, MVT::i64})
128 
129  // SIMD-specific configuration
130  if (Subtarget->hasSIMD128()) {
131  // Hoist bitcasts out of shuffles
133 
134  // Combine extends of extract_subvectors into widening ops
137 
138  // Combine {s,u}int_to_fp of extract_vectors into conversion ops
141 
142  // Combine concat of {s,u}int_to_fp_sat to i32x4.trunc_sat_f64x2_zero_{s,u}
144 
145  // Support saturating add for i8x16 and i16x8
146  for (auto Op : {ISD::SADDSAT, ISD::UADDSAT})
147  for (auto T : {MVT::v16i8, MVT::v8i16})
149 
150  // Support integer abs
151  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
153 
154  // Custom lower BUILD_VECTORs to minimize number of replace_lanes
156  MVT::v2f64})
158 
159  // We have custom shuffle lowering to expose the shuffle mask
161  MVT::v2f64})
163 
164  // Custom lowering since wasm shifts must have a scalar shift amount
165  for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL})
166  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64})
168 
169  // Custom lower lane accesses to expand out variable indices
172  MVT::v2f64})
174 
175  // There is no i8x16.mul instruction
177 
178  // There is no vector conditional select instruction
180  MVT::v2f64})
182 
183  // Expand integer operations supported for scalars but not SIMD
186  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64})
188 
189  // But we do have integer min and max operations
190  for (auto Op : {ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX})
191  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
193 
194  // Expand float operations supported for scalars but not SIMD
197  for (auto T : {MVT::v4f32, MVT::v2f64})
199 
200  // Unsigned comparison operations are unavailable for i64x2 vectors.
201  for (auto CC : {ISD::SETUGT, ISD::SETUGE, ISD::SETULT, ISD::SETULE})
203 
204  // 64x2 conversions are not in the spec
205  for (auto Op :
207  for (auto T : {MVT::v2i64, MVT::v2f64})
209 
210  // But saturating fp_to_int converstions are
213  }
214 
215  // As a special case, these operators use the type to mean the type to
216  // sign-extend from.
218  if (!Subtarget->hasSignExt()) {
219  // Sign extends are legal only when extending a vector extract
220  auto Action = Subtarget->hasSIMD128() ? Custom : Expand;
221  for (auto T : {MVT::i8, MVT::i16, MVT::i32})
223  }
226 
227  // Dynamic stack allocation: use the default expansion.
231 
235 
236  // Expand these forms; we pattern-match the forms that we can handle in isel.
237  for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64})
238  for (auto Op : {ISD::BR_CC, ISD::SELECT_CC})
240 
241  // We have custom switch handling.
243 
244  // WebAssembly doesn't have:
245  // - Floating-point extending loads.
246  // - Floating-point truncating stores.
247  // - i1 extending loads.
248  // - truncating SIMD stores and most extending loads
251  for (auto T : MVT::integer_valuetypes())
254  if (Subtarget->hasSIMD128()) {
256  MVT::v2f64}) {
257  for (auto MemT : MVT::fixedlen_vector_valuetypes()) {
258  if (MVT(T) != MemT) {
259  setTruncStoreAction(T, MemT, Expand);
261  setLoadExtAction(Ext, T, MemT, Expand);
262  }
263  }
264  }
265  // But some vector extending loads are legal
266  for (auto Ext : {ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}) {
270  }
271  // And some truncating stores are legal as well
274  }
275 
276  // Don't do anything clever with build_pairs
278 
279  // Trap lowers to wasm unreachable
282 
283  // Exception handling intrinsics
287 
289 
290  // Override the __gnu_f2h_ieee/__gnu_h2f_ieee names so that the f32 name is
291  // consistent with the f64 and f128 names.
292  setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2");
293  setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2");
294 
295  // Define the emscripten name for return address helper.
296  // TODO: when implementing other Wasm backends, make this generic or only do
297  // this on emscripten depending on what they end up doing.
298  setLibcallName(RTLIB::RETURN_ADDRESS, "emscripten_return_address");
299 
300  // Always convert switches to br_tables unless there is only one case, which
301  // is equivalent to a simple branch. This reduces code size for wasm, and we
302  // defer possible jump table optimizations to the VM.
304 }
305 
307 WebAssemblyTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
308  // We have wasm instructions for these
309  switch (AI->getOperation()) {
310  case AtomicRMWInst::Add:
311  case AtomicRMWInst::Sub:
312  case AtomicRMWInst::And:
313  case AtomicRMWInst::Or:
314  case AtomicRMWInst::Xor:
315  case AtomicRMWInst::Xchg:
317  default:
318  break;
319  }
321 }
322 
323 FastISel *WebAssemblyTargetLowering::createFastISel(
324  FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const {
325  return WebAssembly::createFastISel(FuncInfo, LibInfo);
326 }
327 
328 MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/,
329  EVT VT) const {
330  unsigned BitWidth = NextPowerOf2(VT.getSizeInBits() - 1);
331  if (BitWidth > 1 && BitWidth < 8)
332  BitWidth = 8;
333 
334  if (BitWidth > 64) {
335  // The shift will be lowered to a libcall, and compiler-rt libcalls expect
336  // the count to be an i32.
337  BitWidth = 32;
339  "32-bit shift counts ought to be enough for anyone");
340  }
341 
344  "Unable to represent scalar shift amount type");
345  return Result;
346 }
347 
348 // Lower an fp-to-int conversion operator from the LLVM opcode, which has an
349 // undefined result on invalid/overflow, to the WebAssembly opcode, which
350 // traps on invalid/overflow.
353  const TargetInstrInfo &TII,
354  bool IsUnsigned, bool Int64,
355  bool Float64, unsigned LoweredOpcode) {
356  MachineRegisterInfo &MRI = BB->getParent()->getRegInfo();
357 
358  Register OutReg = MI.getOperand(0).getReg();
359  Register InReg = MI.getOperand(1).getReg();
360 
361  unsigned Abs = Float64 ? WebAssembly::ABS_F64 : WebAssembly::ABS_F32;
362  unsigned FConst = Float64 ? WebAssembly::CONST_F64 : WebAssembly::CONST_F32;
363  unsigned LT = Float64 ? WebAssembly::LT_F64 : WebAssembly::LT_F32;
364  unsigned GE = Float64 ? WebAssembly::GE_F64 : WebAssembly::GE_F32;
365  unsigned IConst = Int64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
366  unsigned Eqz = WebAssembly::EQZ_I32;
367  unsigned And = WebAssembly::AND_I32;
368  int64_t Limit = Int64 ? INT64_MIN : INT32_MIN;
369  int64_t Substitute = IsUnsigned ? 0 : Limit;
370  double CmpVal = IsUnsigned ? -(double)Limit * 2.0 : -(double)Limit;
371  auto &Context = BB->getParent()->getFunction().getContext();
373 
374  const BasicBlock *LLVMBB = BB->getBasicBlock();
375  MachineFunction *F = BB->getParent();
376  MachineBasicBlock *TrueMBB = F->CreateMachineBasicBlock(LLVMBB);
377  MachineBasicBlock *FalseMBB = F->CreateMachineBasicBlock(LLVMBB);
378  MachineBasicBlock *DoneMBB = F->CreateMachineBasicBlock(LLVMBB);
379 
380  MachineFunction::iterator It = ++BB->getIterator();
381  F->insert(It, FalseMBB);
382  F->insert(It, TrueMBB);
383  F->insert(It, DoneMBB);
384 
385  // Transfer the remainder of BB and its successor edges to DoneMBB.
386  DoneMBB->splice(DoneMBB->begin(), BB, std::next(MI.getIterator()), BB->end());
388 
389  BB->addSuccessor(TrueMBB);
390  BB->addSuccessor(FalseMBB);
391  TrueMBB->addSuccessor(DoneMBB);
392  FalseMBB->addSuccessor(DoneMBB);
393 
394  unsigned Tmp0, Tmp1, CmpReg, EqzReg, FalseReg, TrueReg;
395  Tmp0 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
396  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
397  CmpReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
398  EqzReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
399  FalseReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
400  TrueReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
401 
402  MI.eraseFromParent();
403  // For signed numbers, we can do a single comparison to determine whether
404  // fabs(x) is within range.
405  if (IsUnsigned) {
406  Tmp0 = InReg;
407  } else {
408  BuildMI(BB, DL, TII.get(Abs), Tmp0).addReg(InReg);
409  }
410  BuildMI(BB, DL, TII.get(FConst), Tmp1)
411  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, CmpVal)));
412  BuildMI(BB, DL, TII.get(LT), CmpReg).addReg(Tmp0).addReg(Tmp1);
413 
414  // For unsigned numbers, we have to do a separate comparison with zero.
415  if (IsUnsigned) {
416  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
417  Register SecondCmpReg =
418  MRI.createVirtualRegister(&WebAssembly::I32RegClass);
419  Register AndReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
420  BuildMI(BB, DL, TII.get(FConst), Tmp1)
421  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, 0.0)));
422  BuildMI(BB, DL, TII.get(GE), SecondCmpReg).addReg(Tmp0).addReg(Tmp1);
423  BuildMI(BB, DL, TII.get(And), AndReg).addReg(CmpReg).addReg(SecondCmpReg);
424  CmpReg = AndReg;
425  }
426 
427  BuildMI(BB, DL, TII.get(Eqz), EqzReg).addReg(CmpReg);
428 
429  // Create the CFG diamond to select between doing the conversion or using
430  // the substitute value.
431  BuildMI(BB, DL, TII.get(WebAssembly::BR_IF)).addMBB(TrueMBB).addReg(EqzReg);
432  BuildMI(FalseMBB, DL, TII.get(LoweredOpcode), FalseReg).addReg(InReg);
433  BuildMI(FalseMBB, DL, TII.get(WebAssembly::BR)).addMBB(DoneMBB);
434  BuildMI(TrueMBB, DL, TII.get(IConst), TrueReg).addImm(Substitute);
435  BuildMI(*DoneMBB, DoneMBB->begin(), DL, TII.get(TargetOpcode::PHI), OutReg)
436  .addReg(FalseReg)
437  .addMBB(FalseMBB)
438  .addReg(TrueReg)
439  .addMBB(TrueMBB);
440 
441  return DoneMBB;
442 }
443 
444 static MachineBasicBlock *
446  const WebAssemblySubtarget *Subtarget,
447  const TargetInstrInfo &TII) {
448  MachineInstr &CallParams = *CallResults.getPrevNode();
449  assert(CallParams.getOpcode() == WebAssembly::CALL_PARAMS);
450  assert(CallResults.getOpcode() == WebAssembly::CALL_RESULTS ||
451  CallResults.getOpcode() == WebAssembly::RET_CALL_RESULTS);
452 
453  bool IsIndirect = CallParams.getOperand(0).isReg();
454  bool IsRetCall = CallResults.getOpcode() == WebAssembly::RET_CALL_RESULTS;
455 
456  unsigned CallOp;
457  if (IsIndirect && IsRetCall) {
458  CallOp = WebAssembly::RET_CALL_INDIRECT;
459  } else if (IsIndirect) {
460  CallOp = WebAssembly::CALL_INDIRECT;
461  } else if (IsRetCall) {
462  CallOp = WebAssembly::RET_CALL;
463  } else {
464  CallOp = WebAssembly::CALL;
465  }
466 
467  MachineFunction &MF = *BB->getParent();
468  const MCInstrDesc &MCID = TII.get(CallOp);
469  MachineInstrBuilder MIB(MF, MF.CreateMachineInstr(MCID, DL));
470 
471  // See if we must truncate the function pointer.
472  // CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
473  // as 64-bit for uniformity with other pointer types.
474  // See also: WebAssemblyFastISel::selectCall
475  if (IsIndirect && MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()) {
476  Register Reg32 =
477  MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
478  auto &FnPtr = CallParams.getOperand(0);
479  BuildMI(*BB, CallResults.getIterator(), DL,
480  TII.get(WebAssembly::I32_WRAP_I64), Reg32)
481  .addReg(FnPtr.getReg());
482  FnPtr.setReg(Reg32);
483  }
484 
485  // Move the function pointer to the end of the arguments for indirect calls
486  if (IsIndirect) {
487  auto FnPtr = CallParams.getOperand(0);
488  CallParams.RemoveOperand(0);
489  CallParams.addOperand(FnPtr);
490  }
491 
492  for (auto Def : CallResults.defs())
493  MIB.add(Def);
494 
495  if (IsIndirect) {
496  // Placeholder for the type index.
497  MIB.addImm(0);
498  // The table into which this call_indirect indexes.
499  MCSymbolWasm *Table =
501  if (Subtarget->hasReferenceTypes()) {
502  MIB.addSym(Table);
503  } else {
504  // For the MVP there is at most one table whose number is 0, but we can't
505  // write a table symbol or issue relocations. Instead we just ensure the
506  // table is live and write a zero.
507  Table->setNoStrip();
508  MIB.addImm(0);
509  }
510  }
511 
512  for (auto Use : CallParams.uses())
513  MIB.add(Use);
514 
515  BB->insert(CallResults.getIterator(), MIB);
516  CallParams.eraseFromParent();
517  CallResults.eraseFromParent();
518 
519  return BB;
520 }
521 
522 MachineBasicBlock *WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
523  MachineInstr &MI, MachineBasicBlock *BB) const {
524  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
525  DebugLoc DL = MI.getDebugLoc();
526 
527  switch (MI.getOpcode()) {
528  default:
529  llvm_unreachable("Unexpected instr type to insert");
530  case WebAssembly::FP_TO_SINT_I32_F32:
531  return LowerFPToInt(MI, DL, BB, TII, false, false, false,
532  WebAssembly::I32_TRUNC_S_F32);
533  case WebAssembly::FP_TO_UINT_I32_F32:
534  return LowerFPToInt(MI, DL, BB, TII, true, false, false,
535  WebAssembly::I32_TRUNC_U_F32);
536  case WebAssembly::FP_TO_SINT_I64_F32:
537  return LowerFPToInt(MI, DL, BB, TII, false, true, false,
538  WebAssembly::I64_TRUNC_S_F32);
539  case WebAssembly::FP_TO_UINT_I64_F32:
540  return LowerFPToInt(MI, DL, BB, TII, true, true, false,
541  WebAssembly::I64_TRUNC_U_F32);
542  case WebAssembly::FP_TO_SINT_I32_F64:
543  return LowerFPToInt(MI, DL, BB, TII, false, false, true,
544  WebAssembly::I32_TRUNC_S_F64);
545  case WebAssembly::FP_TO_UINT_I32_F64:
546  return LowerFPToInt(MI, DL, BB, TII, true, false, true,
547  WebAssembly::I32_TRUNC_U_F64);
548  case WebAssembly::FP_TO_SINT_I64_F64:
549  return LowerFPToInt(MI, DL, BB, TII, false, true, true,
550  WebAssembly::I64_TRUNC_S_F64);
551  case WebAssembly::FP_TO_UINT_I64_F64:
552  return LowerFPToInt(MI, DL, BB, TII, true, true, true,
553  WebAssembly::I64_TRUNC_U_F64);
554  case WebAssembly::CALL_RESULTS:
555  case WebAssembly::RET_CALL_RESULTS:
556  return LowerCallResults(MI, DL, BB, Subtarget, TII);
557  }
558 }
559 
560 const char *
561 WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {
562  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
565  break;
566 #define HANDLE_NODETYPE(NODE) \
567  case WebAssemblyISD::NODE: \
568  return "WebAssemblyISD::" #NODE;
569 #define HANDLE_MEM_NODETYPE(NODE) HANDLE_NODETYPE(NODE)
570 #include "WebAssemblyISD.def"
571 #undef HANDLE_MEM_NODETYPE
572 #undef HANDLE_NODETYPE
573  }
574  return nullptr;
575 }
576 
577 std::pair<unsigned, const TargetRegisterClass *>
578 WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
579  const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
580  // First, see if this is a constraint that directly corresponds to a
581  // WebAssembly register class.
582  if (Constraint.size() == 1) {
583  switch (Constraint[0]) {
584  case 'r':
585  assert(VT != MVT::iPTR && "Pointer MVT not expected here");
586  if (Subtarget->hasSIMD128() && VT.isVector()) {
587  if (VT.getSizeInBits() == 128)
588  return std::make_pair(0U, &WebAssembly::V128RegClass);
589  }
590  if (VT.isInteger() && !VT.isVector()) {
591  if (VT.getSizeInBits() <= 32)
592  return std::make_pair(0U, &WebAssembly::I32RegClass);
593  if (VT.getSizeInBits() <= 64)
594  return std::make_pair(0U, &WebAssembly::I64RegClass);
595  }
596  if (VT.isFloatingPoint() && !VT.isVector()) {
597  switch (VT.getSizeInBits()) {
598  case 32:
599  return std::make_pair(0U, &WebAssembly::F32RegClass);
600  case 64:
601  return std::make_pair(0U, &WebAssembly::F64RegClass);
602  default:
603  break;
604  }
605  }
606  break;
607  default:
608  break;
609  }
610  }
611 
612  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
613 }
614 
615 bool WebAssemblyTargetLowering::isCheapToSpeculateCttz() const {
616  // Assume ctz is a relatively cheap operation.
617  return true;
618 }
619 
620 bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const {
621  // Assume clz is a relatively cheap operation.
622  return true;
623 }
624 
625 bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL,
626  const AddrMode &AM,
627  Type *Ty, unsigned AS,
628  Instruction *I) const {
629  // WebAssembly offsets are added as unsigned without wrapping. The
630  // isLegalAddressingMode gives us no way to determine if wrapping could be
631  // happening, so we approximate this by accepting only non-negative offsets.
632  if (AM.BaseOffs < 0)
633  return false;
634 
635  // WebAssembly has no scale register operands.
636  if (AM.Scale != 0)
637  return false;
638 
639  // Everything else is legal.
640  return true;
641 }
642 
643 bool WebAssemblyTargetLowering::allowsMisalignedMemoryAccesses(
644  EVT /*VT*/, unsigned /*AddrSpace*/, Align /*Align*/,
645  MachineMemOperand::Flags /*Flags*/, bool *Fast) const {
646  // WebAssembly supports unaligned accesses, though it should be declared
647  // with the p2align attribute on loads and stores which do so, and there
648  // may be a performance impact. We tell LLVM they're "fast" because
649  // for the kinds of things that LLVM uses this for (merging adjacent stores
650  // of constants, etc.), WebAssembly implementations will either want the
651  // unaligned access or they'll split anyway.
652  if (Fast)
653  *Fast = true;
654  return true;
655 }
656 
657 bool WebAssemblyTargetLowering::isIntDivCheap(EVT VT,
658  AttributeList Attr) const {
659  // The current thinking is that wasm engines will perform this optimization,
660  // so we can save on code size.
661  return true;
662 }
663 
664 bool WebAssemblyTargetLowering::isVectorLoadExtDesirable(SDValue ExtVal) const {
665  EVT ExtT = ExtVal.getValueType();
666  EVT MemT = cast<LoadSDNode>(ExtVal->getOperand(0))->getValueType(0);
667  return (ExtT == MVT::v8i16 && MemT == MVT::v8i8) ||
668  (ExtT == MVT::v4i32 && MemT == MVT::v4i16) ||
669  (ExtT == MVT::v2i64 && MemT == MVT::v2i32);
670 }
671 
672 EVT WebAssemblyTargetLowering::getSetCCResultType(const DataLayout &DL,
673  LLVMContext &C,
674  EVT VT) const {
675  if (VT.isVector())
677 
678  // So far, all branch instructions in Wasm take an I32 condition.
679  // The default TargetLowering::getSetCCResultType returns the pointer size,
680  // which would be useful to reduce instruction counts when testing
681  // against 64-bit pointers/values if at some point Wasm supports that.
682  return EVT::getIntegerVT(C, 32);
683 }
684 
685 bool WebAssemblyTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
686  const CallInst &I,
687  MachineFunction &MF,
688  unsigned Intrinsic) const {
689  switch (Intrinsic) {
690  case Intrinsic::wasm_memory_atomic_notify:
692  Info.memVT = MVT::i32;
693  Info.ptrVal = I.getArgOperand(0);
694  Info.offset = 0;
695  Info.align = Align(4);
696  // atomic.notify instruction does not really load the memory specified with
697  // this argument, but MachineMemOperand should either be load or store, so
698  // we set this to a load.
699  // FIXME Volatile isn't really correct, but currently all LLVM atomic
700  // instructions are treated as volatiles in the backend, so we should be
701  // consistent. The same applies for wasm_atomic_wait intrinsics too.
703  return true;
704  case Intrinsic::wasm_memory_atomic_wait32:
706  Info.memVT = MVT::i32;
707  Info.ptrVal = I.getArgOperand(0);
708  Info.offset = 0;
709  Info.align = Align(4);
711  return true;
712  case Intrinsic::wasm_memory_atomic_wait64:
714  Info.memVT = MVT::i64;
715  Info.ptrVal = I.getArgOperand(0);
716  Info.offset = 0;
717  Info.align = Align(8);
719  return true;
720  case Intrinsic::wasm_load32_zero:
721  case Intrinsic::wasm_load64_zero:
723  Info.memVT = Intrinsic == Intrinsic::wasm_load32_zero ? MVT::i32 : MVT::i64;
724  Info.ptrVal = I.getArgOperand(0);
725  Info.offset = 0;
726  Info.align = Info.memVT == MVT::i32 ? Align(4) : Align(8);
728  return true;
729  case Intrinsic::wasm_load8_lane:
730  case Intrinsic::wasm_load16_lane:
731  case Intrinsic::wasm_load32_lane:
732  case Intrinsic::wasm_load64_lane:
733  case Intrinsic::wasm_store8_lane:
734  case Intrinsic::wasm_store16_lane:
735  case Intrinsic::wasm_store32_lane:
736  case Intrinsic::wasm_store64_lane: {
737  MVT MemVT;
738  Align MemAlign;
739  switch (Intrinsic) {
740  case Intrinsic::wasm_load8_lane:
741  case Intrinsic::wasm_store8_lane:
742  MemVT = MVT::i8;
743  MemAlign = Align(1);
744  break;
745  case Intrinsic::wasm_load16_lane:
746  case Intrinsic::wasm_store16_lane:
747  MemVT = MVT::i16;
748  MemAlign = Align(2);
749  break;
750  case Intrinsic::wasm_load32_lane:
751  case Intrinsic::wasm_store32_lane:
752  MemVT = MVT::i32;
753  MemAlign = Align(4);
754  break;
755  case Intrinsic::wasm_load64_lane:
756  case Intrinsic::wasm_store64_lane:
757  MemVT = MVT::i64;
758  MemAlign = Align(8);
759  break;
760  default:
761  llvm_unreachable("unexpected intrinsic");
762  }
763  if (Intrinsic == Intrinsic::wasm_load8_lane ||
764  Intrinsic == Intrinsic::wasm_load16_lane ||
765  Intrinsic == Intrinsic::wasm_load32_lane ||
766  Intrinsic == Intrinsic::wasm_load64_lane) {
769  } else {
772  }
773  Info.ptrVal = I.getArgOperand(0);
774  Info.memVT = MemVT;
775  Info.offset = 0;
776  Info.align = MemAlign;
777  return true;
778  }
779  default:
780  return false;
781  }
782 }
783 
784 //===----------------------------------------------------------------------===//
785 // WebAssembly Lowering private implementation.
786 //===----------------------------------------------------------------------===//
787 
788 //===----------------------------------------------------------------------===//
789 // Lowering Code
790 //===----------------------------------------------------------------------===//
791 
792 static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *Msg) {
794  DAG.getContext()->diagnose(
795  DiagnosticInfoUnsupported(MF.getFunction(), Msg, DL.getDebugLoc()));
796 }
797 
798 // Test whether the given calling convention is supported.
799 static bool callingConvSupported(CallingConv::ID CallConv) {
800  // We currently support the language-independent target-independent
801  // conventions. We don't yet have a way to annotate calls with properties like
802  // "cold", and we don't have any call-clobbered registers, so these are mostly
803  // all handled the same.
804  return CallConv == CallingConv::C || CallConv == CallingConv::Fast ||
805  CallConv == CallingConv::Cold ||
806  CallConv == CallingConv::PreserveMost ||
807  CallConv == CallingConv::PreserveAll ||
808  CallConv == CallingConv::CXX_FAST_TLS ||
810  CallConv == CallingConv::Swift;
811 }
812 
813 SDValue
814 WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
815  SmallVectorImpl<SDValue> &InVals) const {
816  SelectionDAG &DAG = CLI.DAG;
817  SDLoc DL = CLI.DL;
818  SDValue Chain = CLI.Chain;
819  SDValue Callee = CLI.Callee;
821  auto Layout = MF.getDataLayout();
822 
823  CallingConv::ID CallConv = CLI.CallConv;
824  if (!callingConvSupported(CallConv))
825  fail(DL, DAG,
826  "WebAssembly doesn't support language-specific or target-specific "
827  "calling conventions yet");
828  if (CLI.IsPatchPoint)
829  fail(DL, DAG, "WebAssembly doesn't support patch point yet");
830 
831  if (CLI.IsTailCall) {
832  auto NoTail = [&](const char *Msg) {
833  if (CLI.CB && CLI.CB->isMustTailCall())
834  fail(DL, DAG, Msg);
835  CLI.IsTailCall = false;
836  };
837 
838  if (!Subtarget->hasTailCall())
839  NoTail("WebAssembly 'tail-call' feature not enabled");
840 
841  // Varargs calls cannot be tail calls because the buffer is on the stack
842  if (CLI.IsVarArg)
843  NoTail("WebAssembly does not support varargs tail calls");
844 
845  // Do not tail call unless caller and callee return types match
846  const Function &F = MF.getFunction();
847  const TargetMachine &TM = getTargetMachine();
848  Type *RetTy = F.getReturnType();
849  SmallVector<MVT, 4> CallerRetTys;
850  SmallVector<MVT, 4> CalleeRetTys;
851  computeLegalValueVTs(F, TM, RetTy, CallerRetTys);
852  computeLegalValueVTs(F, TM, CLI.RetTy, CalleeRetTys);
853  bool TypesMatch = CallerRetTys.size() == CalleeRetTys.size() &&
854  std::equal(CallerRetTys.begin(), CallerRetTys.end(),
855  CalleeRetTys.begin());
856  if (!TypesMatch)
857  NoTail("WebAssembly tail call requires caller and callee return types to "
858  "match");
859 
860  // If pointers to local stack values are passed, we cannot tail call
861  if (CLI.CB) {
862  for (auto &Arg : CLI.CB->args()) {
863  Value *Val = Arg.get();
864  // Trace the value back through pointer operations
865  while (true) {
866  Value *Src = Val->stripPointerCastsAndAliases();
867  if (auto *GEP = dyn_cast<GetElementPtrInst>(Src))
868  Src = GEP->getPointerOperand();
869  if (Val == Src)
870  break;
871  Val = Src;
872  }
873  if (isa<AllocaInst>(Val)) {
874  NoTail(
875  "WebAssembly does not support tail calling with stack arguments");
876  break;
877  }
878  }
879  }
880  }
881 
883  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
884  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
885 
886  // The generic code may have added an sret argument. If we're lowering an
887  // invoke function, the ABI requires that the function pointer be the first
888  // argument, so we may have to swap the arguments.
889  if (CallConv == CallingConv::WASM_EmscriptenInvoke && Outs.size() >= 2 &&
890  Outs[0].Flags.isSRet()) {
891  std::swap(Outs[0], Outs[1]);
892  std::swap(OutVals[0], OutVals[1]);
893  }
894 
895  bool HasSwiftSelfArg = false;
896  bool HasSwiftErrorArg = false;
897  unsigned NumFixedArgs = 0;
898  for (unsigned I = 0; I < Outs.size(); ++I) {
899  const ISD::OutputArg &Out = Outs[I];
900  SDValue &OutVal = OutVals[I];
901  HasSwiftSelfArg |= Out.Flags.isSwiftSelf();
902  HasSwiftErrorArg |= Out.Flags.isSwiftError();
903  if (Out.Flags.isNest())
904  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
905  if (Out.Flags.isInAlloca())
906  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
907  if (Out.Flags.isInConsecutiveRegs())
908  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
909  if (Out.Flags.isInConsecutiveRegsLast())
910  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
911  if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
912  auto &MFI = MF.getFrameInfo();
913  int FI = MFI.CreateStackObject(Out.Flags.getByValSize(),
915  /*isSS=*/false);
916  SDValue SizeNode =
918  SDValue FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
919  Chain = DAG.getMemcpy(
920  Chain, DL, FINode, OutVal, SizeNode, Out.Flags.getNonZeroByValAlign(),
921  /*isVolatile*/ false, /*AlwaysInline=*/false,
922  /*isTailCall*/ false, MachinePointerInfo(), MachinePointerInfo());
923  OutVal = FINode;
924  }
925  // Count the number of fixed args *after* legalization.
926  NumFixedArgs += Out.IsFixed;
927  }
928 
929  bool IsVarArg = CLI.IsVarArg;
930  auto PtrVT = getPointerTy(Layout);
931 
932  // For swiftcc, emit additional swiftself and swifterror arguments
933  // if there aren't. These additional arguments are also added for callee
934  // signature They are necessary to match callee and caller signature for
935  // indirect call.
936  if (CallConv == CallingConv::Swift) {
937  if (!HasSwiftSelfArg) {
938  NumFixedArgs++;
940  Arg.Flags.setSwiftSelf();
941  CLI.Outs.push_back(Arg);
942  SDValue ArgVal = DAG.getUNDEF(PtrVT);
943  CLI.OutVals.push_back(ArgVal);
944  }
945  if (!HasSwiftErrorArg) {
946  NumFixedArgs++;
948  Arg.Flags.setSwiftError();
949  CLI.Outs.push_back(Arg);
950  SDValue ArgVal = DAG.getUNDEF(PtrVT);
951  CLI.OutVals.push_back(ArgVal);
952  }
953  }
954 
955  // Analyze operands of the call, assigning locations to each operand.
957  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
958 
959  if (IsVarArg) {
960  // Outgoing non-fixed arguments are placed in a buffer. First
961  // compute their offsets and the total amount of buffer space needed.
962  for (unsigned I = NumFixedArgs; I < Outs.size(); ++I) {
963  const ISD::OutputArg &Out = Outs[I];
964  SDValue &Arg = OutVals[I];
965  EVT VT = Arg.getValueType();
966  assert(VT != MVT::iPTR && "Legalized args should be concrete");
967  Type *Ty = VT.getTypeForEVT(*DAG.getContext());
968  Align Alignment =
969  std::max(Out.Flags.getNonZeroOrigAlign(), Layout.getABITypeAlign(Ty));
970  unsigned Offset =
971  CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty), Alignment);
972  CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(),
973  Offset, VT.getSimpleVT(),
975  }
976  }
977 
978  unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
979 
980  SDValue FINode;
981  if (IsVarArg && NumBytes) {
982  // For non-fixed arguments, next emit stores to store the argument values
983  // to the stack buffer at the offsets computed above.
984  int FI = MF.getFrameInfo().CreateStackObject(NumBytes,
985  Layout.getStackAlignment(),
986  /*isSS=*/false);
987  unsigned ValNo = 0;
989  for (SDValue Arg : drop_begin(OutVals, NumFixedArgs)) {
990  assert(ArgLocs[ValNo].getValNo() == ValNo &&
991  "ArgLocs should remain in order and only hold varargs args");
992  unsigned Offset = ArgLocs[ValNo++].getLocMemOffset();
993  FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
994  SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, FINode,
995  DAG.getConstant(Offset, DL, PtrVT));
996  Chains.push_back(
997  DAG.getStore(Chain, DL, Arg, Add,
999  }
1000  if (!Chains.empty())
1001  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
1002  } else if (IsVarArg) {
1003  FINode = DAG.getIntPtrConstant(0, DL);
1004  }
1005 
1006  if (Callee->getOpcode() == ISD::GlobalAddress) {
1007  // If the callee is a GlobalAddress node (quite common, every direct call
1008  // is) turn it into a TargetGlobalAddress node so that LowerGlobalAddress
1009  // doesn't at MO_GOT which is not needed for direct calls.
1010  GlobalAddressSDNode* GA = cast<GlobalAddressSDNode>(Callee);
1012  getPointerTy(DAG.getDataLayout()),
1013  GA->getOffset());
1015  getPointerTy(DAG.getDataLayout()), Callee);
1016  }
1017 
1018  // Compute the operands for the CALLn node.
1020  Ops.push_back(Chain);
1021  Ops.push_back(Callee);
1022 
1023  // Add all fixed arguments. Note that for non-varargs calls, NumFixedArgs
1024  // isn't reliable.
1025  Ops.append(OutVals.begin(),
1026  IsVarArg ? OutVals.begin() + NumFixedArgs : OutVals.end());
1027  // Add a pointer to the vararg buffer.
1028  if (IsVarArg)
1029  Ops.push_back(FINode);
1030 
1031  SmallVector<EVT, 8> InTys;
1032  for (const auto &In : Ins) {
1033  assert(!In.Flags.isByVal() && "byval is not valid for return values");
1034  assert(!In.Flags.isNest() && "nest is not valid for return values");
1035  if (In.Flags.isInAlloca())
1036  fail(DL, DAG, "WebAssembly hasn't implemented inalloca return values");
1037  if (In.Flags.isInConsecutiveRegs())
1038  fail(DL, DAG, "WebAssembly hasn't implemented cons regs return values");
1039  if (In.Flags.isInConsecutiveRegsLast())
1040  fail(DL, DAG,
1041  "WebAssembly hasn't implemented cons regs last return values");
1042  // Ignore In.getNonZeroOrigAlign() because all our arguments are passed in
1043  // registers.
1044  InTys.push_back(In.VT);
1045  }
1046 
1047  if (CLI.IsTailCall) {
1048  // ret_calls do not return values to the current frame
1049  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1050  return DAG.getNode(WebAssemblyISD::RET_CALL, DL, NodeTys, Ops);
1051  }
1052 
1053  InTys.push_back(MVT::Other);
1054  SDVTList InTyList = DAG.getVTList(InTys);
1055  SDValue Res = DAG.getNode(WebAssemblyISD::CALL, DL, InTyList, Ops);
1056 
1057  for (size_t I = 0; I < Ins.size(); ++I)
1058  InVals.push_back(Res.getValue(I));
1059 
1060  // Return the chain
1061  return Res.getValue(Ins.size());
1062 }
1063 
1064 bool WebAssemblyTargetLowering::CanLowerReturn(
1065  CallingConv::ID /*CallConv*/, MachineFunction & /*MF*/, bool /*IsVarArg*/,
1066  const SmallVectorImpl<ISD::OutputArg> &Outs,
1067  LLVMContext & /*Context*/) const {
1068  // WebAssembly can only handle returning tuples with multivalue enabled
1069  return Subtarget->hasMultivalue() || Outs.size() <= 1;
1070 }
1071 
1072 SDValue WebAssemblyTargetLowering::LowerReturn(
1073  SDValue Chain, CallingConv::ID CallConv, bool /*IsVarArg*/,
1074  const SmallVectorImpl<ISD::OutputArg> &Outs,
1075  const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
1076  SelectionDAG &DAG) const {
1077  assert((Subtarget->hasMultivalue() || Outs.size() <= 1) &&
1078  "MVP WebAssembly can only return up to one value");
1079  if (!callingConvSupported(CallConv))
1080  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
1081 
1082  SmallVector<SDValue, 4> RetOps(1, Chain);
1083  RetOps.append(OutVals.begin(), OutVals.end());
1084  Chain = DAG.getNode(WebAssemblyISD::RETURN, DL, MVT::Other, RetOps);
1085 
1086  // Record the number and types of the return values.
1087  for (const ISD::OutputArg &Out : Outs) {
1088  assert(!Out.Flags.isByVal() && "byval is not valid for return values");
1089  assert(!Out.Flags.isNest() && "nest is not valid for return values");
1090  assert(Out.IsFixed && "non-fixed return value is not valid");
1091  if (Out.Flags.isInAlloca())
1092  fail(DL, DAG, "WebAssembly hasn't implemented inalloca results");
1093  if (Out.Flags.isInConsecutiveRegs())
1094  fail(DL, DAG, "WebAssembly hasn't implemented cons regs results");
1095  if (Out.Flags.isInConsecutiveRegsLast())
1096  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results");
1097  }
1098 
1099  return Chain;
1100 }
1101 
1102 SDValue WebAssemblyTargetLowering::LowerFormalArguments(
1103  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
1104  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
1105  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
1106  if (!callingConvSupported(CallConv))
1107  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
1108 
1109  MachineFunction &MF = DAG.getMachineFunction();
1110  auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
1111 
1112  // Set up the incoming ARGUMENTS value, which serves to represent the liveness
1113  // of the incoming values before they're represented by virtual registers.
1114  MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
1115 
1116  bool HasSwiftErrorArg = false;
1117  bool HasSwiftSelfArg = false;
1118  for (const ISD::InputArg &In : Ins) {
1119  HasSwiftSelfArg |= In.Flags.isSwiftSelf();
1120  HasSwiftErrorArg |= In.Flags.isSwiftError();
1121  if (In.Flags.isInAlloca())
1122  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
1123  if (In.Flags.isNest())
1124  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
1125  if (In.Flags.isInConsecutiveRegs())
1126  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
1127  if (In.Flags.isInConsecutiveRegsLast())
1128  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
1129  // Ignore In.getNonZeroOrigAlign() because all our arguments are passed in
1130  // registers.
1131  InVals.push_back(In.Used ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
1132  DAG.getTargetConstant(InVals.size(),
1133  DL, MVT::i32))
1134  : DAG.getUNDEF(In.VT));
1135 
1136  // Record the number and types of arguments.
1137  MFI->addParam(In.VT);
1138  }
1139 
1140  // For swiftcc, emit additional swiftself and swifterror arguments
1141  // if there aren't. These additional arguments are also added for callee
1142  // signature They are necessary to match callee and caller signature for
1143  // indirect call.
1144  auto PtrVT = getPointerTy(MF.getDataLayout());
1145  if (CallConv == CallingConv::Swift) {
1146  if (!HasSwiftSelfArg) {
1147  MFI->addParam(PtrVT);
1148  }
1149  if (!HasSwiftErrorArg) {
1150  MFI->addParam(PtrVT);
1151  }
1152  }
1153  // Varargs are copied into a buffer allocated by the caller, and a pointer to
1154  // the buffer is passed as an argument.
1155  if (IsVarArg) {
1156  MVT PtrVT = getPointerTy(MF.getDataLayout());
1157  Register VarargVreg =
1159  MFI->setVarargBufferVreg(VarargVreg);
1160  Chain = DAG.getCopyToReg(
1161  Chain, DL, VarargVreg,
1162  DAG.getNode(WebAssemblyISD::ARGUMENT, DL, PtrVT,
1163  DAG.getTargetConstant(Ins.size(), DL, MVT::i32)));
1164  MFI->addParam(PtrVT);
1165  }
1166 
1167  // Record the number and types of arguments and results.
1168  SmallVector<MVT, 4> Params;
1171  MF.getFunction(), DAG.getTarget(), Params, Results);
1172  for (MVT VT : Results)
1173  MFI->addResult(VT);
1174  // TODO: Use signatures in WebAssemblyMachineFunctionInfo too and unify
1175  // the param logic here with ComputeSignatureVTs
1176  assert(MFI->getParams().size() == Params.size() &&
1177  std::equal(MFI->getParams().begin(), MFI->getParams().end(),
1178  Params.begin()));
1179 
1180  return Chain;
1181 }
1182 
1183 void WebAssemblyTargetLowering::ReplaceNodeResults(
1185  switch (N->getOpcode()) {
1187  // Do not add any results, signifying that N should not be custom lowered
1188  // after all. This happens because simd128 turns on custom lowering for
1189  // SIGN_EXTEND_INREG, but for non-vector sign extends the result might be an
1190  // illegal type.
1191  break;
1192  default:
1194  "ReplaceNodeResults not implemented for this op for WebAssembly!");
1195  }
1196 }
1197 
1198 //===----------------------------------------------------------------------===//
1199 // Custom lowering hooks.
1200 //===----------------------------------------------------------------------===//
1201 
1202 SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
1203  SelectionDAG &DAG) const {
1204  SDLoc DL(Op);
1205  switch (Op.getOpcode()) {
1206  default:
1207  llvm_unreachable("unimplemented operation lowering");
1208  return SDValue();
1209  case ISD::FrameIndex:
1210  return LowerFrameIndex(Op, DAG);
1211  case ISD::GlobalAddress:
1212  return LowerGlobalAddress(Op, DAG);
1213  case ISD::GlobalTLSAddress:
1214  return LowerGlobalTLSAddress(Op, DAG);
1215  case ISD::ExternalSymbol:
1216  return LowerExternalSymbol(Op, DAG);
1217  case ISD::JumpTable:
1218  return LowerJumpTable(Op, DAG);
1219  case ISD::BR_JT:
1220  return LowerBR_JT(Op, DAG);
1221  case ISD::VASTART:
1222  return LowerVASTART(Op, DAG);
1223  case ISD::BlockAddress:
1224  case ISD::BRIND:
1225  fail(DL, DAG, "WebAssembly hasn't implemented computed gotos");
1226  return SDValue();
1227  case ISD::RETURNADDR:
1228  return LowerRETURNADDR(Op, DAG);
1229  case ISD::FRAMEADDR:
1230  return LowerFRAMEADDR(Op, DAG);
1231  case ISD::CopyToReg:
1232  return LowerCopyToReg(Op, DAG);
1235  return LowerAccessVectorElement(Op, DAG);
1236  case ISD::INTRINSIC_VOID:
1239  return LowerIntrinsic(Op, DAG);
1241  return LowerSIGN_EXTEND_INREG(Op, DAG);
1242  case ISD::BUILD_VECTOR:
1243  return LowerBUILD_VECTOR(Op, DAG);
1244  case ISD::VECTOR_SHUFFLE:
1245  return LowerVECTOR_SHUFFLE(Op, DAG);
1246  case ISD::SETCC:
1247  return LowerSETCC(Op, DAG);
1248  case ISD::SHL:
1249  case ISD::SRA:
1250  case ISD::SRL:
1251  return LowerShift(Op, DAG);
1252  case ISD::FP_TO_SINT_SAT:
1253  case ISD::FP_TO_UINT_SAT:
1254  return LowerFP_TO_INT_SAT(Op, DAG);
1255  }
1256 }
1257 
1258 SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op,
1259  SelectionDAG &DAG) const {
1260  SDValue Src = Op.getOperand(2);
1261  if (isa<FrameIndexSDNode>(Src.getNode())) {
1262  // CopyToReg nodes don't support FrameIndex operands. Other targets select
1263  // the FI to some LEA-like instruction, but since we don't have that, we
1264  // need to insert some kind of instruction that can take an FI operand and
1265  // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
1266  // local.copy between Op and its FI operand.
1267  SDValue Chain = Op.getOperand(0);
1268  SDLoc DL(Op);
1269  unsigned Reg = cast<RegisterSDNode>(Op.getOperand(1))->getReg();
1270  EVT VT = Src.getValueType();
1271  SDValue Copy(DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_I32
1272  : WebAssembly::COPY_I64,
1273  DL, VT, Src),
1274  0);
1275  return Op.getNode()->getNumValues() == 1
1276  ? DAG.getCopyToReg(Chain, DL, Reg, Copy)
1277  : DAG.getCopyToReg(Chain, DL, Reg, Copy,
1278  Op.getNumOperands() == 4 ? Op.getOperand(3)
1279  : SDValue());
1280  }
1281  return SDValue();
1282 }
1283 
1284 SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op,
1285  SelectionDAG &DAG) const {
1286  int FI = cast<FrameIndexSDNode>(Op)->getIndex();
1287  return DAG.getTargetFrameIndex(FI, Op.getValueType());
1288 }
1289 
1290 SDValue WebAssemblyTargetLowering::LowerRETURNADDR(SDValue Op,
1291  SelectionDAG &DAG) const {
1292  SDLoc DL(Op);
1293 
1294  if (!Subtarget->getTargetTriple().isOSEmscripten()) {
1295  fail(DL, DAG,
1296  "Non-Emscripten WebAssembly hasn't implemented "
1297  "__builtin_return_address");
1298  return SDValue();
1299  }
1300 
1302  return SDValue();
1303 
1304  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1305  MakeLibCallOptions CallOptions;
1306  return makeLibCall(DAG, RTLIB::RETURN_ADDRESS, Op.getValueType(),
1307  {DAG.getConstant(Depth, DL, MVT::i32)}, CallOptions, DL)
1308  .first;
1309 }
1310 
1311 SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op,
1312  SelectionDAG &DAG) const {
1313  // Non-zero depths are not supported by WebAssembly currently. Use the
1314  // legalizer's default expansion, which is to return 0 (what this function is
1315  // documented to do).
1316  if (Op.getConstantOperandVal(0) > 0)
1317  return SDValue();
1318 
1320  EVT VT = Op.getValueType();
1321  Register FP =
1323  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT);
1324 }
1325 
1326 SDValue
1327 WebAssemblyTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1328  SelectionDAG &DAG) const {
1329  SDLoc DL(Op);
1330  const auto *GA = cast<GlobalAddressSDNode>(Op);
1331  MVT PtrVT = getPointerTy(DAG.getDataLayout());
1332 
1333  MachineFunction &MF = DAG.getMachineFunction();
1335  report_fatal_error("cannot use thread-local storage without bulk memory",
1336  false);
1337 
1338  const GlobalValue *GV = GA->getGlobal();
1339 
1340  // Currently Emscripten does not support dynamic linking with threads.
1341  // Therefore, if we have thread-local storage, only the local-exec model
1342  // is possible.
1343  // TODO: remove this and implement proper TLS models once Emscripten
1344  // supports dynamic linking with threads.
1346  !Subtarget->getTargetTriple().isOSEmscripten()) {
1347  report_fatal_error("only -ftls-model=local-exec is supported for now on "
1348  "non-Emscripten OSes: variable " +
1349  GV->getName(),
1350  false);
1351  }
1352 
1353  auto GlobalGet = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64
1354  : WebAssembly::GLOBAL_GET_I32;
1355  const char *BaseName = MF.createExternalSymbolName("__tls_base");
1356 
1357  SDValue BaseAddr(
1358  DAG.getMachineNode(GlobalGet, DL, PtrVT,
1359  DAG.getTargetExternalSymbol(BaseName, PtrVT)),
1360  0);
1361 
1362  SDValue TLSOffset = DAG.getTargetGlobalAddress(
1363  GV, DL, PtrVT, GA->getOffset(), WebAssemblyII::MO_TLS_BASE_REL);
1364  SDValue SymAddr = DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT, TLSOffset);
1365 
1366  return DAG.getNode(ISD::ADD, DL, PtrVT, BaseAddr, SymAddr);
1367 }
1368 
1369 SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
1370  SelectionDAG &DAG) const {
1371  SDLoc DL(Op);
1372  const auto *GA = cast<GlobalAddressSDNode>(Op);
1373  EVT VT = Op.getValueType();
1374  assert(GA->getTargetFlags() == 0 &&
1375  "Unexpected target flags on generic GlobalAddressSDNode");
1376  if (GA->getAddressSpace() != 0)
1377  fail(DL, DAG, "WebAssembly only expects the 0 address space");
1378 
1379  unsigned OperandFlags = 0;
1380  if (isPositionIndependent()) {
1381  const GlobalValue *GV = GA->getGlobal();
1382  if (getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV)) {
1383  MachineFunction &MF = DAG.getMachineFunction();
1384  MVT PtrVT = getPointerTy(MF.getDataLayout());
1385  const char *BaseName;
1386  if (GV->getValueType()->isFunctionTy()) {
1387  BaseName = MF.createExternalSymbolName("__table_base");
1389  }
1390  else {
1391  BaseName = MF.createExternalSymbolName("__memory_base");
1393  }
1394  SDValue BaseAddr =
1395  DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
1396  DAG.getTargetExternalSymbol(BaseName, PtrVT));
1397 
1398  SDValue SymAddr = DAG.getNode(
1400  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset(),
1401  OperandFlags));
1402 
1403  return DAG.getNode(ISD::ADD, DL, VT, BaseAddr, SymAddr);
1404  } else {
1406  }
1407  }
1408 
1409  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1410  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
1411  GA->getOffset(), OperandFlags));
1412 }
1413 
1414 SDValue
1415 WebAssemblyTargetLowering::LowerExternalSymbol(SDValue Op,
1416  SelectionDAG &DAG) const {
1417  SDLoc DL(Op);
1418  const auto *ES = cast<ExternalSymbolSDNode>(Op);
1419  EVT VT = Op.getValueType();
1420  assert(ES->getTargetFlags() == 0 &&
1421  "Unexpected target flags on generic ExternalSymbolSDNode");
1422  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1423  DAG.getTargetExternalSymbol(ES->getSymbol(), VT));
1424 }
1425 
1426 SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
1427  SelectionDAG &DAG) const {
1428  // There's no need for a Wrapper node because we always incorporate a jump
1429  // table operand into a BR_TABLE instruction, rather than ever
1430  // materializing it in a register.
1431  const JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1432  return DAG.getTargetJumpTable(JT->getIndex(), Op.getValueType(),
1433  JT->getTargetFlags());
1434 }
1435 
1436 SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op,
1437  SelectionDAG &DAG) const {
1438  SDLoc DL(Op);
1439  SDValue Chain = Op.getOperand(0);
1440  const auto *JT = cast<JumpTableSDNode>(Op.getOperand(1));
1441  SDValue Index = Op.getOperand(2);
1442  assert(JT->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
1443 
1445  Ops.push_back(Chain);
1446  Ops.push_back(Index);
1447 
1449  const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs;
1450 
1451  // Add an operand for each case.
1452  for (auto MBB : MBBs)
1453  Ops.push_back(DAG.getBasicBlock(MBB));
1454 
1455  // Add the first MBB as a dummy default target for now. This will be replaced
1456  // with the proper default target (and the preceding range check eliminated)
1457  // if possible by WebAssemblyFixBrTableDefaults.
1458  Ops.push_back(DAG.getBasicBlock(*MBBs.begin()));
1459  return DAG.getNode(WebAssemblyISD::BR_TABLE, DL, MVT::Other, Ops);
1460 }
1461 
1462 SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op,
1463  SelectionDAG &DAG) const {
1464  SDLoc DL(Op);
1466 
1467  auto *MFI = DAG.getMachineFunction().getInfo<WebAssemblyFunctionInfo>();
1468  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1469 
1470  SDValue ArgN = DAG.getCopyFromReg(DAG.getEntryNode(), DL,
1471  MFI->getVarargBufferVreg(), PtrVT);
1472  return DAG.getStore(Op.getOperand(0), DL, ArgN, Op.getOperand(1),
1473  MachinePointerInfo(SV));
1474 }
1475 
1476 static SDValue getCppExceptionSymNode(SDValue Op, unsigned TagIndex,
1477  SelectionDAG &DAG) {
1478  // We only support C++ exceptions for now
1479  int Tag =
1480  cast<ConstantSDNode>(Op.getOperand(TagIndex).getNode())->getZExtValue();
1481  if (Tag != WebAssembly::CPP_EXCEPTION)
1482  llvm_unreachable("Invalid tag: We only support C++ exceptions for now");
1483  auto &MF = DAG.getMachineFunction();
1484  const auto &TLI = DAG.getTargetLoweringInfo();
1485  MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
1486  const char *SymName = MF.createExternalSymbolName("__cpp_exception");
1487  return DAG.getNode(WebAssemblyISD::Wrapper, SDLoc(Op), PtrVT,
1488  DAG.getTargetExternalSymbol(SymName, PtrVT));
1489 }
1490 
1491 SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
1492  SelectionDAG &DAG) const {
1493  MachineFunction &MF = DAG.getMachineFunction();
1494  unsigned IntNo;
1495  switch (Op.getOpcode()) {
1496  case ISD::INTRINSIC_VOID:
1498  IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
1499  break;
1501  IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1502  break;
1503  default:
1504  llvm_unreachable("Invalid intrinsic");
1505  }
1506  SDLoc DL(Op);
1507 
1508  switch (IntNo) {
1509  default:
1510  return SDValue(); // Don't custom lower most intrinsics.
1511 
1512  case Intrinsic::wasm_lsda: {
1513  EVT VT = Op.getValueType();
1514  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1515  MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
1516  auto &Context = MF.getMMI().getContext();
1517  MCSymbol *S = Context.getOrCreateSymbol(Twine("GCC_except_table") +
1518  Twine(MF.getFunctionNumber()));
1519  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1520  DAG.getMCSymbol(S, PtrVT));
1521  }
1522 
1523  case Intrinsic::wasm_throw: {
1524  SDValue SymNode = getCppExceptionSymNode(Op, 2, DAG);
1525  return DAG.getNode(WebAssemblyISD::THROW, DL,
1526  MVT::Other, // outchain type
1527  {
1528  Op.getOperand(0), // inchain
1529  SymNode, // exception symbol
1530  Op.getOperand(3) // thrown value
1531  });
1532  }
1533 
1534  case Intrinsic::wasm_catch: {
1535  SDValue SymNode = getCppExceptionSymNode(Op, 2, DAG);
1536  return DAG.getNode(WebAssemblyISD::CATCH, DL,
1537  {
1538  MVT::i32, // outchain type
1539  MVT::Other // return value
1540  },
1541  {
1542  Op.getOperand(0), // inchain
1543  SymNode // exception symbol
1544  });
1545  }
1546 
1547  case Intrinsic::wasm_shuffle: {
1548  // Drop in-chain and replace undefs, but otherwise pass through unchanged
1549  SDValue Ops[18];
1550  size_t OpIdx = 0;
1551  Ops[OpIdx++] = Op.getOperand(1);
1552  Ops[OpIdx++] = Op.getOperand(2);
1553  while (OpIdx < 18) {
1554  const SDValue &MaskIdx = Op.getOperand(OpIdx + 1);
1555  if (MaskIdx.isUndef() ||
1556  cast<ConstantSDNode>(MaskIdx.getNode())->getZExtValue() >= 32) {
1557  Ops[OpIdx++] = DAG.getConstant(0, DL, MVT::i32);
1558  } else {
1559  Ops[OpIdx++] = MaskIdx;
1560  }
1561  }
1562  return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
1563  }
1564  }
1565 }
1566 
1567 SDValue
1568 WebAssemblyTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
1569  SelectionDAG &DAG) const {
1570  SDLoc DL(Op);
1571  // If sign extension operations are disabled, allow sext_inreg only if operand
1572  // is a vector extract of an i8 or i16 lane. SIMD does not depend on sign
1573  // extension operations, but allowing sext_inreg in this context lets us have
1574  // simple patterns to select extract_lane_s instructions. Expanding sext_inreg
1575  // everywhere would be simpler in this file, but would necessitate large and
1576  // brittle patterns to undo the expansion and select extract_lane_s
1577  // instructions.
1578  assert(!Subtarget->hasSignExt() && Subtarget->hasSIMD128());
1579  if (Op.getOperand(0).getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1580  return SDValue();
1581 
1582  const SDValue &Extract = Op.getOperand(0);
1583  MVT VecT = Extract.getOperand(0).getSimpleValueType();
1584  if (VecT.getVectorElementType().getSizeInBits() > 32)
1585  return SDValue();
1586  MVT ExtractedLaneT =
1587  cast<VTSDNode>(Op.getOperand(1).getNode())->getVT().getSimpleVT();
1588  MVT ExtractedVecT =
1589  MVT::getVectorVT(ExtractedLaneT, 128 / ExtractedLaneT.getSizeInBits());
1590  if (ExtractedVecT == VecT)
1591  return Op;
1592 
1593  // Bitcast vector to appropriate type to ensure ISel pattern coverage
1594  const SDNode *Index = Extract.getOperand(1).getNode();
1595  if (!isa<ConstantSDNode>(Index))
1596  return SDValue();
1597  unsigned IndexVal = cast<ConstantSDNode>(Index)->getZExtValue();
1598  unsigned Scale =
1599  ExtractedVecT.getVectorNumElements() / VecT.getVectorNumElements();
1600  assert(Scale > 1);
1601  SDValue NewIndex =
1602  DAG.getConstant(IndexVal * Scale, DL, Index->getValueType(0));
1603  SDValue NewExtract = DAG.getNode(
1605  DAG.getBitcast(ExtractedVecT, Extract.getOperand(0)), NewIndex);
1606  return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Op.getValueType(), NewExtract,
1607  Op.getOperand(1));
1608 }
1609 
1610 SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
1611  SelectionDAG &DAG) const {
1612  SDLoc DL(Op);
1613  const EVT VecT = Op.getValueType();
1614  const EVT LaneT = Op.getOperand(0).getValueType();
1615  const size_t Lanes = Op.getNumOperands();
1616  bool CanSwizzle = VecT == MVT::v16i8;
1617 
1618  // BUILD_VECTORs are lowered to the instruction that initializes the highest
1619  // possible number of lanes at once followed by a sequence of replace_lane
1620  // instructions to individually initialize any remaining lanes.
1621 
1622  // TODO: Tune this. For example, lanewise swizzling is very expensive, so
1623  // swizzled lanes should be given greater weight.
1624 
1625  // TODO: Investigate looping rather than always extracting/replacing specific
1626  // lanes to fill gaps.
1627 
1628  auto IsConstant = [](const SDValue &V) {
1629  return V.getOpcode() == ISD::Constant || V.getOpcode() == ISD::ConstantFP;
1630  };
1631 
1632  // Returns the source vector and index vector pair if they exist. Checks for:
1633  // (extract_vector_elt
1634  // $src,
1635  // (sign_extend_inreg (extract_vector_elt $indices, $i))
1636  // )
1637  auto GetSwizzleSrcs = [](size_t I, const SDValue &Lane) {
1638  auto Bail = std::make_pair(SDValue(), SDValue());
1639  if (Lane->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1640  return Bail;
1641  const SDValue &SwizzleSrc = Lane->getOperand(0);
1642  const SDValue &IndexExt = Lane->getOperand(1);
1643  if (IndexExt->getOpcode() != ISD::SIGN_EXTEND_INREG)
1644  return Bail;
1645  const SDValue &Index = IndexExt->getOperand(0);
1646  if (Index->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1647  return Bail;
1648  const SDValue &SwizzleIndices = Index->getOperand(0);
1649  if (SwizzleSrc.getValueType() != MVT::v16i8 ||
1650  SwizzleIndices.getValueType() != MVT::v16i8 ||
1651  Index->getOperand(1)->getOpcode() != ISD::Constant ||
1652  Index->getConstantOperandVal(1) != I)
1653  return Bail;
1654  return std::make_pair(SwizzleSrc, SwizzleIndices);
1655  };
1656 
1657  // If the lane is extracted from another vector at a constant index, return
1658  // that vector. The source vector must not have more lanes than the dest
1659  // because the shufflevector indices are in terms of the destination lanes and
1660  // would not be able to address the smaller individual source lanes.
1661  auto GetShuffleSrc = [&](const SDValue &Lane) {
1662  if (Lane->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1663  return SDValue();
1664  if (!isa<ConstantSDNode>(Lane->getOperand(1).getNode()))
1665  return SDValue();
1666  if (Lane->getOperand(0).getValueType().getVectorNumElements() >
1667  VecT.getVectorNumElements())
1668  return SDValue();
1669  return Lane->getOperand(0);
1670  };
1671 
1672  using ValueEntry = std::pair<SDValue, size_t>;
1673  SmallVector<ValueEntry, 16> SplatValueCounts;
1674 
1675  using SwizzleEntry = std::pair<std::pair<SDValue, SDValue>, size_t>;
1676  SmallVector<SwizzleEntry, 16> SwizzleCounts;
1677 
1678  using ShuffleEntry = std::pair<SDValue, size_t>;
1679  SmallVector<ShuffleEntry, 16> ShuffleCounts;
1680 
1681  auto AddCount = [](auto &Counts, const auto &Val) {
1682  auto CountIt =
1683  llvm::find_if(Counts, [&Val](auto E) { return E.first == Val; });
1684  if (CountIt == Counts.end()) {
1685  Counts.emplace_back(Val, 1);
1686  } else {
1687  CountIt->second++;
1688  }
1689  };
1690 
1691  auto GetMostCommon = [](auto &Counts) {
1692  auto CommonIt =
1693  std::max_element(Counts.begin(), Counts.end(),
1694  [](auto A, auto B) { return A.second < B.second; });
1695  assert(CommonIt != Counts.end() && "Unexpected all-undef build_vector");
1696  return *CommonIt;
1697  };
1698 
1699  size_t NumConstantLanes = 0;
1700 
1701  // Count eligible lanes for each type of vector creation op
1702  for (size_t I = 0; I < Lanes; ++I) {
1703  const SDValue &Lane = Op->getOperand(I);
1704  if (Lane.isUndef())
1705  continue;
1706 
1707  AddCount(SplatValueCounts, Lane);
1708 
1709  if (IsConstant(Lane))
1710  NumConstantLanes++;
1711  if (auto ShuffleSrc = GetShuffleSrc(Lane))
1712  AddCount(ShuffleCounts, ShuffleSrc);
1713  if (CanSwizzle) {
1714  auto SwizzleSrcs = GetSwizzleSrcs(I, Lane);
1715  if (SwizzleSrcs.first)
1716  AddCount(SwizzleCounts, SwizzleSrcs);
1717  }
1718  }
1719 
1720  SDValue SplatValue;
1721  size_t NumSplatLanes;
1722  std::tie(SplatValue, NumSplatLanes) = GetMostCommon(SplatValueCounts);
1723 
1724  SDValue SwizzleSrc;
1725  SDValue SwizzleIndices;
1726  size_t NumSwizzleLanes = 0;
1727  if (SwizzleCounts.size())
1728  std::forward_as_tuple(std::tie(SwizzleSrc, SwizzleIndices),
1729  NumSwizzleLanes) = GetMostCommon(SwizzleCounts);
1730 
1731  // Shuffles can draw from up to two vectors, so find the two most common
1732  // sources.
1733  SDValue ShuffleSrc1, ShuffleSrc2;
1734  size_t NumShuffleLanes = 0;
1735  if (ShuffleCounts.size()) {
1736  std::tie(ShuffleSrc1, NumShuffleLanes) = GetMostCommon(ShuffleCounts);
1737  ShuffleCounts.erase(std::remove_if(ShuffleCounts.begin(),
1738  ShuffleCounts.end(),
1739  [&](const auto &Pair) {
1740  return Pair.first == ShuffleSrc1;
1741  }),
1742  ShuffleCounts.end());
1743  }
1744  if (ShuffleCounts.size()) {
1745  size_t AdditionalShuffleLanes;
1746  std::tie(ShuffleSrc2, AdditionalShuffleLanes) =
1747  GetMostCommon(ShuffleCounts);
1748  NumShuffleLanes += AdditionalShuffleLanes;
1749  }
1750 
1751  // Predicate returning true if the lane is properly initialized by the
1752  // original instruction
1753  std::function<bool(size_t, const SDValue &)> IsLaneConstructed;
1754  SDValue Result;
1755  // Prefer swizzles over shuffles over vector consts over splats
1756  if (NumSwizzleLanes >= NumShuffleLanes &&
1757  NumSwizzleLanes >= NumConstantLanes && NumSwizzleLanes >= NumSplatLanes) {
1758  Result = DAG.getNode(WebAssemblyISD::SWIZZLE, DL, VecT, SwizzleSrc,
1759  SwizzleIndices);
1760  auto Swizzled = std::make_pair(SwizzleSrc, SwizzleIndices);
1761  IsLaneConstructed = [&, Swizzled](size_t I, const SDValue &Lane) {
1762  return Swizzled == GetSwizzleSrcs(I, Lane);
1763  };
1764  } else if (NumShuffleLanes >= NumConstantLanes &&
1765  NumShuffleLanes >= NumSplatLanes) {
1766  size_t DestLaneSize = VecT.getVectorElementType().getFixedSizeInBits() / 8;
1767  size_t DestLaneCount = VecT.getVectorNumElements();
1768  size_t Scale1 = 1;
1769  size_t Scale2 = 1;
1770  SDValue Src1 = ShuffleSrc1;
1771  SDValue Src2 = ShuffleSrc2 ? ShuffleSrc2 : DAG.getUNDEF(VecT);
1772  if (Src1.getValueType() != VecT) {
1773  size_t LaneSize =
1775  assert(LaneSize > DestLaneSize);
1776  Scale1 = LaneSize / DestLaneSize;
1777  Src1 = DAG.getBitcast(VecT, Src1);
1778  }
1779  if (Src2.getValueType() != VecT) {
1780  size_t LaneSize =
1782  assert(LaneSize > DestLaneSize);
1783  Scale2 = LaneSize / DestLaneSize;
1784  Src2 = DAG.getBitcast(VecT, Src2);
1785  }
1786 
1787  int Mask[16];
1788  assert(DestLaneCount <= 16);
1789  for (size_t I = 0; I < DestLaneCount; ++I) {
1790  const SDValue &Lane = Op->getOperand(I);
1791  SDValue Src = GetShuffleSrc(Lane);
1792  if (Src == ShuffleSrc1) {
1793  Mask[I] = Lane->getConstantOperandVal(1) * Scale1;
1794  } else if (Src && Src == ShuffleSrc2) {
1795  Mask[I] = DestLaneCount + Lane->getConstantOperandVal(1) * Scale2;
1796  } else {
1797  Mask[I] = -1;
1798  }
1799  }
1800  ArrayRef<int> MaskRef(Mask, DestLaneCount);
1801  Result = DAG.getVectorShuffle(VecT, DL, Src1, Src2, MaskRef);
1802  IsLaneConstructed = [&](size_t, const SDValue &Lane) {
1803  auto Src = GetShuffleSrc(Lane);
1804  return Src == ShuffleSrc1 || (Src && Src == ShuffleSrc2);
1805  };
1806  } else if (NumConstantLanes >= NumSplatLanes) {
1807  SmallVector<SDValue, 16> ConstLanes;
1808  for (const SDValue &Lane : Op->op_values()) {
1809  if (IsConstant(Lane)) {
1810  ConstLanes.push_back(Lane);
1811  } else if (LaneT.isFloatingPoint()) {
1812  ConstLanes.push_back(DAG.getConstantFP(0, DL, LaneT));
1813  } else {
1814  ConstLanes.push_back(DAG.getConstant(0, DL, LaneT));
1815  }
1816  }
1817  Result = DAG.getBuildVector(VecT, DL, ConstLanes);
1818  IsLaneConstructed = [&IsConstant](size_t _, const SDValue &Lane) {
1819  return IsConstant(Lane);
1820  };
1821  } else {
1822  // Use a splat, but possibly a load_splat
1823  LoadSDNode *SplattedLoad;
1824  if ((SplattedLoad = dyn_cast<LoadSDNode>(SplatValue)) &&
1825  SplattedLoad->getMemoryVT() == VecT.getVectorElementType()) {
1827  WebAssemblyISD::LOAD_SPLAT, DL, DAG.getVTList(VecT),
1828  {SplattedLoad->getChain(), SplattedLoad->getBasePtr(),
1829  SplattedLoad->getOffset()},
1830  SplattedLoad->getMemoryVT(), SplattedLoad->getMemOperand());
1831  } else {
1832  Result = DAG.getSplatBuildVector(VecT, DL, SplatValue);
1833  }
1834  IsLaneConstructed = [&SplatValue](size_t _, const SDValue &Lane) {
1835  return Lane == SplatValue;
1836  };
1837  }
1838 
1839  assert(Result);
1840  assert(IsLaneConstructed);
1841 
1842  // Add replace_lane instructions for any unhandled values
1843  for (size_t I = 0; I < Lanes; ++I) {
1844  const SDValue &Lane = Op->getOperand(I);
1845  if (!Lane.isUndef() && !IsLaneConstructed(I, Lane))
1846  Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VecT, Result, Lane,
1847  DAG.getConstant(I, DL, MVT::i32));
1848  }
1849 
1850  return Result;
1851 }
1852 
1853 SDValue
1854 WebAssemblyTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
1855  SelectionDAG &DAG) const {
1856  SDLoc DL(Op);
1857  ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Op.getNode())->getMask();
1858  MVT VecType = Op.getOperand(0).getSimpleValueType();
1859  assert(VecType.is128BitVector() && "Unexpected shuffle vector type");
1860  size_t LaneBytes = VecType.getVectorElementType().getSizeInBits() / 8;
1861 
1862  // Space for two vector args and sixteen mask indices
1863  SDValue Ops[18];
1864  size_t OpIdx = 0;
1865  Ops[OpIdx++] = Op.getOperand(0);
1866  Ops[OpIdx++] = Op.getOperand(1);
1867 
1868  // Expand mask indices to byte indices and materialize them as operands
1869  for (int M : Mask) {
1870  for (size_t J = 0; J < LaneBytes; ++J) {
1871  // Lower undefs (represented by -1 in mask) to zero
1872  uint64_t ByteIndex = M == -1 ? 0 : (uint64_t)M * LaneBytes + J;
1873  Ops[OpIdx++] = DAG.getConstant(ByteIndex, DL, MVT::i32);
1874  }
1875  }
1876 
1877  return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
1878 }
1879 
1880 SDValue WebAssemblyTargetLowering::LowerSETCC(SDValue Op,
1881  SelectionDAG &DAG) const {
1882  SDLoc DL(Op);
1883  // The legalizer does not know how to expand the unsupported comparison modes
1884  // of i64x2 vectors, so we manually unroll them here.
1885  assert(Op->getOperand(0)->getSimpleValueType(0) == MVT::v2i64);
1886  SmallVector<SDValue, 2> LHS, RHS;
1887  DAG.ExtractVectorElements(Op->getOperand(0), LHS);
1888  DAG.ExtractVectorElements(Op->getOperand(1), RHS);
1889  const SDValue &CC = Op->getOperand(2);
1890  auto MakeLane = [&](unsigned I) {
1891  return DAG.getNode(ISD::SELECT_CC, DL, MVT::i64, LHS[I], RHS[I],
1892  DAG.getConstant(uint64_t(-1), DL, MVT::i64),
1893  DAG.getConstant(uint64_t(0), DL, MVT::i64), CC);
1894  };
1895  return DAG.getBuildVector(Op->getValueType(0), DL,
1896  {MakeLane(0), MakeLane(1)});
1897 }
1898 
1899 SDValue
1900 WebAssemblyTargetLowering::LowerAccessVectorElement(SDValue Op,
1901  SelectionDAG &DAG) const {
1902  // Allow constant lane indices, expand variable lane indices
1903  SDNode *IdxNode = Op.getOperand(Op.getNumOperands() - 1).getNode();
1904  if (isa<ConstantSDNode>(IdxNode) || IdxNode->isUndef())
1905  return Op;
1906  else
1907  // Perform default expansion
1908  return SDValue();
1909 }
1910 
1912  EVT LaneT = Op.getSimpleValueType().getVectorElementType();
1913  // 32-bit and 64-bit unrolled shifts will have proper semantics
1914  if (LaneT.bitsGE(MVT::i32))
1915  return DAG.UnrollVectorOp(Op.getNode());
1916  // Otherwise mask the shift value to get proper semantics from 32-bit shift
1917  SDLoc DL(Op);
1918  size_t NumLanes = Op.getSimpleValueType().getVectorNumElements();
1919  SDValue Mask = DAG.getConstant(LaneT.getSizeInBits() - 1, DL, MVT::i32);
1920  unsigned ShiftOpcode = Op.getOpcode();
1921  SmallVector<SDValue, 16> ShiftedElements;
1922  DAG.ExtractVectorElements(Op.getOperand(0), ShiftedElements, 0, 0, MVT::i32);
1923  SmallVector<SDValue, 16> ShiftElements;
1924  DAG.ExtractVectorElements(Op.getOperand(1), ShiftElements, 0, 0, MVT::i32);
1925  SmallVector<SDValue, 16> UnrolledOps;
1926  for (size_t i = 0; i < NumLanes; ++i) {
1927  SDValue MaskedShiftValue =
1928  DAG.getNode(ISD::AND, DL, MVT::i32, ShiftElements[i], Mask);
1929  SDValue ShiftedValue = ShiftedElements[i];
1930  if (ShiftOpcode == ISD::SRA)
1931  ShiftedValue = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32,
1932  ShiftedValue, DAG.getValueType(LaneT));
1933  UnrolledOps.push_back(
1934  DAG.getNode(ShiftOpcode, DL, MVT::i32, ShiftedValue, MaskedShiftValue));
1935  }
1936  return DAG.getBuildVector(Op.getValueType(), DL, UnrolledOps);
1937 }
1938 
1939 SDValue WebAssemblyTargetLowering::LowerShift(SDValue Op,
1940  SelectionDAG &DAG) const {
1941  SDLoc DL(Op);
1942 
1943  // Only manually lower vector shifts
1944  assert(Op.getSimpleValueType().isVector());
1945 
1946  auto ShiftVal = DAG.getSplatValue(Op.getOperand(1));
1947  if (!ShiftVal)
1948  return unrollVectorShift(Op, DAG);
1949 
1950  // Use anyext because none of the high bits can affect the shift
1951  ShiftVal = DAG.getAnyExtOrTrunc(ShiftVal, DL, MVT::i32);
1952 
1953  unsigned Opcode;
1954  switch (Op.getOpcode()) {
1955  case ISD::SHL:
1956  Opcode = WebAssemblyISD::VEC_SHL;
1957  break;
1958  case ISD::SRA:
1959  Opcode = WebAssemblyISD::VEC_SHR_S;
1960  break;
1961  case ISD::SRL:
1962  Opcode = WebAssemblyISD::VEC_SHR_U;
1963  break;
1964  default:
1965  llvm_unreachable("unexpected opcode");
1966  }
1967 
1968  return DAG.getNode(Opcode, DL, Op.getValueType(), Op.getOperand(0), ShiftVal);
1969 }
1970 
1971 SDValue WebAssemblyTargetLowering::LowerFP_TO_INT_SAT(SDValue Op,
1972  SelectionDAG &DAG) const {
1973  SDLoc DL(Op);
1974  EVT ResT = Op.getValueType();
1975  uint64_t Width = Op.getConstantOperandVal(1);
1976 
1977  if ((ResT == MVT::i32 || ResT == MVT::i64) && (Width == 32 || Width == 64))
1978  return Op;
1979 
1980  if (ResT == MVT::v4i32 && Width == 32)
1981  return Op;
1982 
1983  return SDValue();
1984 }
1985 
1986 //===----------------------------------------------------------------------===//
1987 // Custom DAG combine hooks
1988 //===----------------------------------------------------------------------===//
1989 static SDValue
1991  auto &DAG = DCI.DAG;
1992  auto Shuffle = cast<ShuffleVectorSDNode>(N);
1993 
1994  // Hoist vector bitcasts that don't change the number of lanes out of unary
1995  // shuffles, where they are less likely to get in the way of other combines.
1996  // (shuffle (vNxT1 (bitcast (vNxT0 x))), undef, mask) ->
1997  // (vNxT1 (bitcast (vNxT0 (shuffle x, undef, mask))))
1998  SDValue Bitcast = N->getOperand(0);
1999  if (Bitcast.getOpcode() != ISD::BITCAST)
2000  return SDValue();
2001  if (!N->getOperand(1).isUndef())
2002  return SDValue();
2003  SDValue CastOp = Bitcast.getOperand(0);
2004  MVT SrcType = CastOp.getSimpleValueType();
2005  MVT DstType = Bitcast.getSimpleValueType();
2006  if (!SrcType.is128BitVector() ||
2007  SrcType.getVectorNumElements() != DstType.getVectorNumElements())
2008  return SDValue();
2009  SDValue NewShuffle = DAG.getVectorShuffle(
2010  SrcType, SDLoc(N), CastOp, DAG.getUNDEF(SrcType), Shuffle->getMask());
2011  return DAG.getBitcast(DstType, NewShuffle);
2012 }
2013 
2014 static SDValue
2016  auto &DAG = DCI.DAG;
2017  assert(N->getOpcode() == ISD::SIGN_EXTEND ||
2018  N->getOpcode() == ISD::ZERO_EXTEND);
2019 
2020  // Combine ({s,z}ext (extract_subvector src, i)) into a widening operation if
2021  // possible before the extract_subvector can be expanded.
2022  auto Extract = N->getOperand(0);
2023  if (Extract.getOpcode() != ISD::EXTRACT_SUBVECTOR)
2024  return SDValue();
2025  auto Source = Extract.getOperand(0);
2026  auto *IndexNode = dyn_cast<ConstantSDNode>(Extract.getOperand(1));
2027  if (IndexNode == nullptr)
2028  return SDValue();
2029  auto Index = IndexNode->getZExtValue();
2030 
2031  // Only v8i8, v4i16, and v2i32 extracts can be widened, and only if the
2032  // extracted subvector is the low or high half of its source.
2033  EVT ResVT = N->getValueType(0);
2034  if (ResVT == MVT::v8i16) {
2035  if (Extract.getValueType() != MVT::v8i8 ||
2036  Source.getValueType() != MVT::v16i8 || (Index != 0 && Index != 8))
2037  return SDValue();
2038  } else if (ResVT == MVT::v4i32) {
2039  if (Extract.getValueType() != MVT::v4i16 ||
2040  Source.getValueType() != MVT::v8i16 || (Index != 0 && Index != 4))
2041  return SDValue();
2042  } else if (ResVT == MVT::v2i64) {
2043  if (Extract.getValueType() != MVT::v2i32 ||
2044  Source.getValueType() != MVT::v4i32 || (Index != 0 && Index != 2))
2045  return SDValue();
2046  } else {
2047  return SDValue();
2048  }
2049 
2050  bool IsSext = N->getOpcode() == ISD::SIGN_EXTEND;
2051  bool IsLow = Index == 0;
2052 
2053  unsigned Op = IsSext ? (IsLow ? WebAssemblyISD::EXTEND_LOW_S
2054  : WebAssemblyISD::EXTEND_HIGH_S)
2055  : (IsLow ? WebAssemblyISD::EXTEND_LOW_U
2056  : WebAssemblyISD::EXTEND_HIGH_U);
2057 
2058  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2059 }
2060 
2061 static SDValue
2064  auto &DAG = DCI.DAG;
2065  assert(N->getOpcode() == ISD::SINT_TO_FP ||
2066  N->getOpcode() == ISD::UINT_TO_FP);
2067 
2068  // Combine ({s,u}int_to_fp (extract_subvector ... 0)) to an
2069  // f64x2.convert_low_i32x4_{s,u} SDNode.
2070  auto Extract = N->getOperand(0);
2071  if (Extract.getOpcode() != ISD::EXTRACT_SUBVECTOR)
2072  return SDValue();
2073  auto Source = Extract.getOperand(0);
2074  if (Source.getValueType() != MVT::v4i32)
2075  return SDValue();
2076  auto *IndexNode = dyn_cast<ConstantSDNode>(Extract.getOperand(1));
2077  if (IndexNode == nullptr)
2078  return SDValue();
2079  auto Index = IndexNode->getZExtValue();
2080 
2081  // The types must be correct.
2082  EVT ResVT = N->getValueType(0);
2083  if (ResVT != MVT::v2f64 || Extract.getValueType() != MVT::v2i32)
2084  return SDValue();
2085 
2086  // The extracted vector must be the low half.
2087  if (Index != 0)
2088  return SDValue();
2089 
2090  unsigned Op = N->getOpcode() == ISD::SINT_TO_FP
2091  ? WebAssemblyISD::CONVERT_LOW_S
2092  : WebAssemblyISD::CONVERT_LOW_U;
2093 
2094  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2095 }
2096 
2097 static SDValue
2100  auto &DAG = DCI.DAG;
2101  assert(N->getOpcode() == ISD::CONCAT_VECTORS);
2102 
2103  // Combine this:
2104  //
2105  // (concat_vectors (v2i32 (fp_to_{s,u}int_sat $x, 32)), (v2i32 (splat 0)))
2106  //
2107  // into (i32x4.trunc_sat_f64x2_zero_{s,u} $x).
2108  EVT ResVT = N->getValueType(0);
2109  if (ResVT != MVT::v4i32)
2110  return SDValue();
2111 
2112  auto FPToInt = N->getOperand(0);
2113  auto FPToIntOp = FPToInt.getOpcode();
2114  if (FPToIntOp != ISD::FP_TO_SINT_SAT && FPToIntOp != ISD::FP_TO_UINT_SAT)
2115  return SDValue();
2116  if (FPToInt.getConstantOperandVal(1) != 32)
2117  return SDValue();
2118 
2119  auto Source = FPToInt.getOperand(0);
2120  if (Source.getValueType() != MVT::v2f64)
2121  return SDValue();
2122 
2123  auto *Splat = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
2124  APInt SplatValue, SplatUndef;
2125  unsigned SplatBitSize;
2126  bool HasAnyUndefs;
2127  if (!Splat || !Splat->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
2128  HasAnyUndefs))
2129  return SDValue();
2130  if (SplatValue != 0)
2131  return SDValue();
2132 
2133  unsigned Op = FPToIntOp == ISD::FP_TO_SINT_SAT
2134  ? WebAssemblyISD::TRUNC_SAT_ZERO_S
2135  : WebAssemblyISD::TRUNC_SAT_ZERO_U;
2136 
2137  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2138 }
2139 
2140 SDValue
2141 WebAssemblyTargetLowering::PerformDAGCombine(SDNode *N,
2142  DAGCombinerInfo &DCI) const {
2143  switch (N->getOpcode()) {
2144  default:
2145  return SDValue();
2146  case ISD::VECTOR_SHUFFLE:
2147  return performVECTOR_SHUFFLECombine(N, DCI);
2148  case ISD::SIGN_EXTEND:
2149  case ISD::ZERO_EXTEND:
2150  return performVectorExtendCombine(N, DCI);
2151  case ISD::SINT_TO_FP:
2152  case ISD::UINT_TO_FP:
2153  return performVectorConvertLowCombine(N, DCI);
2154  case ISD::CONCAT_VECTORS:
2155  return performVectorTruncSatLowCombine(N, DCI);
2156  }
2157 }
llvm::MachineRegisterInfo::addLiveIn
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Definition: MachineRegisterInfo.h:929
llvm::SDNode::getConstantOperandVal
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
Definition: SelectionDAGNodes.h:1571
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::SelectionDAG::getSplatValue
SDValue getSplatValue(SDValue V)
If V is a splat vector, return its scalar source operand by extracting that element from the source v...
Definition: SelectionDAG.cpp:2629
llvm::ISD::ExternalSymbol
@ ExternalSymbol
Definition: ISDOpcodes.h:76
llvm::ISD::ArgFlagsTy::isInAlloca
bool isInAlloca() const
Definition: TargetCallingConv.h:89
llvm::ISD::SETUGE
@ SETUGE
Definition: ISDOpcodes.h:1349
performVectorExtendCombine
static SDValue performVectorExtendCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2015
llvm::WebAssemblySubtarget::getRegisterInfo
const WebAssemblyRegisterInfo * getRegisterInfo() const override
Definition: WebAssemblySubtarget.h:80
llvm::TargetLoweringBase::setSchedulingPreference
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
Definition: TargetLowering.h:2093
llvm::ISD::VECTOR_SHUFFLE
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition: ISDOpcodes.h:557
llvm::WebAssemblySubtarget::getTargetTriple
const Triple & getTargetTriple() const
Definition: WebAssemblySubtarget.h:83
llvm::MVT::getVectorElementType
MVT getVectorElementType() const
Definition: MachineValueType.h:499
llvm::ISD::INTRINSIC_VOID
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition: ISDOpcodes.h:192
llvm::MachineInstr::uses
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
Definition: MachineInstr.h:655
llvm::ISD::SETO
@ SETO
Definition: ISDOpcodes.h:1345
llvm::Value::stripPointerCastsAndAliases
const Value * stripPointerCastsAndAliases() const
Strip off pointer casts, all-zero GEPs, address space casts, and aliases.
Definition: Value.cpp:640
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
MathExtras.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:132
llvm
Definition: AllocatorList.h:23
llvm::SmallVectorImpl::erase
iterator erase(const_iterator CI)
Definition: SmallVector.h:705
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
llvm::ISD::JumpTable
@ JumpTable
Definition: ISDOpcodes.h:74
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
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::MachineInstrBuilder::addFPImm
const MachineInstrBuilder & addFPImm(const ConstantFP *Val) const
Definition: MachineInstrBuilder.h:142
llvm::SystemZISD::TM
@ TM
Definition: SystemZISelLowering.h:65
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:275
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1078
llvm::CCValAssign::Full
@ Full
Definition: CallingConvLower.h:36
llvm::TargetLoweringBase::Legal
@ Legal
Definition: TargetLowering.h:193
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:112
llvm::MVT::isInteger
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: MachineValueType.h:331
llvm::ISD::BITCAST
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:833
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:931
llvm::MachineModuleInfo::getContext
const MCContext & getContext() const
Definition: MachineModuleInfo.h:167
llvm::WebAssemblySubtarget::hasTailCall
bool hasTailCall() const
Definition: WebAssemblySubtarget.h:99
llvm::DiagnosticInfoUnsupported
Diagnostic information for unsupported feature in backend.
Definition: DiagnosticInfo.h:993
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::EVT::getFixedSizeInBits
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition: ValueTypes.h:341
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::HexagonISD::JT
@ JT
Definition: HexagonISelLowering.h:52
llvm::SDValue::getNode
SDNode * getNode() const
get the SDNode which holds the desired result
Definition: SelectionDAGNodes.h:152
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:225
llvm::Function
Definition: Function.h:61
llvm::ISD::ConstantFP
@ ConstantFP
Definition: ISDOpcodes.h:70
llvm::MachineFunction::getContext
MCContext & getContext() const
Definition: MachineFunction.h:507
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:513
llvm::ISD::ArgFlagsTy::isInConsecutiveRegsLast
bool isInConsecutiveRegsLast() const
Definition: TargetCallingConv.h:122
llvm::ISD::BSWAP
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:651
llvm::ISD::UDIV
@ UDIV
Definition: ISDOpcodes.h:236
llvm::ISD::DYNAMIC_STACKALLOC
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:916
llvm::AtomicRMWInst::Xor
@ Xor
*p = old ^ v
Definition: Instructions.h:728
llvm::SDNode::isUndef
bool isUndef() const
Return true if the type of the node type undefined.
Definition: SelectionDAGNodes.h:644
llvm::SelectionDAG::getValueType
SDValue getValueType(EVT)
Definition: SelectionDAG.cpp:1696
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)
Definition: SelectionDAG.cpp:6624
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:303
llvm::WebAssembly::CPP_EXCEPTION
@ CPP_EXCEPTION
Definition: WasmEHFuncInfo.h:27
llvm::ISD::ADDC
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:262
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:97
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::AtomicRMWInst::getOperation
BinOp getOperation() const
Definition: Instructions.h:781
llvm::SelectionDAG::getFrameIndex
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
Definition: SelectionDAG.cpp:1577
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:786
Wrapper
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
Definition: AMDGPUAliasAnalysis.cpp:30
llvm::MVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: MachineValueType.h:347
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:997
llvm::SelectionDAG::getVTList
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
Definition: SelectionDAG.cpp:7967
ErrorHandling.h
llvm::CallingConv::PreserveMost
@ PreserveMost
Definition: CallingConv.h:66
llvm::MemSDNode::getMemoryVT
EVT getMemoryVT() const
Return the type of the in-memory value.
Definition: SelectionDAGNodes.h:1325
llvm::MachineFunction::getFunctionNumber
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
Definition: MachineFunction.h:530
llvm::ISD::FLOG2
@ FLOG2
Definition: ISDOpcodes.h:860
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:455
llvm::GlobalAddressSDNode::getTargetFlags
unsigned getTargetFlags() const
Definition: SelectionDAGNodes.h:1706
llvm::ISD::FMA
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition: ISDOpcodes.h:460
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:770
llvm::TargetLowering::DAGCombinerInfo::DAG
SelectionDAG & DAG
Definition: TargetLowering.h:3495
llvm::LoadSDNode
This class is used to represent ISD::LOAD nodes.
Definition: SelectionDAGNodes.h:2255
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:247
llvm::MachineInstr::defs
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
Definition: MachineInstr.h:644
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:231
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:34
llvm::TargetLowering::isPositionIndependent
bool isPositionIndependent() const
Definition: TargetLowering.cpp:45
llvm::ISD::SETULE
@ SETULE
Definition: ISDOpcodes.h:1351
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:46
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:700
llvm::AttributeList
Definition: Attributes.h:385
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:7296
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:10082
llvm::WebAssemblySubtarget::hasAddr64
bool hasAddr64() const
Definition: WebAssemblySubtarget.h:90
llvm::ISD::SETCC
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:687
llvm::AArch64ISD::CALL
@ CALL
Definition: AArch64ISelLowering.h:52
llvm::MVT::integer_valuetypes
static mvt_range integer_valuetypes()
Definition: MachineValueType.h:1362
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
performVECTOR_SHUFFLECombine
static SDValue performVECTOR_SHUFFLECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:1990
T
#define T
Definition: Mips16ISelLowering.cpp:341
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
Results
Function Alias Analysis Results
Definition: AliasAnalysis.cpp:849
WebAssemblyTargetMachine.h
performVectorTruncSatLowCombine
static SDValue performVectorTruncSatLowCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2098
llvm::ISD::VAEND
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1026
llvm::ISD::EXTLOAD
@ EXTLOAD
Definition: ISDOpcodes.h:1316
llvm::MVT::v2f64
@ v2f64
Definition: MachineValueType.h:158
llvm::Triple::isOSEmscripten
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition: Triple.h:615
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:1567
LowerCallResults
static MachineBasicBlock * LowerCallResults(MachineInstr &CallResults, DebugLoc DL, MachineBasicBlock *BB, const WebAssemblySubtarget *Subtarget, const TargetInstrInfo &TII)
Definition: WebAssemblyISelLowering.cpp:445
llvm::ISD::SETUEQ
@ SETUEQ
Definition: ISDOpcodes.h:1347
llvm::ISD::SMAX
@ SMAX
Definition: ISDOpcodes.h:612
llvm::SelectionDAG::getContext
LLVMContext * getContext() const
Definition: SelectionDAG.h:447
llvm::NVPTX::PTXLdStInstCode::VecType
VecType
Definition: NVPTX.h:121
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::ISD::ArgFlagsTy::isSwiftSelf
bool isSwiftSelf() const
Definition: TargetCallingConv.h:95
MachineRegisterInfo.h
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::lltok::equal
@ equal
Definition: LLToken.h:25
llvm::WebAssemblyTargetLowering::WebAssemblyTargetLowering
WebAssemblyTargetLowering(const TargetMachine &TM, const WebAssemblySubtarget &STI)
Definition: WebAssemblyISelLowering.cpp:42
llvm::ISD::BRIND
@ BRIND
BRIND - Indirect branch.
Definition: ISDOpcodes.h:927
llvm::ISD::ROTL
@ ROTL
Definition: ISDOpcodes.h:645
llvm::AArch64CC::LT
@ LT
Definition: AArch64BaseInfo.h:247
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:205
llvm::MachineBasicBlock::addSuccessor
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Definition: MachineBasicBlock.cpp:743
llvm::remove_if
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1544
llvm::ISD::FFLOOR
@ FFLOOR
Definition: ISDOpcodes.h:870
llvm::ISD::BR_CC
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:948
llvm::WebAssemblyII::MO_TLS_BASE_REL
@ MO_TLS_BASE_REL
Definition: WebAssemblyMCTargetDesc.h:106
llvm::MVT::i1
@ i1
Definition: MachineValueType.h:40
llvm::SDNode::getOpcode
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Definition: SelectionDAGNodes.h:621
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:565
llvm::WebAssembly::createFastISel
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
Definition: WebAssemblyFastISel.cpp:1426
llvm::ISD::GlobalAddress
@ GlobalAddress
Definition: ISDOpcodes.h:71
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:679
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:1113
llvm::ISD::CTLZ
@ CTLZ
Definition: ISDOpcodes.h:653
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:147
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
llvm::ISD::Constant
@ Constant
Definition: ISDOpcodes.h:69
llvm::ISD::ZERO_EXTEND
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:714
llvm::ISD::ArgFlagsTy::isByVal
bool isByVal() const
Definition: TargetCallingConv.h:83
llvm::ISD::ABS
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition: ISDOpcodes.h:625
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::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:653
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:49
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:947
llvm::ISD::CopyToReg
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition: ISDOpcodes.h:196
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:732
llvm::SelectionDAG::getTargetLoweringInfo
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:443
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:192
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:488
llvm::MVT::f64
@ f64
Definition: MachineValueType.h:53
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:1346
llvm::GlobalValue::getThreadLocalMode
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:252
llvm::JumpTableSDNode
Definition: SelectionDAGNodes.h:1795
llvm::EVT::getVectorNumElements
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:301
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition: TargetLowering.h:3141
llvm::TargetLowering::DAGCombinerInfo
Definition: TargetLowering.h:3489
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::ISD::SRA
@ SRA
Definition: ISDOpcodes.h:643
llvm::TargetLoweringBase::ZeroOrNegativeOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
Definition: TargetLowering.h:230
unrollVectorShift
static SDValue unrollVectorShift(SDValue Op, SelectionDAG &DAG)
Definition: WebAssemblyISelLowering.cpp:1911
llvm::ISD::UDIVREM
@ UDIVREM
Definition: ISDOpcodes.h:249
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:2140
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:196
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::Instruction
Definition: Instruction.h:45
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:724
llvm::report_fatal_error
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::ISD::FNEARBYINT
@ FNEARBYINT
Definition: ISDOpcodes.h:867
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:843
llvm::ISD::FRINT
@ FRINT
Definition: ISDOpcodes.h:866
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:7023
llvm::CallingConv::Swift
@ Swift
Definition: CallingConv.h:73
llvm::MVT::INVALID_SIMPLE_VALUE_TYPE
@ INVALID_SIMPLE_VALUE_TYPE
Definition: MachineValueType.h:35
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:26
llvm::ISD::AND
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:617
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
llvm::GlobalAddressSDNode::getGlobal
const GlobalValue * getGlobal() const
Definition: SelectionDAGNodes.h:1704
llvm::ISD::FSINCOS
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:900
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:2088
llvm::Type::isFunctionTy
bool isFunctionTy() const
True if this is an instance of FunctionType.
Definition: Type.h:220
llvm::AtomicRMWInst::Xchg
@ Xchg
*p = v
Definition: Instructions.h:716
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::AtomicRMWInst::Add
@ Add
*p = old + v
Definition: Instructions.h:718
llvm::MVT::v4i16
@ v4i16
Definition: MachineValueType.h:86
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:133
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::codeview::ClassOptions::Intrinsic
@ Intrinsic
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::ISD::SETUGT
@ SETUGT
Definition: ISDOpcodes.h:1348
llvm::ISD::ArgFlagsTy::getNonZeroOrigAlign
Align getNonZeroOrigAlign() const
Definition: TargetCallingConv.h:155
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:99
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::ARMISD::WrapperPIC
@ WrapperPIC
Definition: ARMISelLowering.h:61
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:321
llvm::ISD::FPOW
@ FPOW
Definition: ISDOpcodes.h:858
llvm::ISD::BlockAddress
@ BlockAddress
Definition: ISDOpcodes.h:77
llvm::MachineFunction::getMMI
MachineModuleInfo & getMMI() const
Definition: MachineFunction.h:506
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:555
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:2157
llvm::ISD::SMIN
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned integers.
Definition: ISDOpcodes.h:611
llvm::CallingConv::PreserveAll
@ PreserveAll
Definition: CallingConv.h:70
llvm::ISD::FMINIMUM
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
Definition: ISDOpcodes.h:896
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:77
llvm::ISD::FLOG10
@ FLOG10
Definition: ISDOpcodes.h:861
llvm::WebAssemblySubtarget::hasReferenceTypes
bool hasReferenceTypes() const
Definition: WebAssemblySubtarget.h:100
llvm::EVT::getSizeInBits
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:333
llvm::AtomicRMWInst::Sub
@ Sub
*p = old - v
Definition: Instructions.h:720
llvm::CallingConv::CXX_FAST_TLS
@ CXX_FAST_TLS
Definition: CallingConv.h:76
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:318
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:70
llvm::MVT::v2i64
@ v2i64
Definition: MachineValueType.h:109
llvm::ISD::FP_TO_UINT
@ FP_TO_UINT
Definition: ISDOpcodes.h:771
llvm::MemSDNode::getMemOperand
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
Definition: SelectionDAGNodes.h:1329
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:572
llvm::TargetLowering::verifyReturnAddressArgumentIsConstant
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
Definition: TargetLowering.cpp:5933
llvm::SelectionDAG::getIntPtrConstant
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Definition: SelectionDAG.cpp:1470
llvm::TargetLoweringBase::Promote
@ Promote
Definition: TargetLowering.h:194
llvm::LegalizeActions::Bitcast
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Definition: LegalizerInfo.h:72
llvm::MCSymbolWasm
Definition: MCSymbolWasm.h:16
llvm::WebAssemblySubtarget::hasNontrappingFPToInt
bool hasNontrappingFPToInt() const
Definition: WebAssemblySubtarget.h:93
llvm::ISD::TRAP
@ TRAP
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:1073
llvm::CallingConv::Fast
@ Fast
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:42
llvm::MachinePointerInfo
This class contains a discriminated union of information about pointers in memory operands,...
Definition: MachineMemOperand.h:37
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:228
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:505
llvm::TargetLoweringBase::setStackPointerRegisterToSaveRestore
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
Definition: TargetLowering.h:2106
llvm::SDNode::getOperand
const SDValue & getOperand(unsigned Num) const
Definition: SelectionDAGNodes.h:896
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::SelectionDAG::getNode
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
Definition: SelectionDAG.cpp:7732
Analysis.h
llvm::ISD::FP_TO_FP16
@ FP_TO_FP16
Definition: ISDOpcodes.h:844
llvm::FramePointer::FP
FP
Definition: CodeGen.h:71
llvm::CallingConv::Cold
@ Cold
Definition: CallingConv.h:48
llvm::ISD::UADDSAT
@ UADDSAT
Definition: ISDOpcodes.h:321
llvm::ISD::FCOPYSIGN
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition: ISDOpcodes.h:470
llvm::AtomicRMWInst::Or
@ Or
*p = old | v
Definition: Instructions.h:726
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:1261
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:77
llvm::GlobalAddressSDNode::getOffset
int64_t getOffset() const
Definition: SelectionDAGNodes.h:1705
llvm::MVT::v4f32
@ v4f32
Definition: MachineValueType.h:145
llvm::MachineMemOperand::Flags
Flags
Flags values. These may be or'd together.
Definition: MachineMemOperand.h:130
llvm::MVT::getVectorNumElements
unsigned getVectorNumElements() const
Definition: MachineValueType.h:650
llvm::ISD::InputArg
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
Definition: TargetCallingConv.h:190
performVectorConvertLowCombine
static SDValue performVectorConvertLowCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2062
llvm::ISD::ZEXTLOAD
@ ZEXTLOAD
Definition: ISDOpcodes.h:1316
llvm::SDValue::getValue
SDValue getValue(unsigned R) const
Definition: SelectionDAGNodes.h:172
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:41
llvm::ilist_node_with_parent::getPrevNode
NodeTy * getPrevNode()
Definition: ilist_node.h:274
llvm::ISD::ArgFlagsTy::isNest
bool isNest() const
Definition: TargetCallingConv.h:113
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:1769
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:77
llvm::ISD::MULHS
@ MULHS
Definition: ISDOpcodes.h:607
llvm::FunctionLoweringInfo
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Definition: FunctionLoweringInfo.h:53
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:39
llvm::MVT::getSizeInBits
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
Definition: MachineValueType.h:815
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:571
llvm::ISD::SETULT
@ SETULT
Definition: ISDOpcodes.h:1350
llvm::ISD::DEBUGTRAP
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
Definition: ISDOpcodes.h:1076
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:8405
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:2055
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:88
llvm::MVT
Machine Value Type.
Definition: MachineValueType.h:30
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:98
llvm::FastISel
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Definition: FastISel.h:65
llvm::ISD::SRA_PARTS
@ SRA_PARTS
Definition: ISDOpcodes.h:701
llvm::ISD::VASTART
@ VASTART
Definition: ISDOpcodes.h:1027
WebAssemblyMachineFunctionInfo.h
_
#define _
Definition: HexagonMCCodeEmitter.cpp:47
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:71
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::WebAssemblyII::MO_MEMORY_BASE_REL
@ MO_MEMORY_BASE_REL
Definition: WebAssemblyMCTargetDesc.h:101
llvm::MVT::getVectorVT
static MVT getVectorVT(MVT VT, unsigned NumElements)
Definition: MachineValueType.h:1119
TargetOptions.h
llvm::ISD::FMAXIMUM
@ FMAXIMUM
Definition: ISDOpcodes.h:897
llvm::ISD::GlobalTLSAddress
@ GlobalTLSAddress
Definition: ISDOpcodes.h:72
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:98
llvm::AArch64CC::GE
@ GE
Definition: AArch64BaseInfo.h:246
llvm::ArrayRef< int >
llvm::computeLegalValueVTs
void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, SmallVectorImpl< MVT > &ValueVTs)
Definition: WebAssemblyMachineFunctionInfo.cpp:30
llvm::EVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:149
llvm::ISD::UMAX
@ UMAX
Definition: ISDOpcodes.h:614
llvm::MCSymbolWasm::setNoStrip
void setNoStrip() const
Definition: MCSymbolWasm.h:66
llvm::MVT::i64
@ i64
Definition: MachineValueType.h:44
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:94
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:859
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:478
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::ISD::SREM
@ SREM
Definition: ISDOpcodes.h:237
LowerFPToInt
static MachineBasicBlock * LowerFPToInt(MachineInstr &MI, DebugLoc DL, MachineBasicBlock *BB, const TargetInstrInfo &TII, bool IsUnsigned, bool Int64, bool Float64, unsigned LoweredOpcode)
Definition: WebAssemblyISelLowering.cpp:351
llvm::ISD::UMUL_LOHI
@ UMUL_LOHI
Definition: ISDOpcodes.h:244
llvm::ISD::OutputArg::Flags
ArgFlagsTy Flags
Definition: TargetCallingConv.h:229
llvm::WebAssemblySubtarget::hasBulkMemory
bool hasBulkMemory() const
Definition: WebAssemblySubtarget.h:96
llvm::MVT::is128BitVector
bool is128BitVector() const
Return true if this is a 128-bit vector type.
Definition: MachineValueType.h:388
llvm::SDValue::getOperand
const SDValue & getOperand(unsigned i) const
Definition: SelectionDAGNodes.h:1121
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
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::WebAssemblySubtarget
Definition: WebAssemblySubtarget.h:35
llvm::ISD::FEXP
@ FEXP
Definition: ISDOpcodes.h:862
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:243
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:4548
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:2223
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:2177
llvm::SDValue::getSimpleValueType
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
Definition: SelectionDAGNodes.h:183
llvm::MVT::v4i32
@ v4i32
Definition: MachineValueType.h:96
llvm::ISD::FEXP2
@ FEXP2
Definition: ISDOpcodes.h:863
llvm::SelectionDAG::getBasicBlock
SDValue getBasicBlock(MachineBasicBlock *MBB)
Definition: SelectionDAG.cpp:1682
llvm::MVT::iPTR
@ iPTR
Definition: MachineValueType.h:295
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:298
llvm::SDVTList
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
Definition: SelectionDAGNodes.h:79
llvm::MachineMemOperand::MOVolatile
@ MOVolatile
The memory access is volatile.
Definition: MachineMemOperand.h:138
llvm::ISD::SEXTLOAD
@ SEXTLOAD
Definition: ISDOpcodes.h:1316
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:1526
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:702
llvm::MachineMemOperand::MOLoad
@ MOLoad
The memory access reads data.
Definition: MachineMemOperand.h:134
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:177
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:1532
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:87
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:205
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:73
llvm::CallingConv::WASM_EmscriptenInvoke
@ WASM_EmscriptenInvoke
Calling convention for emscripten __invoke_* functions.
Definition: CallingConv.h:242
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::TargetLoweringBase::getTargetMachine
const TargetMachine & getTargetMachine() const
Definition: TargetLowering.h:335
callingConvSupported
static bool callingConvSupported(CallingConv::ID CallConv)
Definition: WebAssemblyISelLowering.cpp:799
llvm::LLVMContext::diagnose
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Definition: LLVMContext.cpp:228
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
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:46
llvm::ISD::ArgFlagsTy::getByValSize
unsigned getByValSize() const
Definition: TargetCallingConv.h:164
llvm::CallingConv::C
@ C
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
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:2165
llvm::GlobalAddressSDNode
Definition: SelectionDAGNodes.h:1692
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:521
llvm::ISD::EXTRACT_SUBVECTOR
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition: ISDOpcodes.h:543
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 integer type wi...
Definition: ISDOpcodes.h:785
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:9825
llvm::TargetLoweringBase::AtomicExpansionKind
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
Definition: TargetLowering.h:246
llvm::MVT::fixedlen_vector_valuetypes
static mvt_range fixedlen_vector_valuetypes()
Definition: MachineValueType.h:1377
CallingConvLower.h
llvm::MVT::integer_fixedlen_vector_valuetypes
static mvt_range integer_fixedlen_vector_valuetypes()
Definition: MachineValueType.h:1389
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
llvm::ISD::BR
@ BR
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:922
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
llvm::ISD::FCOS
@ FCOS
Definition: ISDOpcodes.h:856
WasmEHFuncInfo.h
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:864
llvm::ISD::FSIN
@ FSIN
Definition: ISDOpcodes.h:855
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:440
llvm::MVT::v8i16
@ v8i16
Definition: MachineValueType.h:87
llvm::AtomicRMWInst::And
@ And
*p = old & v
Definition: Instructions.h:722
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:932
llvm::ISD::BUILD_VECTOR
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:485
DiagnosticInfo.h
Function.h
llvm::TargetLoweringBase::Custom
@ Custom
Definition: TargetLowering.h:197
WebAssemblySubtarget.h
llvm::ISD::SUBC
@ SUBC
Definition: ISDOpcodes.h:263
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:1727
llvm::SelectionDAG::getMCSymbol
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
Definition: SelectionDAG.cpp:1718
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:43
llvm::ISD::SETUO
@ SETUO
Definition: ISDOpcodes.h:1346
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:207
getCppExceptionSymNode
static SDValue getCppExceptionSymNode(SDValue Op, unsigned TagIndex, SelectionDAG &DAG)
Definition: WebAssemblyISelLowering.cpp:1476
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:138
llvm::ISD::SDIV
@ SDIV
Definition: ISDOpcodes.h:235
llvm::Function::getFunctionType
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:165
llvm::TargetLoweringBase::ZeroOrOneBooleanContent
@ ZeroOrOneBooleanContent
Definition: TargetLowering.h:229
llvm::WebAssemblySubtarget::hasSIMD128
bool hasSIMD128() const
Definition: WebAssemblySubtarget.h:91
llvm::MCID::Add
@ Add
Definition: MCInstrDesc.h:184
llvm::TargetLoweringBase::setLibcallName
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
Definition: TargetLowering.h:2806
llvm::ISD::VACOPY
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1022
llvm::MachineMemOperand::MOStore
@ MOStore
The memory access writes data.
Definition: MachineMemOperand.h:136
llvm::ISD::SRL_PARTS
@ SRL_PARTS
Definition: ISDOpcodes.h:702
llvm::AMDGPU::Hwreg::Width
Width
Definition: SIDefines.h:403
llvm::ISD::UINT_TO_FP
@ UINT_TO_FP
Definition: ISDOpcodes.h:725
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:232
llvm::SDValue::isUndef
bool isUndef() const
Definition: SelectionDAGNodes.h:1149
llvm::EVT::getVectorElementType
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:293
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:2074
llvm::MachineInstrBuilder::addSym
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
Definition: MachineInstrBuilder.h:268
llvm::ISD::SHL
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:642
llvm::ISD::FREM
@ FREM
Definition: ISDOpcodes.h:375
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:995
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
llvm::ISD::ArgFlagsTy::getNonZeroByValAlign
Align getNonZeroByValAlign() const
Definition: TargetCallingConv.h:148
llvm::ISD::MUL
@ MUL
Definition: ISDOpcodes.h:234
llvm::ISD::UREM
@ UREM
Definition: ISDOpcodes.h:238
llvm::TargetLoweringBase::Expand
@ Expand
Definition: TargetLowering.h:195
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:2254
llvm::MVT::f16
@ f16
Definition: MachineValueType.h:51
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:329
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:1255
llvm::TargetLoweringBase::setMaxAtomicSizeInBitsSupported
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Definition: TargetLowering.h:2284
llvm::ISD::SUBE
@ SUBE
Definition: ISDOpcodes.h:273
llvm::TargetLoweringBase::setMinimumJumpTableEntries
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
Definition: TargetLoweringBase.cpp:1969
llvm::ISD::SRL
@ SRL
Definition: ISDOpcodes.h:644
llvm::MachineInstr::addOperand
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
Definition: MachineInstr.cpp:207
llvm::ISD::ArgFlagsTy::isInConsecutiveRegs
bool isInConsecutiveRegs() const
Definition: TargetCallingConv.h:119
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:350
llvm::MVT::getVT
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:497
llvm::GlobalAddressSDNode::getAddressSpace
unsigned getAddressSpace() const
Definition: SelectionDAG.cpp:10099
llvm::ISD::CTTZ
@ CTTZ
Definition: ISDOpcodes.h:652
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:838
llvm::MachineFunction::getDataLayout
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Definition: MachineFunction.cpp:260
llvm::WebAssemblyII::MO_TABLE_BASE_REL
@ MO_TABLE_BASE_REL
Definition: WebAssemblyMCTargetDesc.h:111
llvm::TargetLoweringBase::AtomicExpansionKind::None
@ None
llvm::ISD::UMIN
@ UMIN
Definition: ISDOpcodes.h:613
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:606
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:882
llvm::SDValue::getOpcode
unsigned getOpcode() const
Definition: SelectionDAGNodes.h:1109
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
llvm::ISD::SETONE
@ SETONE
Definition: ISDOpcodes.h:1344
llvm::MVT::i16
@ i16
Definition: MachineValueType.h:42
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:185
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1450
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:98
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:171
llvm::MachineFunction::createExternalSymbolName
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
Definition: MachineFunction.cpp:495
llvm::ISD::BUILD_PAIR
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition: ISDOpcodes.h:222
llvm::ISD::VAARG
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1017
llvm::WebAssemblyISD::FIRST_MEM_OPCODE
@ FIRST_MEM_OPCODE
Definition: WebAssemblyISelLowering.h:29
llvm::ISD::SDIVREM
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:248
llvm::MachineFunction::getJumpTableInfo
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
Definition: MachineFunction.h:578
llvm::MachineFunction::CreateMachineInstr
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, const DebugLoc &DL, bool NoImplicit=false)
CreateMachineInstr - Allocate a new MachineInstr.
Definition: MachineFunction.cpp:348
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineFrameInfo::setFrameAddressIsTaken
void setFrameAddressIsTaken(bool T)
Definition: MachineFrameInfo.h:367
llvm::EVT::bitsGE
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
Definition: ValueTypes.h:257
llvm::MachineJumpTableInfo
Definition: MachineJumpTableInfo.h:42
llvm::ISD::SIGN_EXTEND
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:711
raw_ostream.h
llvm::MVT::v8i8
@ v8i8
Definition: MachineValueType.h:76
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160
llvm::ISD::FTRUNC
@ FTRUNC
Definition: ISDOpcodes.h:865
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:677
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:494
llvm::ISD::STACKSAVE
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:993
llvm::ISD::FLOG
@ FLOG
Definition: ISDOpcodes.h:859
llvm::ISD::ADDE
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:272
llvm::MVT::f32
@ f32
Definition: MachineValueType.h:52
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::ISD::ROTR
@ ROTR
Definition: ISDOpcodes.h:646
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:134
llvm::Type::getFloatTy
static Type * getFloatTy(LLVMContext &C)
Definition: Type.cpp:191
llvm::WebAssemblySubtarget::hasSignExt
bool hasSignExt() const
Definition: WebAssemblySubtarget.h:94
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:342
llvm::ISD::CTPOP
@ CTPOP
Definition: ISDOpcodes.h:654
llvm::ISD::SADDSAT
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition: ISDOpcodes.h:320
llvm::ISD::TokenFactor
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
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:792
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:281
llvm::MVT::getIntegerVT
static MVT getIntegerVT(unsigned BitWidth)
Definition: MachineValueType.h:1100
llvm::ISD::OutputArg::IsFixed
bool IsFixed
IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
Definition: TargetCallingConv.h:234
INT64_MIN
#define INT64_MIN
Definition: DataTypes.h:74