LLVM  16.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.
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.
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
581  // having the function pointer added at the end of the params list, a zero
582  // (the index in
583  // __funcref_call_table is added).
584  if (IsFuncrefCall) {
585  Register RegZero =
586  MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
587  MachineInstrBuilder MIBC0 =
588  BuildMI(MF, DL, TII.get(WebAssembly::CONST_I32), RegZero).addImm(0);
589 
590  BB->insert(CallResults.getIterator(), MIBC0);
591  MachineInstrBuilder(MF, CallParams).addReg(RegZero);
592  } else
593  CallParams.addOperand(FnPtr);
594  }
595 
596  for (auto Def : CallResults.defs())
597  MIB.add(Def);
598 
599  if (IsIndirect) {
600  // Placeholder for the type index.
601  MIB.addImm(0);
602  // The table into which this call_indirect indexes.
603  MCSymbolWasm *Table = IsFuncrefCall
605  MF.getContext(), Subtarget)
607  MF.getContext(), Subtarget);
608  if (Subtarget->hasReferenceTypes()) {
609  MIB.addSym(Table);
610  } else {
611  // For the MVP there is at most one table whose number is 0, but we can't
612  // write a table symbol or issue relocations. Instead we just ensure the
613  // table is live and write a zero.
614  Table->setNoStrip();
615  MIB.addImm(0);
616  }
617  }
618 
619  for (auto Use : CallParams.uses())
620  MIB.add(Use);
621 
622  BB->insert(CallResults.getIterator(), MIB);
623  CallParams.eraseFromParent();
624  CallResults.eraseFromParent();
625 
626  // If this is a funcref call, to avoid hidden GC roots, we need to clear the
627  // table slot with ref.null upon call_indirect return.
628  //
629  // This generates the following code, which comes right after a call_indirect
630  // of a funcref:
631  //
632  // i32.const 0
633  // ref.null func
634  // table.set __funcref_call_table
635  if (IsIndirect && IsFuncrefCall) {
637  MF.getContext(), Subtarget);
638  Register RegZero =
639  MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
640  MachineInstr *Const0 =
641  BuildMI(MF, DL, TII.get(WebAssembly::CONST_I32), RegZero).addImm(0);
642  BB->insertAfter(MIB.getInstr()->getIterator(), Const0);
643 
644  Register RegFuncref =
645  MF.getRegInfo().createVirtualRegister(&WebAssembly::FUNCREFRegClass);
646  MachineInstr *RefNull =
647  BuildMI(MF, DL, TII.get(WebAssembly::REF_NULL_FUNCREF), RegFuncref);
648  BB->insertAfter(Const0->getIterator(), RefNull);
649 
650  MachineInstr *TableSet =
651  BuildMI(MF, DL, TII.get(WebAssembly::TABLE_SET_FUNCREF))
652  .addSym(Table)
653  .addReg(RegZero)
654  .addReg(RegFuncref);
655  BB->insertAfter(RefNull->getIterator(), TableSet);
656  }
657 
658  return BB;
659 }
660 
661 MachineBasicBlock *WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
662  MachineInstr &MI, MachineBasicBlock *BB) const {
663  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
664  DebugLoc DL = MI.getDebugLoc();
665 
666  switch (MI.getOpcode()) {
667  default:
668  llvm_unreachable("Unexpected instr type to insert");
669  case WebAssembly::FP_TO_SINT_I32_F32:
670  return LowerFPToInt(MI, DL, BB, TII, false, false, false,
671  WebAssembly::I32_TRUNC_S_F32);
672  case WebAssembly::FP_TO_UINT_I32_F32:
673  return LowerFPToInt(MI, DL, BB, TII, true, false, false,
674  WebAssembly::I32_TRUNC_U_F32);
675  case WebAssembly::FP_TO_SINT_I64_F32:
676  return LowerFPToInt(MI, DL, BB, TII, false, true, false,
677  WebAssembly::I64_TRUNC_S_F32);
678  case WebAssembly::FP_TO_UINT_I64_F32:
679  return LowerFPToInt(MI, DL, BB, TII, true, true, false,
680  WebAssembly::I64_TRUNC_U_F32);
681  case WebAssembly::FP_TO_SINT_I32_F64:
682  return LowerFPToInt(MI, DL, BB, TII, false, false, true,
683  WebAssembly::I32_TRUNC_S_F64);
684  case WebAssembly::FP_TO_UINT_I32_F64:
685  return LowerFPToInt(MI, DL, BB, TII, true, false, true,
686  WebAssembly::I32_TRUNC_U_F64);
687  case WebAssembly::FP_TO_SINT_I64_F64:
688  return LowerFPToInt(MI, DL, BB, TII, false, true, true,
689  WebAssembly::I64_TRUNC_S_F64);
690  case WebAssembly::FP_TO_UINT_I64_F64:
691  return LowerFPToInt(MI, DL, BB, TII, true, true, true,
692  WebAssembly::I64_TRUNC_U_F64);
693  case WebAssembly::CALL_RESULTS:
694  case WebAssembly::RET_CALL_RESULTS:
695  return LowerCallResults(MI, DL, BB, Subtarget, TII);
696  }
697 }
698 
699 const char *
700 WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {
701  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
704  break;
705 #define HANDLE_NODETYPE(NODE) \
706  case WebAssemblyISD::NODE: \
707  return "WebAssemblyISD::" #NODE;
708 #define HANDLE_MEM_NODETYPE(NODE) HANDLE_NODETYPE(NODE)
709 #include "WebAssemblyISD.def"
710 #undef HANDLE_MEM_NODETYPE
711 #undef HANDLE_NODETYPE
712  }
713  return nullptr;
714 }
715 
716 std::pair<unsigned, const TargetRegisterClass *>
717 WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
718  const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
719  // First, see if this is a constraint that directly corresponds to a
720  // WebAssembly register class.
721  if (Constraint.size() == 1) {
722  switch (Constraint[0]) {
723  case 'r':
724  assert(VT != MVT::iPTR && "Pointer MVT not expected here");
725  if (Subtarget->hasSIMD128() && VT.isVector()) {
726  if (VT.getSizeInBits() == 128)
727  return std::make_pair(0U, &WebAssembly::V128RegClass);
728  }
729  if (VT.isInteger() && !VT.isVector()) {
730  if (VT.getSizeInBits() <= 32)
731  return std::make_pair(0U, &WebAssembly::I32RegClass);
732  if (VT.getSizeInBits() <= 64)
733  return std::make_pair(0U, &WebAssembly::I64RegClass);
734  }
735  if (VT.isFloatingPoint() && !VT.isVector()) {
736  switch (VT.getSizeInBits()) {
737  case 32:
738  return std::make_pair(0U, &WebAssembly::F32RegClass);
739  case 64:
740  return std::make_pair(0U, &WebAssembly::F64RegClass);
741  default:
742  break;
743  }
744  }
745  break;
746  default:
747  break;
748  }
749  }
750 
751  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
752 }
753 
754 bool WebAssemblyTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
755  // Assume ctz is a relatively cheap operation.
756  return true;
757 }
758 
759 bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {
760  // Assume clz is a relatively cheap operation.
761  return true;
762 }
763 
764 bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL,
765  const AddrMode &AM,
766  Type *Ty, unsigned AS,
767  Instruction *I) const {
768  // WebAssembly offsets are added as unsigned without wrapping. The
769  // isLegalAddressingMode gives us no way to determine if wrapping could be
770  // happening, so we approximate this by accepting only non-negative offsets.
771  if (AM.BaseOffs < 0)
772  return false;
773 
774  // WebAssembly has no scale register operands.
775  if (AM.Scale != 0)
776  return false;
777 
778  // Everything else is legal.
779  return true;
780 }
781 
782 bool WebAssemblyTargetLowering::allowsMisalignedMemoryAccesses(
783  EVT /*VT*/, unsigned /*AddrSpace*/, Align /*Align*/,
784  MachineMemOperand::Flags /*Flags*/, bool *Fast) const {
785  // WebAssembly supports unaligned accesses, though it should be declared
786  // with the p2align attribute on loads and stores which do so, and there
787  // may be a performance impact. We tell LLVM they're "fast" because
788  // for the kinds of things that LLVM uses this for (merging adjacent stores
789  // of constants, etc.), WebAssembly implementations will either want the
790  // unaligned access or they'll split anyway.
791  if (Fast)
792  *Fast = true;
793  return true;
794 }
795 
796 bool WebAssemblyTargetLowering::isIntDivCheap(EVT VT,
797  AttributeList Attr) const {
798  // The current thinking is that wasm engines will perform this optimization,
799  // so we can save on code size.
800  return true;
801 }
802 
803 bool WebAssemblyTargetLowering::isVectorLoadExtDesirable(SDValue ExtVal) const {
804  EVT ExtT = ExtVal.getValueType();
805  EVT MemT = cast<LoadSDNode>(ExtVal->getOperand(0))->getValueType(0);
806  return (ExtT == MVT::v8i16 && MemT == MVT::v8i8) ||
807  (ExtT == MVT::v4i32 && MemT == MVT::v4i16) ||
808  (ExtT == MVT::v2i64 && MemT == MVT::v2i32);
809 }
810 
811 bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
812  const GlobalAddressSDNode *GA) const {
813  // Wasm doesn't support function addresses with offsets
814  const GlobalValue *GV = GA->getGlobal();
815  return isa<Function>(GV) ? false : TargetLowering::isOffsetFoldingLegal(GA);
816 }
817 
818 EVT WebAssemblyTargetLowering::getSetCCResultType(const DataLayout &DL,
819  LLVMContext &C,
820  EVT VT) const {
821  if (VT.isVector())
823 
824  // So far, all branch instructions in Wasm take an I32 condition.
825  // The default TargetLowering::getSetCCResultType returns the pointer size,
826  // which would be useful to reduce instruction counts when testing
827  // against 64-bit pointers/values if at some point Wasm supports that.
828  return EVT::getIntegerVT(C, 32);
829 }
830 
831 bool WebAssemblyTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
832  const CallInst &I,
833  MachineFunction &MF,
834  unsigned Intrinsic) const {
835  switch (Intrinsic) {
836  case Intrinsic::wasm_memory_atomic_notify:
838  Info.memVT = MVT::i32;
839  Info.ptrVal = I.getArgOperand(0);
840  Info.offset = 0;
841  Info.align = Align(4);
842  // atomic.notify instruction does not really load the memory specified with
843  // this argument, but MachineMemOperand should either be load or store, so
844  // we set this to a load.
845  // FIXME Volatile isn't really correct, but currently all LLVM atomic
846  // instructions are treated as volatiles in the backend, so we should be
847  // consistent. The same applies for wasm_atomic_wait intrinsics too.
849  return true;
850  case Intrinsic::wasm_memory_atomic_wait32:
852  Info.memVT = MVT::i32;
853  Info.ptrVal = I.getArgOperand(0);
854  Info.offset = 0;
855  Info.align = Align(4);
857  return true;
858  case Intrinsic::wasm_memory_atomic_wait64:
860  Info.memVT = MVT::i64;
861  Info.ptrVal = I.getArgOperand(0);
862  Info.offset = 0;
863  Info.align = Align(8);
865  return true;
866  default:
867  return false;
868  }
869 }
870 
871 void WebAssemblyTargetLowering::computeKnownBitsForTargetNode(
872  const SDValue Op, KnownBits &Known, const APInt &DemandedElts,
873  const SelectionDAG &DAG, unsigned Depth) const {
874  switch (Op.getOpcode()) {
875  default:
876  break;
878  unsigned IntNo = Op.getConstantOperandVal(0);
879  switch (IntNo) {
880  default:
881  break;
882  case Intrinsic::wasm_bitmask: {
883  unsigned BitWidth = Known.getBitWidth();
884  EVT VT = Op.getOperand(1).getSimpleValueType();
885  unsigned PossibleBits = VT.getVectorNumElements();
886  APInt ZeroMask = APInt::getHighBitsSet(BitWidth, BitWidth - PossibleBits);
887  Known.Zero |= ZeroMask;
888  break;
889  }
890  }
891  }
892  }
893 }
894 
896 WebAssemblyTargetLowering::getPreferredVectorAction(MVT VT) const {
897  if (VT.isFixedLengthVector()) {
898  MVT EltVT = VT.getVectorElementType();
899  // We have legal vector types with these lane types, so widening the
900  // vector would let us use some of the lanes directly without having to
901  // extend or truncate values.
902  if (EltVT == MVT::i8 || EltVT == MVT::i16 || EltVT == MVT::i32 ||
903  EltVT == MVT::i64 || EltVT == MVT::f32 || EltVT == MVT::f64)
904  return TypeWidenVector;
905  }
906 
908 }
909 
910 bool WebAssemblyTargetLowering::shouldSimplifyDemandedVectorElts(
911  SDValue Op, const TargetLoweringOpt &TLO) const {
912  // ISel process runs DAGCombiner after legalization; this step is called
913  // SelectionDAG optimization phase. This post-legalization combining process
914  // runs DAGCombiner on each node, and if there was a change to be made,
915  // re-runs legalization again on it and its user nodes to make sure
916  // everythiing is in a legalized state.
917  //
918  // The legalization calls lowering routines, and we do our custom lowering for
919  // build_vectors (LowerBUILD_VECTOR), which converts undef vector elements
920  // into zeros. But there is a set of routines in DAGCombiner that turns unused
921  // (= not demanded) nodes into undef, among which SimplifyDemandedVectorElts
922  // turns unused vector elements into undefs. But this routine does not work
923  // with our custom LowerBUILD_VECTOR, which turns undefs into zeros. This
924  // combination can result in a infinite loop, in which undefs are converted to
925  // zeros in legalization and back to undefs in combining.
926  //
927  // So after DAG is legalized, we prevent SimplifyDemandedVectorElts from
928  // running for build_vectors.
929  if (Op.getOpcode() == ISD::BUILD_VECTOR && TLO.LegalOps && TLO.LegalTys)
930  return false;
931  return true;
932 }
933 
934 //===----------------------------------------------------------------------===//
935 // WebAssembly Lowering private implementation.
936 //===----------------------------------------------------------------------===//
937 
938 //===----------------------------------------------------------------------===//
939 // Lowering Code
940 //===----------------------------------------------------------------------===//
941 
942 static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *Msg) {
944  DAG.getContext()->diagnose(
945  DiagnosticInfoUnsupported(MF.getFunction(), Msg, DL.getDebugLoc()));
946 }
947 
948 // Test whether the given calling convention is supported.
949 static bool callingConvSupported(CallingConv::ID CallConv) {
950  // We currently support the language-independent target-independent
951  // conventions. We don't yet have a way to annotate calls with properties like
952  // "cold", and we don't have any call-clobbered registers, so these are mostly
953  // all handled the same.
954  return CallConv == CallingConv::C || CallConv == CallingConv::Fast ||
955  CallConv == CallingConv::Cold ||
956  CallConv == CallingConv::PreserveMost ||
957  CallConv == CallingConv::PreserveAll ||
958  CallConv == CallingConv::CXX_FAST_TLS ||
960  CallConv == CallingConv::Swift;
961 }
962 
963 SDValue
964 WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
965  SmallVectorImpl<SDValue> &InVals) const {
966  SelectionDAG &DAG = CLI.DAG;
967  SDLoc DL = CLI.DL;
968  SDValue Chain = CLI.Chain;
969  SDValue Callee = CLI.Callee;
971  auto Layout = MF.getDataLayout();
972 
973  CallingConv::ID CallConv = CLI.CallConv;
974  if (!callingConvSupported(CallConv))
975  fail(DL, DAG,
976  "WebAssembly doesn't support language-specific or target-specific "
977  "calling conventions yet");
978  if (CLI.IsPatchPoint)
979  fail(DL, DAG, "WebAssembly doesn't support patch point yet");
980 
981  if (CLI.IsTailCall) {
982  auto NoTail = [&](const char *Msg) {
983  if (CLI.CB && CLI.CB->isMustTailCall())
984  fail(DL, DAG, Msg);
985  CLI.IsTailCall = false;
986  };
987 
988  if (!Subtarget->hasTailCall())
989  NoTail("WebAssembly 'tail-call' feature not enabled");
990 
991  // Varargs calls cannot be tail calls because the buffer is on the stack
992  if (CLI.IsVarArg)
993  NoTail("WebAssembly does not support varargs tail calls");
994 
995  // Do not tail call unless caller and callee return types match
996  const Function &F = MF.getFunction();
997  const TargetMachine &TM = getTargetMachine();
998  Type *RetTy = F.getReturnType();
999  SmallVector<MVT, 4> CallerRetTys;
1000  SmallVector<MVT, 4> CalleeRetTys;
1001  computeLegalValueVTs(F, TM, RetTy, CallerRetTys);
1002  computeLegalValueVTs(F, TM, CLI.RetTy, CalleeRetTys);
1003  bool TypesMatch = CallerRetTys.size() == CalleeRetTys.size() &&
1004  std::equal(CallerRetTys.begin(), CallerRetTys.end(),
1005  CalleeRetTys.begin());
1006  if (!TypesMatch)
1007  NoTail("WebAssembly tail call requires caller and callee return types to "
1008  "match");
1009 
1010  // If pointers to local stack values are passed, we cannot tail call
1011  if (CLI.CB) {
1012  for (auto &Arg : CLI.CB->args()) {
1013  Value *Val = Arg.get();
1014  // Trace the value back through pointer operations
1015  while (true) {
1016  Value *Src = Val->stripPointerCastsAndAliases();
1017  if (auto *GEP = dyn_cast<GetElementPtrInst>(Src))
1018  Src = GEP->getPointerOperand();
1019  if (Val == Src)
1020  break;
1021  Val = Src;
1022  }
1023  if (isa<AllocaInst>(Val)) {
1024  NoTail(
1025  "WebAssembly does not support tail calling with stack arguments");
1026  break;
1027  }
1028  }
1029  }
1030  }
1031 
1033  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
1034  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
1035 
1036  // The generic code may have added an sret argument. If we're lowering an
1037  // invoke function, the ABI requires that the function pointer be the first
1038  // argument, so we may have to swap the arguments.
1039  if (CallConv == CallingConv::WASM_EmscriptenInvoke && Outs.size() >= 2 &&
1040  Outs[0].Flags.isSRet()) {
1041  std::swap(Outs[0], Outs[1]);
1042  std::swap(OutVals[0], OutVals[1]);
1043  }
1044 
1045  bool HasSwiftSelfArg = false;
1046  bool HasSwiftErrorArg = false;
1047  unsigned NumFixedArgs = 0;
1048  for (unsigned I = 0; I < Outs.size(); ++I) {
1049  const ISD::OutputArg &Out = Outs[I];
1050  SDValue &OutVal = OutVals[I];
1051  HasSwiftSelfArg |= Out.Flags.isSwiftSelf();
1052  HasSwiftErrorArg |= Out.Flags.isSwiftError();
1053  if (Out.Flags.isNest())
1054  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
1055  if (Out.Flags.isInAlloca())
1056  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
1057  if (Out.Flags.isInConsecutiveRegs())
1058  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
1059  if (Out.Flags.isInConsecutiveRegsLast())
1060  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
1061  if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
1062  auto &MFI = MF.getFrameInfo();
1063  int FI = MFI.CreateStackObject(Out.Flags.getByValSize(),
1065  /*isSS=*/false);
1066  SDValue SizeNode =
1067  DAG.getConstant(Out.Flags.getByValSize(), DL, MVT::i32);
1068  SDValue FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
1069  Chain = DAG.getMemcpy(
1070  Chain, DL, FINode, OutVal, SizeNode, Out.Flags.getNonZeroByValAlign(),
1071  /*isVolatile*/ false, /*AlwaysInline=*/false,
1072  /*isTailCall*/ false, MachinePointerInfo(), MachinePointerInfo());
1073  OutVal = FINode;
1074  }
1075  // Count the number of fixed args *after* legalization.
1076  NumFixedArgs += Out.IsFixed;
1077  }
1078 
1079  bool IsVarArg = CLI.IsVarArg;
1080  auto PtrVT = getPointerTy(Layout);
1081 
1082  // For swiftcc, emit additional swiftself and swifterror arguments
1083  // if there aren't. These additional arguments are also added for callee
1084  // signature They are necessary to match callee and caller signature for
1085  // indirect call.
1086  if (CallConv == CallingConv::Swift) {
1087  if (!HasSwiftSelfArg) {
1088  NumFixedArgs++;
1090  Arg.Flags.setSwiftSelf();
1091  CLI.Outs.push_back(Arg);
1092  SDValue ArgVal = DAG.getUNDEF(PtrVT);
1093  CLI.OutVals.push_back(ArgVal);
1094  }
1095  if (!HasSwiftErrorArg) {
1096  NumFixedArgs++;
1098  Arg.Flags.setSwiftError();
1099  CLI.Outs.push_back(Arg);
1100  SDValue ArgVal = DAG.getUNDEF(PtrVT);
1101  CLI.OutVals.push_back(ArgVal);
1102  }
1103  }
1104 
1105  // Analyze operands of the call, assigning locations to each operand.
1107  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
1108 
1109  if (IsVarArg) {
1110  // Outgoing non-fixed arguments are placed in a buffer. First
1111  // compute their offsets and the total amount of buffer space needed.
1112  for (unsigned I = NumFixedArgs; I < Outs.size(); ++I) {
1113  const ISD::OutputArg &Out = Outs[I];
1114  SDValue &Arg = OutVals[I];
1115  EVT VT = Arg.getValueType();
1116  assert(VT != MVT::iPTR && "Legalized args should be concrete");
1117  Type *Ty = VT.getTypeForEVT(*DAG.getContext());
1118  Align Alignment =
1119  std::max(Out.Flags.getNonZeroOrigAlign(), Layout.getABITypeAlign(Ty));
1120  unsigned Offset =
1121  CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty), Alignment);
1122  CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(),
1123  Offset, VT.getSimpleVT(),
1125  }
1126  }
1127 
1128  unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
1129 
1130  SDValue FINode;
1131  if (IsVarArg && NumBytes) {
1132  // For non-fixed arguments, next emit stores to store the argument values
1133  // to the stack buffer at the offsets computed above.
1134  int FI = MF.getFrameInfo().CreateStackObject(NumBytes,
1135  Layout.getStackAlignment(),
1136  /*isSS=*/false);
1137  unsigned ValNo = 0;
1138  SmallVector<SDValue, 8> Chains;
1139  for (SDValue Arg : drop_begin(OutVals, NumFixedArgs)) {
1140  assert(ArgLocs[ValNo].getValNo() == ValNo &&
1141  "ArgLocs should remain in order and only hold varargs args");
1142  unsigned Offset = ArgLocs[ValNo++].getLocMemOffset();
1143  FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
1144  SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, FINode,
1145  DAG.getConstant(Offset, DL, PtrVT));
1146  Chains.push_back(
1147  DAG.getStore(Chain, DL, Arg, Add,
1148  MachinePointerInfo::getFixedStack(MF, FI, Offset)));
1149  }
1150  if (!Chains.empty())
1151  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
1152  } else if (IsVarArg) {
1153  FINode = DAG.getIntPtrConstant(0, DL);
1154  }
1155 
1156  if (Callee->getOpcode() == ISD::GlobalAddress) {
1157  // If the callee is a GlobalAddress node (quite common, every direct call
1158  // is) turn it into a TargetGlobalAddress node so that LowerGlobalAddress
1159  // doesn't at MO_GOT which is not needed for direct calls.
1160  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Callee);
1162  getPointerTy(DAG.getDataLayout()),
1163  GA->getOffset());
1165  getPointerTy(DAG.getDataLayout()), Callee);
1166  }
1167 
1168  // Compute the operands for the CALLn node.
1170  Ops.push_back(Chain);
1171  Ops.push_back(Callee);
1172 
1173  // Add all fixed arguments. Note that for non-varargs calls, NumFixedArgs
1174  // isn't reliable.
1175  Ops.append(OutVals.begin(),
1176  IsVarArg ? OutVals.begin() + NumFixedArgs : OutVals.end());
1177  // Add a pointer to the vararg buffer.
1178  if (IsVarArg)
1179  Ops.push_back(FINode);
1180 
1181  SmallVector<EVT, 8> InTys;
1182  for (const auto &In : Ins) {
1183  assert(!In.Flags.isByVal() && "byval is not valid for return values");
1184  assert(!In.Flags.isNest() && "nest is not valid for return values");
1185  if (In.Flags.isInAlloca())
1186  fail(DL, DAG, "WebAssembly hasn't implemented inalloca return values");
1187  if (In.Flags.isInConsecutiveRegs())
1188  fail(DL, DAG, "WebAssembly hasn't implemented cons regs return values");
1189  if (In.Flags.isInConsecutiveRegsLast())
1190  fail(DL, DAG,
1191  "WebAssembly hasn't implemented cons regs last return values");
1192  // Ignore In.getNonZeroOrigAlign() because all our arguments are passed in
1193  // registers.
1194  InTys.push_back(In.VT);
1195  }
1196 
1197  // Lastly, if this is a call to a funcref we need to add an instruction
1198  // table.set to the chain and transform the call.
1199  if (CLI.CB &&
1200  WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) {
1201  // In the absence of function references proposal where a funcref call is
1202  // lowered to call_ref, using reference types we generate a table.set to set
1203  // the funcref to a special table used solely for this purpose, followed by
1204  // a call_indirect. Here we just generate the table set, and return the
1205  // SDValue of the table.set so that LowerCall can finalize the lowering by
1206  // generating the call_indirect.
1207  SDValue Chain = Ops[0];
1208 
1210  MF.getContext(), Subtarget);
1211  SDValue Sym = DAG.getMCSymbol(Table, PtrVT);
1212  SDValue TableSlot = DAG.getConstant(0, DL, MVT::i32);
1213  SDValue TableSetOps[] = {Chain, Sym, TableSlot, Callee};
1214  SDValue TableSet = DAG.getMemIntrinsicNode(
1215  WebAssemblyISD::TABLE_SET, DL, DAG.getVTList(MVT::Other), TableSetOps,
1216  MVT::funcref,
1217  // Machine Mem Operand args
1220  CLI.CB->getCalledOperand()->getPointerAlignment(DAG.getDataLayout()),
1222 
1223  Ops[0] = TableSet; // The new chain is the TableSet itself
1224  }
1225 
1226  if (CLI.IsTailCall) {
1227  // ret_calls do not return values to the current frame
1228  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1229  return DAG.getNode(WebAssemblyISD::RET_CALL, DL, NodeTys, Ops);
1230  }
1231 
1232  InTys.push_back(MVT::Other);
1233  SDVTList InTyList = DAG.getVTList(InTys);
1234  SDValue Res = DAG.getNode(WebAssemblyISD::CALL, DL, InTyList, Ops);
1235 
1236  for (size_t I = 0; I < Ins.size(); ++I)
1237  InVals.push_back(Res.getValue(I));
1238 
1239  // Return the chain
1240  return Res.getValue(Ins.size());
1241 }
1242 
1243 bool WebAssemblyTargetLowering::CanLowerReturn(
1244  CallingConv::ID /*CallConv*/, MachineFunction & /*MF*/, bool /*IsVarArg*/,
1245  const SmallVectorImpl<ISD::OutputArg> &Outs,
1246  LLVMContext & /*Context*/) const {
1247  // WebAssembly can only handle returning tuples with multivalue enabled
1248  return Subtarget->hasMultivalue() || Outs.size() <= 1;
1249 }
1250 
1251 SDValue WebAssemblyTargetLowering::LowerReturn(
1252  SDValue Chain, CallingConv::ID CallConv, bool /*IsVarArg*/,
1253  const SmallVectorImpl<ISD::OutputArg> &Outs,
1254  const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
1255  SelectionDAG &DAG) const {
1256  assert((Subtarget->hasMultivalue() || Outs.size() <= 1) &&
1257  "MVP WebAssembly can only return up to one value");
1258  if (!callingConvSupported(CallConv))
1259  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
1260 
1261  SmallVector<SDValue, 4> RetOps(1, Chain);
1262  RetOps.append(OutVals.begin(), OutVals.end());
1263  Chain = DAG.getNode(WebAssemblyISD::RETURN, DL, MVT::Other, RetOps);
1264 
1265  // Record the number and types of the return values.
1266  for (const ISD::OutputArg &Out : Outs) {
1267  assert(!Out.Flags.isByVal() && "byval is not valid for return values");
1268  assert(!Out.Flags.isNest() && "nest is not valid for return values");
1269  assert(Out.IsFixed && "non-fixed return value is not valid");
1270  if (Out.Flags.isInAlloca())
1271  fail(DL, DAG, "WebAssembly hasn't implemented inalloca results");
1272  if (Out.Flags.isInConsecutiveRegs())
1273  fail(DL, DAG, "WebAssembly hasn't implemented cons regs results");
1274  if (Out.Flags.isInConsecutiveRegsLast())
1275  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results");
1276  }
1277 
1278  return Chain;
1279 }
1280 
1281 SDValue WebAssemblyTargetLowering::LowerFormalArguments(
1282  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
1283  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
1284  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
1285  if (!callingConvSupported(CallConv))
1286  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
1287 
1288  MachineFunction &MF = DAG.getMachineFunction();
1289  auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
1290 
1291  // Set up the incoming ARGUMENTS value, which serves to represent the liveness
1292  // of the incoming values before they're represented by virtual registers.
1293  MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
1294 
1295  bool HasSwiftErrorArg = false;
1296  bool HasSwiftSelfArg = false;
1297  for (const ISD::InputArg &In : Ins) {
1298  HasSwiftSelfArg |= In.Flags.isSwiftSelf();
1299  HasSwiftErrorArg |= In.Flags.isSwiftError();
1300  if (In.Flags.isInAlloca())
1301  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
1302  if (In.Flags.isNest())
1303  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
1304  if (In.Flags.isInConsecutiveRegs())
1305  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
1306  if (In.Flags.isInConsecutiveRegsLast())
1307  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
1308  // Ignore In.getNonZeroOrigAlign() because all our arguments are passed in
1309  // registers.
1310  InVals.push_back(In.Used ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
1311  DAG.getTargetConstant(InVals.size(),
1312  DL, MVT::i32))
1313  : DAG.getUNDEF(In.VT));
1314 
1315  // Record the number and types of arguments.
1316  MFI->addParam(In.VT);
1317  }
1318 
1319  // For swiftcc, emit additional swiftself and swifterror arguments
1320  // if there aren't. These additional arguments are also added for callee
1321  // signature They are necessary to match callee and caller signature for
1322  // indirect call.
1323  auto PtrVT = getPointerTy(MF.getDataLayout());
1324  if (CallConv == CallingConv::Swift) {
1325  if (!HasSwiftSelfArg) {
1326  MFI->addParam(PtrVT);
1327  }
1328  if (!HasSwiftErrorArg) {
1329  MFI->addParam(PtrVT);
1330  }
1331  }
1332  // Varargs are copied into a buffer allocated by the caller, and a pointer to
1333  // the buffer is passed as an argument.
1334  if (IsVarArg) {
1335  MVT PtrVT = getPointerTy(MF.getDataLayout());
1336  Register VarargVreg =
1338  MFI->setVarargBufferVreg(VarargVreg);
1339  Chain = DAG.getCopyToReg(
1340  Chain, DL, VarargVreg,
1341  DAG.getNode(WebAssemblyISD::ARGUMENT, DL, PtrVT,
1342  DAG.getTargetConstant(Ins.size(), DL, MVT::i32)));
1343  MFI->addParam(PtrVT);
1344  }
1345 
1346  // Record the number and types of arguments and results.
1347  SmallVector<MVT, 4> Params;
1350  MF.getFunction(), DAG.getTarget(), Params, Results);
1351  for (MVT VT : Results)
1352  MFI->addResult(VT);
1353  // TODO: Use signatures in WebAssemblyMachineFunctionInfo too and unify
1354  // the param logic here with ComputeSignatureVTs
1355  assert(MFI->getParams().size() == Params.size() &&
1356  std::equal(MFI->getParams().begin(), MFI->getParams().end(),
1357  Params.begin()));
1358 
1359  return Chain;
1360 }
1361 
1362 void WebAssemblyTargetLowering::ReplaceNodeResults(
1364  switch (N->getOpcode()) {
1366  // Do not add any results, signifying that N should not be custom lowered
1367  // after all. This happens because simd128 turns on custom lowering for
1368  // SIGN_EXTEND_INREG, but for non-vector sign extends the result might be an
1369  // illegal type.
1370  break;
1371  default:
1373  "ReplaceNodeResults not implemented for this op for WebAssembly!");
1374  }
1375 }
1376 
1377 //===----------------------------------------------------------------------===//
1378 // Custom lowering hooks.
1379 //===----------------------------------------------------------------------===//
1380 
1381 SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
1382  SelectionDAG &DAG) const {
1383  SDLoc DL(Op);
1384  switch (Op.getOpcode()) {
1385  default:
1386  llvm_unreachable("unimplemented operation lowering");
1387  return SDValue();
1388  case ISD::FrameIndex:
1389  return LowerFrameIndex(Op, DAG);
1390  case ISD::GlobalAddress:
1391  return LowerGlobalAddress(Op, DAG);
1392  case ISD::GlobalTLSAddress:
1393  return LowerGlobalTLSAddress(Op, DAG);
1394  case ISD::ExternalSymbol:
1395  return LowerExternalSymbol(Op, DAG);
1396  case ISD::JumpTable:
1397  return LowerJumpTable(Op, DAG);
1398  case ISD::BR_JT:
1399  return LowerBR_JT(Op, DAG);
1400  case ISD::VASTART:
1401  return LowerVASTART(Op, DAG);
1402  case ISD::BlockAddress:
1403  case ISD::BRIND:
1404  fail(DL, DAG, "WebAssembly hasn't implemented computed gotos");
1405  return SDValue();
1406  case ISD::RETURNADDR:
1407  return LowerRETURNADDR(Op, DAG);
1408  case ISD::FRAMEADDR:
1409  return LowerFRAMEADDR(Op, DAG);
1410  case ISD::CopyToReg:
1411  return LowerCopyToReg(Op, DAG);
1414  return LowerAccessVectorElement(Op, DAG);
1415  case ISD::INTRINSIC_VOID:
1418  return LowerIntrinsic(Op, DAG);
1420  return LowerSIGN_EXTEND_INREG(Op, DAG);
1421  case ISD::BUILD_VECTOR:
1422  return LowerBUILD_VECTOR(Op, DAG);
1423  case ISD::VECTOR_SHUFFLE:
1424  return LowerVECTOR_SHUFFLE(Op, DAG);
1425  case ISD::SETCC:
1426  return LowerSETCC(Op, DAG);
1427  case ISD::SHL:
1428  case ISD::SRA:
1429  case ISD::SRL:
1430  return LowerShift(Op, DAG);
1431  case ISD::FP_TO_SINT_SAT:
1432  case ISD::FP_TO_UINT_SAT:
1433  return LowerFP_TO_INT_SAT(Op, DAG);
1434  case ISD::LOAD:
1435  return LowerLoad(Op, DAG);
1436  case ISD::STORE:
1437  return LowerStore(Op, DAG);
1438  case ISD::CTPOP:
1439  case ISD::CTLZ:
1440  case ISD::CTTZ:
1441  return DAG.UnrollVectorOp(Op.getNode());
1442  }
1443 }
1444 
1446  if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op))
1448 
1449  return false;
1450 }
1451 
1453  const FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op);
1454  if (!FI)
1455  return None;
1456 
1457  auto &MF = DAG.getMachineFunction();
1459 }
1460 
1461 SDValue WebAssemblyTargetLowering::LowerStore(SDValue Op,
1462  SelectionDAG &DAG) const {
1463  SDLoc DL(Op);
1464  StoreSDNode *SN = cast<StoreSDNode>(Op.getNode());
1465  const SDValue &Value = SN->getValue();
1466  const SDValue &Base = SN->getBasePtr();
1467  const SDValue &Offset = SN->getOffset();
1468 
1469  if (IsWebAssemblyGlobal(Base)) {
1470  if (!Offset->isUndef())
1471  report_fatal_error("unexpected offset when storing to webassembly global",
1472  false);
1473 
1474  SDVTList Tys = DAG.getVTList(MVT::Other);
1475  SDValue Ops[] = {SN->getChain(), Value, Base};
1476  return DAG.getMemIntrinsicNode(WebAssemblyISD::GLOBAL_SET, DL, Tys, Ops,
1477  SN->getMemoryVT(), SN->getMemOperand());
1478  }
1479 
1480  if (Optional<unsigned> Local = IsWebAssemblyLocal(Base, DAG)) {
1481  if (!Offset->isUndef())
1482  report_fatal_error("unexpected offset when storing to webassembly local",
1483  false);
1484 
1485  SDValue Idx = DAG.getTargetConstant(*Local, Base, MVT::i32);
1486  SDVTList Tys = DAG.getVTList(MVT::Other); // The chain.
1487  SDValue Ops[] = {SN->getChain(), Idx, Value};
1488  return DAG.getNode(WebAssemblyISD::LOCAL_SET, DL, Tys, Ops);
1489  }
1490 
1493  "Encountered an unlowerable store to the wasm_var address space",
1494  false);
1495 
1496  return Op;
1497 }
1498 
1499 SDValue WebAssemblyTargetLowering::LowerLoad(SDValue Op,
1500  SelectionDAG &DAG) const {
1501  SDLoc DL(Op);
1502  LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
1503  const SDValue &Base = LN->getBasePtr();
1504  const SDValue &Offset = LN->getOffset();
1505 
1506  if (IsWebAssemblyGlobal(Base)) {
1507  if (!Offset->isUndef())
1509  "unexpected offset when loading from webassembly global", false);
1510 
1511  SDVTList Tys = DAG.getVTList(LN->getValueType(0), MVT::Other);
1512  SDValue Ops[] = {LN->getChain(), Base};
1513  return DAG.getMemIntrinsicNode(WebAssemblyISD::GLOBAL_GET, DL, Tys, Ops,
1514  LN->getMemoryVT(), LN->getMemOperand());
1515  }
1516 
1517  if (Optional<unsigned> Local = IsWebAssemblyLocal(Base, DAG)) {
1518  if (!Offset->isUndef())
1520  "unexpected offset when loading from webassembly local", false);
1521 
1522  SDValue Idx = DAG.getTargetConstant(*Local, Base, MVT::i32);
1523  EVT LocalVT = LN->getValueType(0);
1524  SDValue LocalGet = DAG.getNode(WebAssemblyISD::LOCAL_GET, DL, LocalVT,
1525  {LN->getChain(), Idx});
1526  SDValue Result = DAG.getMergeValues({LocalGet, LN->getChain()}, DL);
1527  assert(Result->getNumValues() == 2 && "Loads must carry a chain!");
1528  return Result;
1529  }
1530 
1533  "Encountered an unlowerable load from the wasm_var address space",
1534  false);
1535 
1536  return Op;
1537 }
1538 
1539 SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op,
1540  SelectionDAG &DAG) const {
1541  SDValue Src = Op.getOperand(2);
1542  if (isa<FrameIndexSDNode>(Src.getNode())) {
1543  // CopyToReg nodes don't support FrameIndex operands. Other targets select
1544  // the FI to some LEA-like instruction, but since we don't have that, we
1545  // need to insert some kind of instruction that can take an FI operand and
1546  // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
1547  // local.copy between Op and its FI operand.
1548  SDValue Chain = Op.getOperand(0);
1549  SDLoc DL(Op);
1550  Register Reg = cast<RegisterSDNode>(Op.getOperand(1))->getReg();
1551  EVT VT = Src.getValueType();
1552  SDValue Copy(DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_I32
1553  : WebAssembly::COPY_I64,
1554  DL, VT, Src),
1555  0);
1556  return Op.getNode()->getNumValues() == 1
1557  ? DAG.getCopyToReg(Chain, DL, Reg, Copy)
1558  : DAG.getCopyToReg(Chain, DL, Reg, Copy,
1559  Op.getNumOperands() == 4 ? Op.getOperand(3)
1560  : SDValue());
1561  }
1562  return SDValue();
1563 }
1564 
1565 SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op,
1566  SelectionDAG &DAG) const {
1567  int FI = cast<FrameIndexSDNode>(Op)->getIndex();
1568  return DAG.getTargetFrameIndex(FI, Op.getValueType());
1569 }
1570 
1571 SDValue WebAssemblyTargetLowering::LowerRETURNADDR(SDValue Op,
1572  SelectionDAG &DAG) const {
1573  SDLoc DL(Op);
1574 
1575  if (!Subtarget->getTargetTriple().isOSEmscripten()) {
1576  fail(DL, DAG,
1577  "Non-Emscripten WebAssembly hasn't implemented "
1578  "__builtin_return_address");
1579  return SDValue();
1580  }
1581 
1583  return SDValue();
1584 
1585  unsigned Depth = Op.getConstantOperandVal(0);
1586  MakeLibCallOptions CallOptions;
1587  return makeLibCall(DAG, RTLIB::RETURN_ADDRESS, Op.getValueType(),
1588  {DAG.getConstant(Depth, DL, MVT::i32)}, CallOptions, DL)
1589  .first;
1590 }
1591 
1592 SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op,
1593  SelectionDAG &DAG) const {
1594  // Non-zero depths are not supported by WebAssembly currently. Use the
1595  // legalizer's default expansion, which is to return 0 (what this function is
1596  // documented to do).
1597  if (Op.getConstantOperandVal(0) > 0)
1598  return SDValue();
1599 
1601  EVT VT = Op.getValueType();
1602  Register FP =
1604  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT);
1605 }
1606 
1607 SDValue
1608 WebAssemblyTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1609  SelectionDAG &DAG) const {
1610  SDLoc DL(Op);
1611  const auto *GA = cast<GlobalAddressSDNode>(Op);
1612 
1613  MachineFunction &MF = DAG.getMachineFunction();
1615  report_fatal_error("cannot use thread-local storage without bulk memory",
1616  false);
1617 
1618  const GlobalValue *GV = GA->getGlobal();
1619 
1620  // Currently only Emscripten supports dynamic linking with threads. Therefore,
1621  // on other targets, if we have thread-local storage, only the local-exec
1622  // model is possible.
1623  auto model = Subtarget->getTargetTriple().isOSEmscripten()
1624  ? GV->getThreadLocalMode()
1626 
1627  // Unsupported TLS modes
1630 
1634  getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))) {
1635  // For DSO-local TLS variables we use offset from __tls_base
1636 
1637  MVT PtrVT = getPointerTy(DAG.getDataLayout());
1638  auto GlobalGet = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64
1639  : WebAssembly::GLOBAL_GET_I32;
1640  const char *BaseName = MF.createExternalSymbolName("__tls_base");
1641 
1642  SDValue BaseAddr(
1643  DAG.getMachineNode(GlobalGet, DL, PtrVT,
1644  DAG.getTargetExternalSymbol(BaseName, PtrVT)),
1645  0);
1646 
1647  SDValue TLSOffset = DAG.getTargetGlobalAddress(
1648  GV, DL, PtrVT, GA->getOffset(), WebAssemblyII::MO_TLS_BASE_REL);
1649  SDValue SymOffset =
1650  DAG.getNode(WebAssemblyISD::WrapperREL, DL, PtrVT, TLSOffset);
1651 
1652  return DAG.getNode(ISD::ADD, DL, PtrVT, BaseAddr, SymOffset);
1653  }
1654 
1656 
1657  EVT VT = Op.getValueType();
1658  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1659  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
1660  GA->getOffset(),
1662 }
1663 
1664 SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
1665  SelectionDAG &DAG) const {
1666  SDLoc DL(Op);
1667  const auto *GA = cast<GlobalAddressSDNode>(Op);
1668  EVT VT = Op.getValueType();
1669  assert(GA->getTargetFlags() == 0 &&
1670  "Unexpected target flags on generic GlobalAddressSDNode");
1672  fail(DL, DAG, "Invalid address space for WebAssembly target");
1673 
1674  unsigned OperandFlags = 0;
1675  if (isPositionIndependent()) {
1676  const GlobalValue *GV = GA->getGlobal();
1677  if (getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV)) {
1678  MachineFunction &MF = DAG.getMachineFunction();
1679  MVT PtrVT = getPointerTy(MF.getDataLayout());
1680  const char *BaseName;
1681  if (GV->getValueType()->isFunctionTy()) {
1682  BaseName = MF.createExternalSymbolName("__table_base");
1684  } else {
1685  BaseName = MF.createExternalSymbolName("__memory_base");
1687  }
1688  SDValue BaseAddr =
1689  DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
1690  DAG.getTargetExternalSymbol(BaseName, PtrVT));
1691 
1692  SDValue SymAddr = DAG.getNode(
1693  WebAssemblyISD::WrapperREL, DL, VT,
1694  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset(),
1695  OperandFlags));
1696 
1697  return DAG.getNode(ISD::ADD, DL, VT, BaseAddr, SymAddr);
1698  }
1700  }
1701 
1702  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1703  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
1704  GA->getOffset(), OperandFlags));
1705 }
1706 
1707 SDValue
1708 WebAssemblyTargetLowering::LowerExternalSymbol(SDValue Op,
1709  SelectionDAG &DAG) const {
1710  SDLoc DL(Op);
1711  const auto *ES = cast<ExternalSymbolSDNode>(Op);
1712  EVT VT = Op.getValueType();
1713  assert(ES->getTargetFlags() == 0 &&
1714  "Unexpected target flags on generic ExternalSymbolSDNode");
1715  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1716  DAG.getTargetExternalSymbol(ES->getSymbol(), VT));
1717 }
1718 
1719 SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
1720  SelectionDAG &DAG) const {
1721  // There's no need for a Wrapper node because we always incorporate a jump
1722  // table operand into a BR_TABLE instruction, rather than ever
1723  // materializing it in a register.
1724  const JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1725  return DAG.getTargetJumpTable(JT->getIndex(), Op.getValueType(),
1726  JT->getTargetFlags());
1727 }
1728 
1729 SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op,
1730  SelectionDAG &DAG) const {
1731  SDLoc DL(Op);
1732  SDValue Chain = Op.getOperand(0);
1733  const auto *JT = cast<JumpTableSDNode>(Op.getOperand(1));
1734  SDValue Index = Op.getOperand(2);
1735  assert(JT->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
1736 
1738  Ops.push_back(Chain);
1739  Ops.push_back(Index);
1740 
1742  const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs;
1743 
1744  // Add an operand for each case.
1745  for (auto *MBB : MBBs)
1746  Ops.push_back(DAG.getBasicBlock(MBB));
1747 
1748  // Add the first MBB as a dummy default target for now. This will be replaced
1749  // with the proper default target (and the preceding range check eliminated)
1750  // if possible by WebAssemblyFixBrTableDefaults.
1751  Ops.push_back(DAG.getBasicBlock(*MBBs.begin()));
1752  return DAG.getNode(WebAssemblyISD::BR_TABLE, DL, MVT::Other, Ops);
1753 }
1754 
1755 SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op,
1756  SelectionDAG &DAG) const {
1757  SDLoc DL(Op);
1759 
1760  auto *MFI = DAG.getMachineFunction().getInfo<WebAssemblyFunctionInfo>();
1761  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1762 
1763  SDValue ArgN = DAG.getCopyFromReg(DAG.getEntryNode(), DL,
1764  MFI->getVarargBufferVreg(), PtrVT);
1765  return DAG.getStore(Op.getOperand(0), DL, ArgN, Op.getOperand(1),
1766  MachinePointerInfo(SV));
1767 }
1768 
1769 SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
1770  SelectionDAG &DAG) const {
1771  MachineFunction &MF = DAG.getMachineFunction();
1772  unsigned IntNo;
1773  switch (Op.getOpcode()) {
1774  case ISD::INTRINSIC_VOID:
1776  IntNo = Op.getConstantOperandVal(1);
1777  break;
1779  IntNo = Op.getConstantOperandVal(0);
1780  break;
1781  default:
1782  llvm_unreachable("Invalid intrinsic");
1783  }
1784  SDLoc DL(Op);
1785 
1786  switch (IntNo) {
1787  default:
1788  return SDValue(); // Don't custom lower most intrinsics.
1789 
1790  case Intrinsic::wasm_lsda: {
1791  auto PtrVT = getPointerTy(MF.getDataLayout());
1792  const char *SymName = MF.createExternalSymbolName(
1793  "GCC_except_table" + std::to_string(MF.getFunctionNumber()));
1794  if (isPositionIndependent()) {
1795  SDValue Node = DAG.getTargetExternalSymbol(
1796  SymName, PtrVT, WebAssemblyII::MO_MEMORY_BASE_REL);
1797  const char *BaseName = MF.createExternalSymbolName("__memory_base");
1798  SDValue BaseAddr =
1799  DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
1800  DAG.getTargetExternalSymbol(BaseName, PtrVT));
1801  SDValue SymAddr =
1802  DAG.getNode(WebAssemblyISD::WrapperREL, DL, PtrVT, Node);
1803  return DAG.getNode(ISD::ADD, DL, PtrVT, BaseAddr, SymAddr);
1804  }
1805  SDValue Node = DAG.getTargetExternalSymbol(SymName, PtrVT);
1806  return DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT, Node);
1807  }
1808 
1809  case Intrinsic::wasm_shuffle: {
1810  // Drop in-chain and replace undefs, but otherwise pass through unchanged
1811  SDValue Ops[18];
1812  size_t OpIdx = 0;
1813  Ops[OpIdx++] = Op.getOperand(1);
1814  Ops[OpIdx++] = Op.getOperand(2);
1815  while (OpIdx < 18) {
1816  const SDValue &MaskIdx = Op.getOperand(OpIdx + 1);
1817  if (MaskIdx.isUndef() ||
1818  cast<ConstantSDNode>(MaskIdx.getNode())->getZExtValue() >= 32) {
1819  Ops[OpIdx++] = DAG.getConstant(0, DL, MVT::i32);
1820  } else {
1821  Ops[OpIdx++] = MaskIdx;
1822  }
1823  }
1824  return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
1825  }
1826  }
1827 }
1828 
1829 SDValue
1830 WebAssemblyTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
1831  SelectionDAG &DAG) const {
1832  SDLoc DL(Op);
1833  // If sign extension operations are disabled, allow sext_inreg only if operand
1834  // is a vector extract of an i8 or i16 lane. SIMD does not depend on sign
1835  // extension operations, but allowing sext_inreg in this context lets us have
1836  // simple patterns to select extract_lane_s instructions. Expanding sext_inreg
1837  // everywhere would be simpler in this file, but would necessitate large and
1838  // brittle patterns to undo the expansion and select extract_lane_s
1839  // instructions.
1840  assert(!Subtarget->hasSignExt() && Subtarget->hasSIMD128());
1841  if (Op.getOperand(0).getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1842  return SDValue();
1843 
1844  const SDValue &Extract = Op.getOperand(0);
1845  MVT VecT = Extract.getOperand(0).getSimpleValueType();
1846  if (VecT.getVectorElementType().getSizeInBits() > 32)
1847  return SDValue();
1848  MVT ExtractedLaneT =
1849  cast<VTSDNode>(Op.getOperand(1).getNode())->getVT().getSimpleVT();
1850  MVT ExtractedVecT =
1851  MVT::getVectorVT(ExtractedLaneT, 128 / ExtractedLaneT.getSizeInBits());
1852  if (ExtractedVecT == VecT)
1853  return Op;
1854 
1855  // Bitcast vector to appropriate type to ensure ISel pattern coverage
1856  const SDNode *Index = Extract.getOperand(1).getNode();
1857  if (!isa<ConstantSDNode>(Index))
1858  return SDValue();
1859  unsigned IndexVal = cast<ConstantSDNode>(Index)->getZExtValue();
1860  unsigned Scale =
1861  ExtractedVecT.getVectorNumElements() / VecT.getVectorNumElements();
1862  assert(Scale > 1);
1863  SDValue NewIndex =
1864  DAG.getConstant(IndexVal * Scale, DL, Index->getValueType(0));
1865  SDValue NewExtract = DAG.getNode(
1867  DAG.getBitcast(ExtractedVecT, Extract.getOperand(0)), NewIndex);
1868  return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Op.getValueType(), NewExtract,
1869  Op.getOperand(1));
1870 }
1871 
1873  SDLoc DL(Op);
1874  if (Op.getValueType() != MVT::v2f64)
1875  return SDValue();
1876 
1877  auto GetConvertedLane = [](SDValue Op, unsigned &Opcode, SDValue &SrcVec,
1878  unsigned &Index) -> bool {
1879  switch (Op.getOpcode()) {
1880  case ISD::SINT_TO_FP:
1881  Opcode = WebAssemblyISD::CONVERT_LOW_S;
1882  break;
1883  case ISD::UINT_TO_FP:
1884  Opcode = WebAssemblyISD::CONVERT_LOW_U;
1885  break;
1886  case ISD::FP_EXTEND:
1887  Opcode = WebAssemblyISD::PROMOTE_LOW;
1888  break;
1889  default:
1890  return false;
1891  }
1892 
1893  auto ExtractVector = Op.getOperand(0);
1894  if (ExtractVector.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1895  return false;
1896 
1897  if (!isa<ConstantSDNode>(ExtractVector.getOperand(1).getNode()))
1898  return false;
1899 
1900  SrcVec = ExtractVector.getOperand(0);
1901  Index = ExtractVector.getConstantOperandVal(1);
1902  return true;
1903  };
1904 
1905  unsigned LHSOpcode, RHSOpcode, LHSIndex, RHSIndex;
1906  SDValue LHSSrcVec, RHSSrcVec;
1907  if (!GetConvertedLane(Op.getOperand(0), LHSOpcode, LHSSrcVec, LHSIndex) ||
1908  !GetConvertedLane(Op.getOperand(1), RHSOpcode, RHSSrcVec, RHSIndex))
1909  return SDValue();
1910 
1911  if (LHSOpcode != RHSOpcode)
1912  return SDValue();
1913 
1914  MVT ExpectedSrcVT;
1915  switch (LHSOpcode) {
1916  case WebAssemblyISD::CONVERT_LOW_S:
1917  case WebAssemblyISD::CONVERT_LOW_U:
1918  ExpectedSrcVT = MVT::v4i32;
1919  break;
1920  case WebAssemblyISD::PROMOTE_LOW:
1921  ExpectedSrcVT = MVT::v4f32;
1922  break;
1923  }
1924  if (LHSSrcVec.getValueType() != ExpectedSrcVT)
1925  return SDValue();
1926 
1927  auto Src = LHSSrcVec;
1928  if (LHSIndex != 0 || RHSIndex != 1 || LHSSrcVec != RHSSrcVec) {
1929  // Shuffle the source vector so that the converted lanes are the low lanes.
1930  Src = DAG.getVectorShuffle(
1931  ExpectedSrcVT, DL, LHSSrcVec, RHSSrcVec,
1932  {static_cast<int>(LHSIndex), static_cast<int>(RHSIndex) + 4, -1, -1});
1933  }
1934  return DAG.getNode(LHSOpcode, DL, MVT::v2f64, Src);
1935 }
1936 
1937 SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
1938  SelectionDAG &DAG) const {
1939  if (auto ConvertLow = LowerConvertLow(Op, DAG))
1940  return ConvertLow;
1941 
1942  SDLoc DL(Op);
1943  const EVT VecT = Op.getValueType();
1944  const EVT LaneT = Op.getOperand(0).getValueType();
1945  const size_t Lanes = Op.getNumOperands();
1946  bool CanSwizzle = VecT == MVT::v16i8;
1947 
1948  // BUILD_VECTORs are lowered to the instruction that initializes the highest
1949  // possible number of lanes at once followed by a sequence of replace_lane
1950  // instructions to individually initialize any remaining lanes.
1951 
1952  // TODO: Tune this. For example, lanewise swizzling is very expensive, so
1953  // swizzled lanes should be given greater weight.
1954 
1955  // TODO: Investigate looping rather than always extracting/replacing specific
1956  // lanes to fill gaps.
1957 
1958  auto IsConstant = [](const SDValue &V) {
1959  return V.getOpcode() == ISD::Constant || V.getOpcode() == ISD::ConstantFP;
1960  };
1961 
1962  // Returns the source vector and index vector pair if they exist. Checks for:
1963  // (extract_vector_elt
1964  // $src,
1965  // (sign_extend_inreg (extract_vector_elt $indices, $i))
1966  // )
1967  auto GetSwizzleSrcs = [](size_t I, const SDValue &Lane) {
1968  auto Bail = std::make_pair(SDValue(), SDValue());
1969  if (Lane->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1970  return Bail;
1971  const SDValue &SwizzleSrc = Lane->getOperand(0);
1972  const SDValue &IndexExt = Lane->getOperand(1);
1973  if (IndexExt->getOpcode() != ISD::SIGN_EXTEND_INREG)
1974  return Bail;
1975  const SDValue &Index = IndexExt->getOperand(0);
1976  if (Index->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1977  return Bail;
1978  const SDValue &SwizzleIndices = Index->getOperand(0);
1979  if (SwizzleSrc.getValueType() != MVT::v16i8 ||
1980  SwizzleIndices.getValueType() != MVT::v16i8 ||
1981  Index->getOperand(1)->getOpcode() != ISD::Constant ||
1982  Index->getConstantOperandVal(1) != I)
1983  return Bail;
1984  return std::make_pair(SwizzleSrc, SwizzleIndices);
1985  };
1986 
1987  // If the lane is extracted from another vector at a constant index, return
1988  // that vector. The source vector must not have more lanes than the dest
1989  // because the shufflevector indices are in terms of the destination lanes and
1990  // would not be able to address the smaller individual source lanes.
1991  auto GetShuffleSrc = [&](const SDValue &Lane) {
1992  if (Lane->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1993  return SDValue();
1994  if (!isa<ConstantSDNode>(Lane->getOperand(1).getNode()))
1995  return SDValue();
1996  if (Lane->getOperand(0).getValueType().getVectorNumElements() >
1997  VecT.getVectorNumElements())
1998  return SDValue();
1999  return Lane->getOperand(0);
2000  };
2001 
2002  using ValueEntry = std::pair<SDValue, size_t>;
2003  SmallVector<ValueEntry, 16> SplatValueCounts;
2004 
2005  using SwizzleEntry = std::pair<std::pair<SDValue, SDValue>, size_t>;
2006  SmallVector<SwizzleEntry, 16> SwizzleCounts;
2007 
2008  using ShuffleEntry = std::pair<SDValue, size_t>;
2009  SmallVector<ShuffleEntry, 16> ShuffleCounts;
2010 
2011  auto AddCount = [](auto &Counts, const auto &Val) {
2012  auto CountIt =
2013  llvm::find_if(Counts, [&Val](auto E) { return E.first == Val; });
2014  if (CountIt == Counts.end()) {
2015  Counts.emplace_back(Val, 1);
2016  } else {
2017  CountIt->second++;
2018  }
2019  };
2020 
2021  auto GetMostCommon = [](auto &Counts) {
2022  auto CommonIt =
2023  std::max_element(Counts.begin(), Counts.end(), llvm::less_second());
2024  assert(CommonIt != Counts.end() && "Unexpected all-undef build_vector");
2025  return *CommonIt;
2026  };
2027 
2028  size_t NumConstantLanes = 0;
2029 
2030  // Count eligible lanes for each type of vector creation op
2031  for (size_t I = 0; I < Lanes; ++I) {
2032  const SDValue &Lane = Op->getOperand(I);
2033  if (Lane.isUndef())
2034  continue;
2035 
2036  AddCount(SplatValueCounts, Lane);
2037 
2038  if (IsConstant(Lane))
2039  NumConstantLanes++;
2040  if (auto ShuffleSrc = GetShuffleSrc(Lane))
2041  AddCount(ShuffleCounts, ShuffleSrc);
2042  if (CanSwizzle) {
2043  auto SwizzleSrcs = GetSwizzleSrcs(I, Lane);
2044  if (SwizzleSrcs.first)
2045  AddCount(SwizzleCounts, SwizzleSrcs);
2046  }
2047  }
2048 
2049  SDValue SplatValue;
2050  size_t NumSplatLanes;
2051  std::tie(SplatValue, NumSplatLanes) = GetMostCommon(SplatValueCounts);
2052 
2053  SDValue SwizzleSrc;
2054  SDValue SwizzleIndices;
2055  size_t NumSwizzleLanes = 0;
2056  if (SwizzleCounts.size())
2057  std::forward_as_tuple(std::tie(SwizzleSrc, SwizzleIndices),
2058  NumSwizzleLanes) = GetMostCommon(SwizzleCounts);
2059 
2060  // Shuffles can draw from up to two vectors, so find the two most common
2061  // sources.
2062  SDValue ShuffleSrc1, ShuffleSrc2;
2063  size_t NumShuffleLanes = 0;
2064  if (ShuffleCounts.size()) {
2065  std::tie(ShuffleSrc1, NumShuffleLanes) = GetMostCommon(ShuffleCounts);
2066  llvm::erase_if(ShuffleCounts,
2067  [&](const auto &Pair) { return Pair.first == ShuffleSrc1; });
2068  }
2069  if (ShuffleCounts.size()) {
2070  size_t AdditionalShuffleLanes;
2071  std::tie(ShuffleSrc2, AdditionalShuffleLanes) =
2072  GetMostCommon(ShuffleCounts);
2073  NumShuffleLanes += AdditionalShuffleLanes;
2074  }
2075 
2076  // Predicate returning true if the lane is properly initialized by the
2077  // original instruction
2078  std::function<bool(size_t, const SDValue &)> IsLaneConstructed;
2079  SDValue Result;
2080  // Prefer swizzles over shuffles over vector consts over splats
2081  if (NumSwizzleLanes >= NumShuffleLanes &&
2082  NumSwizzleLanes >= NumConstantLanes && NumSwizzleLanes >= NumSplatLanes) {
2083  Result = DAG.getNode(WebAssemblyISD::SWIZZLE, DL, VecT, SwizzleSrc,
2084  SwizzleIndices);
2085  auto Swizzled = std::make_pair(SwizzleSrc, SwizzleIndices);
2086  IsLaneConstructed = [&, Swizzled](size_t I, const SDValue &Lane) {
2087  return Swizzled == GetSwizzleSrcs(I, Lane);
2088  };
2089  } else if (NumShuffleLanes >= NumConstantLanes &&
2090  NumShuffleLanes >= NumSplatLanes) {
2091  size_t DestLaneSize = VecT.getVectorElementType().getFixedSizeInBits() / 8;
2092  size_t DestLaneCount = VecT.getVectorNumElements();
2093  size_t Scale1 = 1;
2094  size_t Scale2 = 1;
2095  SDValue Src1 = ShuffleSrc1;
2096  SDValue Src2 = ShuffleSrc2 ? ShuffleSrc2 : DAG.getUNDEF(VecT);
2097  if (Src1.getValueType() != VecT) {
2098  size_t LaneSize =
2100  assert(LaneSize > DestLaneSize);
2101  Scale1 = LaneSize / DestLaneSize;
2102  Src1 = DAG.getBitcast(VecT, Src1);
2103  }
2104  if (Src2.getValueType() != VecT) {
2105  size_t LaneSize =
2107  assert(LaneSize > DestLaneSize);
2108  Scale2 = LaneSize / DestLaneSize;
2109  Src2 = DAG.getBitcast(VecT, Src2);
2110  }
2111 
2112  int Mask[16];
2113  assert(DestLaneCount <= 16);
2114  for (size_t I = 0; I < DestLaneCount; ++I) {
2115  const SDValue &Lane = Op->getOperand(I);
2116  SDValue Src = GetShuffleSrc(Lane);
2117  if (Src == ShuffleSrc1) {
2118  Mask[I] = Lane->getConstantOperandVal(1) * Scale1;
2119  } else if (Src && Src == ShuffleSrc2) {
2120  Mask[I] = DestLaneCount + Lane->getConstantOperandVal(1) * Scale2;
2121  } else {
2122  Mask[I] = -1;
2123  }
2124  }
2125  ArrayRef<int> MaskRef(Mask, DestLaneCount);
2126  Result = DAG.getVectorShuffle(VecT, DL, Src1, Src2, MaskRef);
2127  IsLaneConstructed = [&](size_t, const SDValue &Lane) {
2128  auto Src = GetShuffleSrc(Lane);
2129  return Src == ShuffleSrc1 || (Src && Src == ShuffleSrc2);
2130  };
2131  } else if (NumConstantLanes >= NumSplatLanes) {
2132  SmallVector<SDValue, 16> ConstLanes;
2133  for (const SDValue &Lane : Op->op_values()) {
2134  if (IsConstant(Lane)) {
2135  // Values may need to be fixed so that they will sign extend to be
2136  // within the expected range during ISel. Check whether the value is in
2137  // bounds based on the lane bit width and if it is out of bounds, lop
2138  // off the extra bits and subtract 2^n to reflect giving the high bit
2139  // value -2^(n-1) rather than +2^(n-1). Skip the i64 case because it
2140  // cannot possibly be out of range.
2141  auto *Const = dyn_cast<ConstantSDNode>(Lane.getNode());
2142  int64_t Val = Const ? Const->getSExtValue() : 0;
2143  uint64_t LaneBits = 128 / Lanes;
2144  assert((LaneBits == 64 || Val >= -(1ll << (LaneBits - 1))) &&
2145  "Unexpected out of bounds negative value");
2146  if (Const && LaneBits != 64 && Val > (1ll << (LaneBits - 1)) - 1) {
2147  auto NewVal = ((uint64_t)Val % (1ll << LaneBits)) - (1ll << LaneBits);
2148  ConstLanes.push_back(DAG.getConstant(NewVal, SDLoc(Lane), LaneT));
2149  } else {
2150  ConstLanes.push_back(Lane);
2151  }
2152  } else if (LaneT.isFloatingPoint()) {
2153  ConstLanes.push_back(DAG.getConstantFP(0, DL, LaneT));
2154  } else {
2155  ConstLanes.push_back(DAG.getConstant(0, DL, LaneT));
2156  }
2157  }
2158  Result = DAG.getBuildVector(VecT, DL, ConstLanes);
2159  IsLaneConstructed = [&IsConstant](size_t _, const SDValue &Lane) {
2160  return IsConstant(Lane);
2161  };
2162  } else {
2163  // Use a splat, but possibly a load_splat
2164  LoadSDNode *SplattedLoad;
2165  if ((SplattedLoad = dyn_cast<LoadSDNode>(SplatValue)) &&
2166  SplattedLoad->getMemoryVT() == VecT.getVectorElementType()) {
2168  WebAssemblyISD::LOAD_SPLAT, DL, DAG.getVTList(VecT),
2169  {SplattedLoad->getChain(), SplattedLoad->getBasePtr(),
2170  SplattedLoad->getOffset()},
2171  SplattedLoad->getMemoryVT(), SplattedLoad->getMemOperand());
2172  } else {
2173  Result = DAG.getSplatBuildVector(VecT, DL, SplatValue);
2174  }
2175  IsLaneConstructed = [&SplatValue](size_t _, const SDValue &Lane) {
2176  return Lane == SplatValue;
2177  };
2178  }
2179 
2180  assert(Result);
2181  assert(IsLaneConstructed);
2182 
2183  // Add replace_lane instructions for any unhandled values
2184  for (size_t I = 0; I < Lanes; ++I) {
2185  const SDValue &Lane = Op->getOperand(I);
2186  if (!Lane.isUndef() && !IsLaneConstructed(I, Lane))
2187  Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VecT, Result, Lane,
2188  DAG.getConstant(I, DL, MVT::i32));
2189  }
2190 
2191  return Result;
2192 }
2193 
2194 SDValue
2195 WebAssemblyTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
2196  SelectionDAG &DAG) const {
2197  SDLoc DL(Op);
2198  ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Op.getNode())->getMask();
2199  MVT VecType = Op.getOperand(0).getSimpleValueType();
2200  assert(VecType.is128BitVector() && "Unexpected shuffle vector type");
2201  size_t LaneBytes = VecType.getVectorElementType().getSizeInBits() / 8;
2202 
2203  // Space for two vector args and sixteen mask indices
2204  SDValue Ops[18];
2205  size_t OpIdx = 0;
2206  Ops[OpIdx++] = Op.getOperand(0);
2207  Ops[OpIdx++] = Op.getOperand(1);
2208 
2209  // Expand mask indices to byte indices and materialize them as operands
2210  for (int M : Mask) {
2211  for (size_t J = 0; J < LaneBytes; ++J) {
2212  // Lower undefs (represented by -1 in mask) to {0..J}, which use a
2213  // whole lane of vector input, to allow further reduction at VM. E.g.
2214  // match an 8x16 byte shuffle to an equivalent cheaper 32x4 shuffle.
2215  uint64_t ByteIndex = M == -1 ? J : (uint64_t)M * LaneBytes + J;
2216  Ops[OpIdx++] = DAG.getConstant(ByteIndex, DL, MVT::i32);
2217  }
2218  }
2219 
2220  return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
2221 }
2222 
2223 SDValue WebAssemblyTargetLowering::LowerSETCC(SDValue Op,
2224  SelectionDAG &DAG) const {
2225  SDLoc DL(Op);
2226  // The legalizer does not know how to expand the unsupported comparison modes
2227  // of i64x2 vectors, so we manually unroll them here.
2228  assert(Op->getOperand(0)->getSimpleValueType(0) == MVT::v2i64);
2230  DAG.ExtractVectorElements(Op->getOperand(0), LHS);
2231  DAG.ExtractVectorElements(Op->getOperand(1), RHS);
2232  const SDValue &CC = Op->getOperand(2);
2233  auto MakeLane = [&](unsigned I) {
2234  return DAG.getNode(ISD::SELECT_CC, DL, MVT::i64, LHS[I], RHS[I],
2235  DAG.getConstant(uint64_t(-1), DL, MVT::i64),
2236  DAG.getConstant(uint64_t(0), DL, MVT::i64), CC);
2237  };
2238  return DAG.getBuildVector(Op->getValueType(0), DL,
2239  {MakeLane(0), MakeLane(1)});
2240 }
2241 
2242 SDValue
2243 WebAssemblyTargetLowering::LowerAccessVectorElement(SDValue Op,
2244  SelectionDAG &DAG) const {
2245  // Allow constant lane indices, expand variable lane indices
2246  SDNode *IdxNode = Op.getOperand(Op.getNumOperands() - 1).getNode();
2247  if (isa<ConstantSDNode>(IdxNode) || IdxNode->isUndef())
2248  return Op;
2249  else
2250  // Perform default expansion
2251  return SDValue();
2252 }
2253 
2255  EVT LaneT = Op.getSimpleValueType().getVectorElementType();
2256  // 32-bit and 64-bit unrolled shifts will have proper semantics
2257  if (LaneT.bitsGE(MVT::i32))
2258  return DAG.UnrollVectorOp(Op.getNode());
2259  // Otherwise mask the shift value to get proper semantics from 32-bit shift
2260  SDLoc DL(Op);
2261  size_t NumLanes = Op.getSimpleValueType().getVectorNumElements();
2262  SDValue Mask = DAG.getConstant(LaneT.getSizeInBits() - 1, DL, MVT::i32);
2263  unsigned ShiftOpcode = Op.getOpcode();
2264  SmallVector<SDValue, 16> ShiftedElements;
2265  DAG.ExtractVectorElements(Op.getOperand(0), ShiftedElements, 0, 0, MVT::i32);
2266  SmallVector<SDValue, 16> ShiftElements;
2267  DAG.ExtractVectorElements(Op.getOperand(1), ShiftElements, 0, 0, MVT::i32);
2268  SmallVector<SDValue, 16> UnrolledOps;
2269  for (size_t i = 0; i < NumLanes; ++i) {
2270  SDValue MaskedShiftValue =
2271  DAG.getNode(ISD::AND, DL, MVT::i32, ShiftElements[i], Mask);
2272  SDValue ShiftedValue = ShiftedElements[i];
2273  if (ShiftOpcode == ISD::SRA)
2274  ShiftedValue = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32,
2275  ShiftedValue, DAG.getValueType(LaneT));
2276  UnrolledOps.push_back(
2277  DAG.getNode(ShiftOpcode, DL, MVT::i32, ShiftedValue, MaskedShiftValue));
2278  }
2279  return DAG.getBuildVector(Op.getValueType(), DL, UnrolledOps);
2280 }
2281 
2282 SDValue WebAssemblyTargetLowering::LowerShift(SDValue Op,
2283  SelectionDAG &DAG) const {
2284  SDLoc DL(Op);
2285 
2286  // Only manually lower vector shifts
2287  assert(Op.getSimpleValueType().isVector());
2288 
2289  auto ShiftVal = DAG.getSplatValue(Op.getOperand(1));
2290  if (!ShiftVal)
2291  return unrollVectorShift(Op, DAG);
2292 
2293  // Use anyext because none of the high bits can affect the shift
2294  ShiftVal = DAG.getAnyExtOrTrunc(ShiftVal, DL, MVT::i32);
2295 
2296  unsigned Opcode;
2297  switch (Op.getOpcode()) {
2298  case ISD::SHL:
2299  Opcode = WebAssemblyISD::VEC_SHL;
2300  break;
2301  case ISD::SRA:
2302  Opcode = WebAssemblyISD::VEC_SHR_S;
2303  break;
2304  case ISD::SRL:
2305  Opcode = WebAssemblyISD::VEC_SHR_U;
2306  break;
2307  default:
2308  llvm_unreachable("unexpected opcode");
2309  }
2310 
2311  return DAG.getNode(Opcode, DL, Op.getValueType(), Op.getOperand(0), ShiftVal);
2312 }
2313 
2314 SDValue WebAssemblyTargetLowering::LowerFP_TO_INT_SAT(SDValue Op,
2315  SelectionDAG &DAG) const {
2316  SDLoc DL(Op);
2317  EVT ResT = Op.getValueType();
2318  EVT SatVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
2319 
2320  if ((ResT == MVT::i32 || ResT == MVT::i64) &&
2321  (SatVT == MVT::i32 || SatVT == MVT::i64))
2322  return Op;
2323 
2324  if (ResT == MVT::v4i32 && SatVT == MVT::i32)
2325  return Op;
2326 
2327  return SDValue();
2328 }
2329 
2330 //===----------------------------------------------------------------------===//
2331 // Custom DAG combine hooks
2332 //===----------------------------------------------------------------------===//
2333 static SDValue
2335  auto &DAG = DCI.DAG;
2336  auto Shuffle = cast<ShuffleVectorSDNode>(N);
2337 
2338  // Hoist vector bitcasts that don't change the number of lanes out of unary
2339  // shuffles, where they are less likely to get in the way of other combines.
2340  // (shuffle (vNxT1 (bitcast (vNxT0 x))), undef, mask) ->
2341  // (vNxT1 (bitcast (vNxT0 (shuffle x, undef, mask))))
2342  SDValue Bitcast = N->getOperand(0);
2343  if (Bitcast.getOpcode() != ISD::BITCAST)
2344  return SDValue();
2345  if (!N->getOperand(1).isUndef())
2346  return SDValue();
2347  SDValue CastOp = Bitcast.getOperand(0);
2348  MVT SrcType = CastOp.getSimpleValueType();
2349  MVT DstType = Bitcast.getSimpleValueType();
2350  if (!SrcType.is128BitVector() ||
2351  SrcType.getVectorNumElements() != DstType.getVectorNumElements())
2352  return SDValue();
2353  SDValue NewShuffle = DAG.getVectorShuffle(
2354  SrcType, SDLoc(N), CastOp, DAG.getUNDEF(SrcType), Shuffle->getMask());
2355  return DAG.getBitcast(DstType, NewShuffle);
2356 }
2357 
2358 static SDValue
2360  auto &DAG = DCI.DAG;
2361  assert(N->getOpcode() == ISD::SIGN_EXTEND ||
2362  N->getOpcode() == ISD::ZERO_EXTEND);
2363 
2364  // Combine ({s,z}ext (extract_subvector src, i)) into a widening operation if
2365  // possible before the extract_subvector can be expanded.
2366  auto Extract = N->getOperand(0);
2367  if (Extract.getOpcode() != ISD::EXTRACT_SUBVECTOR)
2368  return SDValue();
2369  auto Source = Extract.getOperand(0);
2370  auto *IndexNode = dyn_cast<ConstantSDNode>(Extract.getOperand(1));
2371  if (IndexNode == nullptr)
2372  return SDValue();
2373  auto Index = IndexNode->getZExtValue();
2374 
2375  // Only v8i8, v4i16, and v2i32 extracts can be widened, and only if the
2376  // extracted subvector is the low or high half of its source.
2377  EVT ResVT = N->getValueType(0);
2378  if (ResVT == MVT::v8i16) {
2379  if (Extract.getValueType() != MVT::v8i8 ||
2380  Source.getValueType() != MVT::v16i8 || (Index != 0 && Index != 8))
2381  return SDValue();
2382  } else if (ResVT == MVT::v4i32) {
2383  if (Extract.getValueType() != MVT::v4i16 ||
2384  Source.getValueType() != MVT::v8i16 || (Index != 0 && Index != 4))
2385  return SDValue();
2386  } else if (ResVT == MVT::v2i64) {
2387  if (Extract.getValueType() != MVT::v2i32 ||
2388  Source.getValueType() != MVT::v4i32 || (Index != 0 && Index != 2))
2389  return SDValue();
2390  } else {
2391  return SDValue();
2392  }
2393 
2394  bool IsSext = N->getOpcode() == ISD::SIGN_EXTEND;
2395  bool IsLow = Index == 0;
2396 
2397  unsigned Op = IsSext ? (IsLow ? WebAssemblyISD::EXTEND_LOW_S
2398  : WebAssemblyISD::EXTEND_HIGH_S)
2399  : (IsLow ? WebAssemblyISD::EXTEND_LOW_U
2400  : WebAssemblyISD::EXTEND_HIGH_U);
2401 
2402  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2403 }
2404 
2405 static SDValue
2407  auto &DAG = DCI.DAG;
2408 
2409  auto GetWasmConversionOp = [](unsigned Op) {
2410  switch (Op) {
2411  case ISD::FP_TO_SINT_SAT:
2412  return WebAssemblyISD::TRUNC_SAT_ZERO_S;
2413  case ISD::FP_TO_UINT_SAT:
2414  return WebAssemblyISD::TRUNC_SAT_ZERO_U;
2415  case ISD::FP_ROUND:
2416  return WebAssemblyISD::DEMOTE_ZERO;
2417  }
2418  llvm_unreachable("unexpected op");
2419  };
2420 
2421  auto IsZeroSplat = [](SDValue SplatVal) {
2422  auto *Splat = dyn_cast<BuildVectorSDNode>(SplatVal.getNode());
2423  APInt SplatValue, SplatUndef;
2424  unsigned SplatBitSize;
2425  bool HasAnyUndefs;
2426  return Splat &&
2427  Splat->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
2428  HasAnyUndefs) &&
2429  SplatValue == 0;
2430  };
2431 
2432  if (N->getOpcode() == ISD::CONCAT_VECTORS) {
2433  // Combine this:
2434  //
2435  // (concat_vectors (v2i32 (fp_to_{s,u}int_sat $x, 32)), (v2i32 (splat 0)))
2436  //
2437  // into (i32x4.trunc_sat_f64x2_zero_{s,u} $x).
2438  //
2439  // Or this:
2440  //
2441  // (concat_vectors (v2f32 (fp_round (v2f64 $x))), (v2f32 (splat 0)))
2442  //
2443  // into (f32x4.demote_zero_f64x2 $x).
2444  EVT ResVT;
2445  EVT ExpectedConversionType;
2446  auto Conversion = N->getOperand(0);
2447  auto ConversionOp = Conversion.getOpcode();
2448  switch (ConversionOp) {
2449  case ISD::FP_TO_SINT_SAT:
2450  case ISD::FP_TO_UINT_SAT:
2451  ResVT = MVT::v4i32;
2452  ExpectedConversionType = MVT::v2i32;
2453  break;
2454  case ISD::FP_ROUND:
2455  ResVT = MVT::v4f32;
2456  ExpectedConversionType = MVT::v2f32;
2457  break;
2458  default:
2459  return SDValue();
2460  }
2461 
2462  if (N->getValueType(0) != ResVT)
2463  return SDValue();
2464 
2465  if (Conversion.getValueType() != ExpectedConversionType)
2466  return SDValue();
2467 
2468  auto Source = Conversion.getOperand(0);
2469  if (Source.getValueType() != MVT::v2f64)
2470  return SDValue();
2471 
2472  if (!IsZeroSplat(N->getOperand(1)) ||
2473  N->getOperand(1).getValueType() != ExpectedConversionType)
2474  return SDValue();
2475 
2476  unsigned Op = GetWasmConversionOp(ConversionOp);
2477  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2478  }
2479 
2480  // Combine this:
2481  //
2482  // (fp_to_{s,u}int_sat (concat_vectors $x, (v2f64 (splat 0))), 32)
2483  //
2484  // into (i32x4.trunc_sat_f64x2_zero_{s,u} $x).
2485  //
2486  // Or this:
2487  //
2488  // (v4f32 (fp_round (concat_vectors $x, (v2f64 (splat 0)))))
2489  //
2490  // into (f32x4.demote_zero_f64x2 $x).
2491  EVT ResVT;
2492  auto ConversionOp = N->getOpcode();
2493  switch (ConversionOp) {
2494  case ISD::FP_TO_SINT_SAT:
2495  case ISD::FP_TO_UINT_SAT:
2496  ResVT = MVT::v4i32;
2497  break;
2498  case ISD::FP_ROUND:
2499  ResVT = MVT::v4f32;
2500  break;
2501  default:
2502  llvm_unreachable("unexpected op");
2503  }
2504 
2505  if (N->getValueType(0) != ResVT)
2506  return SDValue();
2507 
2508  auto Concat = N->getOperand(0);
2509  if (Concat.getValueType() != MVT::v4f64)
2510  return SDValue();
2511 
2512  auto Source = Concat.getOperand(0);
2513  if (Source.getValueType() != MVT::v2f64)
2514  return SDValue();
2515 
2516  if (!IsZeroSplat(Concat.getOperand(1)) ||
2517  Concat.getOperand(1).getValueType() != MVT::v2f64)
2518  return SDValue();
2519 
2520  unsigned Op = GetWasmConversionOp(ConversionOp);
2521  return DAG.getNode(Op, SDLoc(N), ResVT, Source);
2522 }
2523 
2524 // Helper to extract VectorWidth bits from Vec, starting from IdxVal.
2525 static SDValue extractSubVector(SDValue Vec, unsigned IdxVal, SelectionDAG &DAG,
2526  const SDLoc &DL, unsigned VectorWidth) {
2527  EVT VT = Vec.getValueType();
2528  EVT ElVT = VT.getVectorElementType();
2529  unsigned Factor = VT.getSizeInBits() / VectorWidth;
2530  EVT ResultVT = EVT::getVectorVT(*DAG.getContext(), ElVT,
2531  VT.getVectorNumElements() / Factor);
2532 
2533  // Extract the relevant VectorWidth bits. Generate an EXTRACT_SUBVECTOR
2534  unsigned ElemsPerChunk = VectorWidth / ElVT.getSizeInBits();
2535  assert(isPowerOf2_32(ElemsPerChunk) && "Elements per chunk not power of 2");
2536 
2537  // This is the index of the first element of the VectorWidth-bit chunk
2538  // we want. Since ElemsPerChunk is a power of 2 just need to clear bits.
2539  IdxVal &= ~(ElemsPerChunk - 1);
2540 
2541  // If the input is a buildvector just emit a smaller one.
2542  if (Vec.getOpcode() == ISD::BUILD_VECTOR)
2543  return DAG.getBuildVector(ResultVT, DL,
2544  Vec->ops().slice(IdxVal, ElemsPerChunk));
2545 
2546  SDValue VecIdx = DAG.getIntPtrConstant(IdxVal, DL);
2547  return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ResultVT, Vec, VecIdx);
2548 }
2549 
2550 // Helper to recursively truncate vector elements in half with NARROW_U. DstVT
2551 // is the expected destination value type after recursion. In is the initial
2552 // input. Note that the input should have enough leading zero bits to prevent
2553 // NARROW_U from saturating results.
2555  SelectionDAG &DAG) {
2556  EVT SrcVT = In.getValueType();
2557 
2558  // No truncation required, we might get here due to recursive calls.
2559  if (SrcVT == DstVT)
2560  return In;
2561 
2562  unsigned SrcSizeInBits = SrcVT.getSizeInBits();
2563  unsigned NumElems = SrcVT.getVectorNumElements();
2564  if (!isPowerOf2_32(NumElems))
2565  return SDValue();
2566  assert(DstVT.getVectorNumElements() == NumElems && "Illegal truncation");
2567  assert(SrcSizeInBits > DstVT.getSizeInBits() && "Illegal truncation");
2568 
2569  LLVMContext &Ctx = *DAG.getContext();
2570  EVT PackedSVT = EVT::getIntegerVT(Ctx, SrcVT.getScalarSizeInBits() / 2);
2571 
2572  // Narrow to the largest type possible:
2573  // vXi64/vXi32 -> i16x8.narrow_i32x4_u and vXi16 -> i8x16.narrow_i16x8_u.
2574  EVT InVT = MVT::i16, OutVT = MVT::i8;
2575  if (SrcVT.getScalarSizeInBits() > 16) {
2576  InVT = MVT::i32;
2577  OutVT = MVT::i16;
2578  }
2579  unsigned SubSizeInBits = SrcSizeInBits / 2;
2580  InVT = EVT::getVectorVT(Ctx, InVT, SubSizeInBits / InVT.getSizeInBits());
2581  OutVT = EVT::getVectorVT(Ctx, OutVT, SubSizeInBits / OutVT.getSizeInBits());
2582 
2583  // Split lower/upper subvectors.
2584  SDValue Lo = extractSubVector(In, 0, DAG, DL, SubSizeInBits);
2585  SDValue Hi = extractSubVector(In, NumElems / 2, DAG, DL, SubSizeInBits);
2586 
2587  // 256bit -> 128bit truncate - Narrow lower/upper 128-bit subvectors.
2588  if (SrcVT.is256BitVector() && DstVT.is128BitVector()) {
2589  Lo = DAG.getBitcast(InVT, Lo);
2590  Hi = DAG.getBitcast(InVT, Hi);
2591  SDValue Res = DAG.getNode(WebAssemblyISD::NARROW_U, DL, OutVT, Lo, Hi);
2592  return DAG.getBitcast(DstVT, Res);
2593  }
2594 
2595  // Recursively narrow lower/upper subvectors, concat result and narrow again.
2596  EVT PackedVT = EVT::getVectorVT(Ctx, PackedSVT, NumElems / 2);
2597  Lo = truncateVectorWithNARROW(PackedVT, Lo, DL, DAG);
2598  Hi = truncateVectorWithNARROW(PackedVT, Hi, DL, DAG);
2599 
2600  PackedVT = EVT::getVectorVT(Ctx, PackedSVT, NumElems);
2601  SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, DL, PackedVT, Lo, Hi);
2602  return truncateVectorWithNARROW(DstVT, Res, DL, DAG);
2603 }
2604 
2607  auto &DAG = DCI.DAG;
2608 
2609  SDValue In = N->getOperand(0);
2610  EVT InVT = In.getValueType();
2611  if (!InVT.isSimple())
2612  return SDValue();
2613 
2614  EVT OutVT = N->getValueType(0);
2615  if (!OutVT.isVector())
2616  return SDValue();
2617 
2618  EVT OutSVT = OutVT.getVectorElementType();
2619  EVT InSVT = InVT.getVectorElementType();
2620  // Currently only cover truncate to v16i8 or v8i16.
2621  if (!((InSVT == MVT::i16 || InSVT == MVT::i32 || InSVT == MVT::i64) &&
2622  (OutSVT == MVT::i8 || OutSVT == MVT::i16) && OutVT.is128BitVector()))
2623  return SDValue();
2624 
2625  SDLoc DL(N);
2627  OutVT.getScalarSizeInBits());
2628  In = DAG.getNode(ISD::AND, DL, InVT, In, DAG.getConstant(Mask, DL, InVT));
2629  return truncateVectorWithNARROW(OutVT, In, DL, DAG);
2630 }
2631 
2632 SDValue
2633 WebAssemblyTargetLowering::PerformDAGCombine(SDNode *N,
2634  DAGCombinerInfo &DCI) const {
2635  switch (N->getOpcode()) {
2636  default:
2637  return SDValue();
2638  case ISD::VECTOR_SHUFFLE:
2639  return performVECTOR_SHUFFLECombine(N, DCI);
2640  case ISD::SIGN_EXTEND:
2641  case ISD::ZERO_EXTEND:
2642  return performVectorExtendCombine(N, DCI);
2643  case ISD::FP_TO_SINT_SAT:
2644  case ISD::FP_TO_UINT_SAT:
2645  case ISD::FP_ROUND:
2646  case ISD::CONCAT_VECTORS:
2647  return performVectorTruncZeroCombine(N, DCI);
2648  case ISD::TRUNCATE:
2649  return performTruncateCombine(N, DCI);
2650  }
2651 }
llvm::TargetLoweringBase::getPreferredVectorAction
virtual TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const
Return the preferred vector type legalization action.
Definition: TargetLowering.h:459
IsWebAssemblyLocal
static Optional< unsigned > IsWebAssemblyLocal(SDValue Op, SelectionDAG &DAG)
Definition: WebAssemblyISelLowering.cpp:1452
llvm::MachineRegisterInfo::addLiveIn
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Definition: MachineRegisterInfo.h:959
llvm::SDNode::getConstantOperandVal
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
Definition: SelectionDAGNodes.h:1622
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(), AAResults *AA=nullptr)
Definition: SelectionDAG.cpp:7268
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:1437
performVectorExtendCombine
static SDValue performVectorExtendCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2359
llvm::LoadSDNode::getOffset
const SDValue & getOffset() const
Definition: SelectionDAGNodes.h:2362
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:360
performTruncateCombine
static SDValue performTruncateCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2605
llvm::StoreSDNode::getBasePtr
const SDValue & getBasePtr() const
Definition: SelectionDAGNodes.h:2392
llvm::less_second
Function object to check whether the second component of a std::pair compares less than the second co...
Definition: STLExtras.h:1340
llvm::TargetLoweringBase::setSchedulingPreference
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
Definition: TargetLowering.h:2272
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:531
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:689
llvm::ISD::SETO
@ SETO
Definition: ISDOpcodes.h:1433
llvm::Value::stripPointerCastsAndAliases
const Value * stripPointerCastsAndAliases() const
Strip off pointer casts, all-zero GEPs, address space casts, and aliases.
Definition: Value.cpp:689
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
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:18
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
llvm::CallingConv::WASM_EmscriptenInvoke
@ WASM_EmscriptenInvoke
For emscripten __invoke_* functions.
Definition: CallingConv.h:230
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:983
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:268
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1103
llvm::MVT::isFixedLengthVector
bool isFixedLengthVector() const
Definition: MachineValueType.h:388
llvm::CCValAssign::Full
@ Full
Definition: CallingConvLower.h:34
llvm::TargetLoweringBase::Legal
@ Legal
Definition: TargetLowering.h:195
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:360
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:991
PHI
Rewrite undef for PHI
Definition: AMDGPURewriteUndefForPHI.cpp:101
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:764
llvm::GlobalValue::LocalDynamicTLSModel
@ LocalDynamicTLSModel
Definition: GlobalValue.h:194
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:159
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:608
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:976
llvm::AtomicRMWInst::Xor
@ Xor
*p = old ^ v
Definition: Instructions.h:741
llvm::SDNode::isUndef
bool isUndef() const
Return true if the type of the node type undefined.
Definition: SelectionDAGNodes.h:665
llvm::SelectionDAG::getValueType
SDValue getValueType(EVT)
Definition: SelectionDAG.cpp:1839
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:60
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:192
llvm::AtomicRMWInst::getOperation
BinOp getOperation() const
Definition: Instructions.h:801
llvm::SelectionDAG::getFrameIndex
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
Definition: SelectionDAG.cpp:1720
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1181
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:376
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:1057
llvm::SelectionDAG::getVTList
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
Definition: SelectionDAG.cpp:9316
performVectorTruncZeroCombine
static SDValue performVectorTruncZeroCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition: WebAssemblyISelLowering.cpp:2406
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:2525
llvm::WebAssembly::isFuncrefType
bool isFuncrefType(const Type *Ty)
Definition: WebAssemblyTypeUtilities.h:72
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:1802
llvm::MemSDNode::getMemoryVT
EVT getMemoryVT() const
Return the type of the in-memory value.
Definition: SelectionDAGNodes.h:1354
llvm::MachineFunction::getFunctionNumber
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
Definition: MachineFunction.h:631
llvm::ISD::FLOG2
@ FLOG2
Definition: ISDOpcodes.h:920
llvm::MemSDNode::getChain
const SDValue & getChain() const
Definition: SelectionDAGNodes.h:1377
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:462
llvm::GlobalAddressSDNode::getTargetFlags
unsigned getTargetFlags() const
Definition: SelectionDAGNodes.h:1771
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:3854
llvm::LoadSDNode
This class is used to represent ISD::LOAD nodes.
Definition: SelectionDAGNodes.h:2342
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:272
llvm::MachineInstr::defs
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
Definition: MachineInstr.h:678
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:237
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:373
llvm::ISD::SETULE
@ SETULE
Definition: ISDOpcodes.h:1439
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:425
llvm::WebAssembly::WASM_ADDRESS_SPACE_EXTERNREF
@ WASM_ADDRESS_SPACE_EXTERNREF
Definition: WebAssemblyTypeUtilities.h:58
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:7976
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:11539
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:53
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:836
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:2334
Results
Function Alias Analysis Results
Definition: AliasAnalysis.cpp:830
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
WebAssemblyTargetMachine.h
llvm::ISD::VAEND
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1086
llvm::ISD::EXTLOAD
@ EXTLOAD
Definition: ISDOpcodes.h:1404
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:458
llvm::MVT::v2f64
@ v2f64
Definition: MachineValueType.h:180
llvm::Sched::Fast
@ Fast
Definition: TargetLowering.h:103
llvm::Triple::isOSEmscripten
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition: Triple.h:646
SelectionDAG.h
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
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:1435
llvm::ISD::SMAX
@ SMAX
Definition: ISDOpcodes.h:661
llvm::SelectionDAG::getContext
LLVMContext * getContext() const
Definition: SelectionDAG.h:476
llvm::NVPTX::PTXLdStInstCode::VecType
VecType
Definition: NVPTX.h:121
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
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:987
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:2474
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
llvm::MVT::integer_valuetypes
static auto integer_valuetypes()
Definition: MachineValueType.h:1472
llvm::MachineBasicBlock::addSuccessor
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Definition: MachineBasicBlock.cpp:762
llvm::ISD::FFLOOR
@ FFLOOR
Definition: ISDOpcodes.h:930
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:280
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::ISD::BR_CC
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1008
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:642
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:666
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:98
llvm::SelectionDAG::getTargetFrameIndex
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:717
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:1138
llvm::CallingConv::PreserveMost
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition: CallingConv.h:63
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::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::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:754
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:1002
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:1872
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:526
false
Function Alias Analysis false
Definition: AliasAnalysis.cpp:830
llvm::MVT::f64
@ f64
Definition: MachineValueType.h:58
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:1495
llvm::GlobalValue::getThreadLocalMode
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:265
llvm::JumpTableSDNode
Definition: SelectionDAGNodes.h:1860
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:3446
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::TargetLowering::DAGCombinerInfo
Definition: TargetLowering.h:3848
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:232
unrollVectorShift
static SDValue unrollVectorShift(SDValue Op, SelectionDAG &DAG)
Definition: WebAssemblyISelLowering.cpp:2254
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:611
llvm::ISD::UDIVREM
@ UDIVREM
Definition: ISDOpcodes.h:256
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
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:2319
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:197
llvm::MVT::v4f64
@ v4f64
Definition: MachineValueType.h:182
llvm::StoreSDNode::getOffset
const SDValue & getOffset() const
Definition: SelectionDAGNodes.h:2393
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
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:145
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:927
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:926
llvm::FrameIndexSDNode
Definition: SelectionDAGNodes.h:1783
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:7701
llvm::CallingConv::Cold
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
Definition: CallingConv.h:47
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
llvm::SmallVectorImpl::append
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:669
Align
uint64_t Align
Definition: ELFObjHandler.cpp:81
llvm::GlobalAddressSDNode::getGlobal
const GlobalValue * getGlobal() const
Definition: SelectionDAGNodes.h:1769
llvm::ISD::FSINCOS
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:960
llvm::TargetLoweringBase::TypeWidenVector
@ TypeWidenVector
Definition: TargetLowering.h:212
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:2267
llvm::Type::isFunctionTy
bool isFunctionTy() const
True if this is an instance of FunctionType.
Definition: Type.h:214
llvm::AtomicRMWInst::Xchg
@ Xchg
*p = v
Definition: Instructions.h:729
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:731
llvm::MVT::v4i16
@ v4i16
Definition: MachineValueType.h:99
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::CallingConv::Swift
@ Swift
Calling convention for Swift.
Definition: CallingConv.h:69
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::ISD::SETUGT
@ SETUGT
Definition: ISDOpcodes.h:1436
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:560
llvm::Sched::RegPressure
@ RegPressure
Definition: TargetLowering.h:99
llvm::SelectionDAG::getTargetGlobalAddress
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:712
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:475
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:647
llvm::MVT::isFloatingPoint
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: MachineValueType.h:350
llvm::ISD::FPOW
@ FPOW
Definition: ISDOpcodes.h:918
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:656
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::TargetLoweringBase::setOperationAction
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
Definition: TargetLowering.h:2336
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:956
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::MVT::v16i8
@ v16i8
Definition: MachineValueType.h:88
llvm::ISD::FLOG10
@ FLOG10
Definition: ISDOpcodes.h:921
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:416
llvm::AtomicRMWInst::Sub
@ Sub
*p = old - v
Definition: Instructions.h:733
Index
uint32_t Index
Definition: ELFObjHandler.cpp:82
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:126
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:1358
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:650
llvm::GlobalValue::GeneralDynamicTLSModel
@ GeneralDynamicTLSModel
Definition: GlobalValue.h:193
llvm::TargetLowering::verifyReturnAddressArgumentIsConstant
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
Definition: TargetLowering.cpp:6665
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:966
llvm::MVT::externref
@ externref
Definition: MachineValueType.h:281
llvm::SelectionDAG::getIntPtrConstant
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Definition: SelectionDAG.cpp:1615
llvm::TargetLoweringBase::Promote
@ Promote
Definition: TargetLowering.h:196
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:1133
llvm::MachinePointerInfo
This class contains a discriminated union of information about pointers in memory operands,...
Definition: MachineMemOperand.h:39
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
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:790
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:2285
llvm::SDNode::getOperand
const SDValue & getOperand(unsigned Num) const
Definition: SelectionDAGNodes.h:918
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::FrameIndexSDNode::getIndex
int getIndex() const
Definition: SelectionDAGNodes.h:1794
llvm::SelectionDAG::getNode
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
Definition: SelectionDAG.cpp:9010
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:739
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:1407
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:1770
llvm::MVT::v4f32
@ v4f32
Definition: MachineValueType.h:165
llvm::MachineMemOperand::Flags
Flags
Flags values. These may be or'd together.
Definition: MachineMemOperand.h:130
llvm::MVT::getVectorNumElements
unsigned getVectorNumElements() const
Definition: MachineValueType.h:876
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:2370
llvm::ISD::ZEXTLOAD
@ ZEXTLOAD
Definition: ISDOpcodes.h:1404
llvm::SDValue::getValue
SDValue getValue(unsigned R) const
Definition: SelectionDAGNodes.h:179
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:46
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:1919
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::CallingConv::CXX_FAST_TLS
@ CXX_FAST_TLS
Used for access functions.
Definition: CallingConv.h:72
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:890
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:672
llvm::ISD::SETULT
@ SETULT
Definition: ISDOpcodes.h:1438
llvm::ISD::DEBUGTRAP
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
Definition: ISDOpcodes.h:1136
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:9754
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:2205
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:66
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:2391
llvm::ISD::SRA_PARTS
@ SRA_PARTS
Definition: ISDOpcodes.h:750
llvm::ISD::VASTART
@ VASTART
Definition: ISDOpcodes.h:1087
WebAssemblyMachineFunctionInfo.h
_
#define _
Definition: HexagonMCCodeEmitter.cpp:47
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::WebAssemblyII::MO_MEMORY_BASE_REL
@ MO_MEMORY_BASE_REL
Definition: WebAssemblyMCTargetDesc.h:101
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
llvm::MVT::getVectorVT
static MVT getVectorVT(MVT VT, unsigned NumElements)
Definition: MachineValueType.h:1225
TargetOptions.h
llvm::ISD::FMAXIMUM
@ FMAXIMUM
Definition: ISDOpcodes.h:957
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:43
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:98
llvm::AArch64CC::GE
@ GE
Definition: AArch64BaseInfo.h:265
llvm::MVT::fixedlen_vector_valuetypes
static auto fixedlen_vector_valuetypes()
Definition: MachineValueType.h:1489
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:49
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:109
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
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:1009
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:516
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:163
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
uint32_t
llvm::WebAssemblySubtarget::hasBulkMemory
bool hasBulkMemory() const
Definition: WebAssemblySubtarget.h:99
llvm::CallingConv::Fast
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
llvm::MVT::is128BitVector
bool is128BitVector() const
Return true if this is a 128-bit vector type.
Definition: MachineValueType.h:417
llvm::SDValue::getOperand
const SDValue & getOperand(unsigned i) const
Definition: SelectionDAGNodes.h:1146
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:922
CC
auto CC
Definition: RISCVRedundantCopyElimination.cpp:79
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:1307
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:5266
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:2375
llvm::SDValue::getSimpleValueType
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
Definition: SelectionDAGNodes.h:190
llvm::MVT::v4i32
@ v4i32
Definition: MachineValueType.h:111
llvm::SDNode::ops
ArrayRef< SDUse > ops() const
Definition: SelectionDAGNodes.h:927
llvm::ISD::FEXP2
@ FEXP2
Definition: ISDOpcodes.h:923
llvm::SelectionDAG::getBasicBlock
SDValue getBasicBlock(MachineBasicBlock *MBB)
Definition: SelectionDAG.cpp:1825
llvm::MVT::iPTR
@ iPTR
Definition: MachineValueType.h:322
llvm::SDVTList
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
Definition: SelectionDAGNodes.h:79
llvm::MachineMemOperand::MOVolatile
@ MOVolatile
The memory access is volatile.
Definition: MachineMemOperand.h:138
llvm::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:1404
llvm::SelectionDAG::getBuildVector
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
Definition: SelectionDAG.h:819
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:1669
llvm::GlobalValue::LocalExecTLSModel
@ LocalExecTLSModel
Definition: GlobalValue.h:196
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:715
llvm::MachineMemOperand::MOLoad
@ MOLoad
The memory access reads data.
Definition: MachineMemOperand.h:134
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ISD::INTRINSIC_WO_CHAIN
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition: ISDOpcodes.h:184
llvm::LoadSDNode::getBasePtr
const SDValue & getBasePtr() const
Definition: SelectionDAGNodes.h:2361
llvm::SelectionDAG::getTargetJumpTable
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:722
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:1617
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:187
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::TargetLoweringBase::getTargetMachine
const TargetMachine & getTargetMachine() const
Definition: TargetLowering.h:346
callingConvSupported
static bool callingConvSupported(CallingConv::ID CallConv)
Definition: WebAssemblyISelLowering.cpp:949
llvm::LLVMContext::diagnose
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Definition: LLVMContext.cpp:248
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:65
llvm::ISD::ArgFlagsTy::getByValSize
unsigned getByValSize() const
Definition: TargetCallingConv.h:169
llvm::TargetLoweringBase::setLoadExtAction
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
Definition: TargetLowering.h:2353
llvm::GlobalAddressSDNode
Definition: SelectionDAGNodes.h:1757
llvm::KnownBits
Definition: KnownBits.h:23
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:622
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::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:11265
llvm::TargetLoweringBase::AtomicExpansionKind
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
Definition: TargetLowering.h:248
llvm::CallingConv::PreserveAll
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition: CallingConv.h:66
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:348
llvm::ISD::BR
@ BR
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:982
llvm::MemSDNode::getAddressSpace
unsigned getAddressSpace() const
Return the address space for the associated pointer.
Definition: SelectionDAGNodes.h:1365
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:916
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:545
llvm::ISD::FCEIL
@ FCEIL
Definition: ISDOpcodes.h:924
IsWebAssemblyGlobal
static bool IsWebAssemblyGlobal(SDValue Op)
Definition: WebAssemblyISelLowering.cpp:1445
llvm::ISD::FSIN
@ FSIN
Definition: ISDOpcodes.h:915
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:466
llvm::MVT::v8i16
@ v8i16
Definition: MachineValueType.h:100
llvm::AtomicRMWInst::And
@ And
*p = old & v
Definition: Instructions.h:735
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:926
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:199
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:1870
llvm::SelectionDAG::getMCSymbol
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
Definition: SelectionDAG.cpp:1861
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:48
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:204
llvm::ISD::SETUO
@ SETUO
Definition: ISDOpcodes.h:1434
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:225
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:145
llvm::ISD::SDIV
@ SDIV
Definition: ISDOpcodes.h:242
llvm::Function::getFunctionType
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:175
Conversion
X86 cmov Conversion
Definition: X86CmovConversion.cpp:874
llvm::TargetLoweringBase::ZeroOrOneBooleanContent
@ ZeroOrOneBooleanContent
Definition: TargetLowering.h:231
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::TargetLoweringBase::setLibcallName
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
Definition: TargetLowering.h:3103
llvm::ISD::STORE
@ STORE
Definition: ISDOpcodes.h:967
llvm::ISD::VACOPY
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1082
llvm::MachineMemOperand::MOStore
@ MOStore
The memory access writes data.
Definition: MachineMemOperand.h:136
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:1205
llvm::SDValue::isUndef
bool isUndef() const
Definition: SelectionDAGNodes.h:1174
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:2554
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:2253
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::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
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:1018
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:305
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:197
llvm::MVT::f16
@ f16
Definition: MachineValueType.h:56
llvm::WebAssembly::isWasmVarAddressSpace
bool isWasmVarAddressSpace(unsigned AS)
Definition: WebAssemblyTypeUtilities.h:66
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:1284
llvm::TargetLoweringBase::setMaxAtomicSizeInBitsSupported
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Definition: TargetLowering.h:2509
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:1989
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:85
llvm::ISD::ArgFlagsTy::isInConsecutiveRegs
bool isInConsecutiveRegs() const
Definition: TargetCallingConv.h:124
llvm::MVT::getVT
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:545
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:2436
llvm::GlobalAddressSDNode::getAddressSpace
unsigned getAddressSpace() const
Definition: SelectionDAG.cpp:11556
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:893
llvm::MachineFunction::getDataLayout
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Definition: MachineFunction.cpp:285
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:901
llvm::SDValue::getOpcode
unsigned getOpcode() const
Definition: SelectionDAGNodes.h:1134
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:666
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition: GlobalValue.h:290
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::ISD::SETONE
@ SETONE
Definition: ISDOpcodes.h:1432
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:47
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:463
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:171
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:1077
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:679
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::MVT::v8i8
@ v8i8
Definition: MachineValueType.h:87
llvm::GlobalValue::InitialExecTLSModel
@ InitialExecTLSModel
Definition: GlobalValue.h:195
llvm::ISD::FTRUNC
@ FTRUNC
Definition: ISDOpcodes.h:925
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:684
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:2794
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:1053
llvm::ISD::FLOG
@ FLOG
Definition: ISDOpcodes.h:919
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:57
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:467
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:69
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:353
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:7690
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:942
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:1202
llvm::MVT::integer_fixedlen_vector_valuetypes
static auto integer_fixedlen_vector_valuetypes()
Definition: MachineValueType.h:1501
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