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