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