LLVM  9.0.0svn
WebAssemblyISelLowering.cpp
Go to the documentation of this file.
1 //=- WebAssemblyISelLowering.cpp - WebAssembly DAG Lowering Implementation -==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements the WebAssemblyTargetLowering class.
12 ///
13 //===----------------------------------------------------------------------===//
14 
18 #include "WebAssemblySubtarget.h"
20 #include "llvm/CodeGen/Analysis.h"
28 #include "llvm/IR/DiagnosticInfo.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/IR/Intrinsics.h"
32 #include "llvm/Support/Debug.h"
36 using namespace llvm;
37 
38 #define DEBUG_TYPE "wasm-lower"
39 
41  const TargetMachine &TM, const WebAssemblySubtarget &STI)
42  : TargetLowering(TM), Subtarget(&STI) {
43  auto MVTPtr = Subtarget->hasAddr64() ? MVT::i64 : MVT::i32;
44 
45  // Booleans always contain 0 or 1.
47  // Except in SIMD vectors
49  // WebAssembly does not produce floating-point exceptions on normal floating
50  // point operations.
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  if (Subtarget->hasUnimplementedSIMD128()) {
68  addRegisterClass(MVT::v2i64, &WebAssembly::V128RegClass);
69  addRegisterClass(MVT::v2f64, &WebAssembly::V128RegClass);
70  }
71  }
72  // Compute derived properties from the register classes.
74 
80 
81  // Take the default expansion for va_arg, va_copy, and va_end. There is no
82  // default action for va_start, so we do that custom.
87 
88  for (auto T : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) {
89  // Don't expand the floating-point types to constant pools.
91  // Expand floating-point comparisons.
92  for (auto CC : {ISD::SETO, ISD::SETUO, ISD::SETUEQ, ISD::SETONE,
95  // Expand floating-point library function operators.
96  for (auto Op :
99  // Note supported floating-point library function operators that otherwise
100  // default to expand.
101  for (auto Op :
104  // Support minimum and maximum, which otherwise default to expand.
107  // WebAssembly currently has no builtin f16 support.
112  }
113 
114  // Support saturating add for i8x16 and i16x8
115  if (Subtarget->hasSIMD128())
116  for (auto T : {MVT::v16i8, MVT::v8i16})
117  for (auto Op : {ISD::SADDSAT, ISD::UADDSAT})
119 
120  // Expand unavailable integer operations.
121  for (auto Op :
125  for (auto T : {MVT::i32, MVT::i64}) {
127  }
128  if (Subtarget->hasSIMD128()) {
129  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32}) {
131  }
132  if (Subtarget->hasUnimplementedSIMD128()) {
134  }
135  }
136  }
137 
138  // There is no i64x2.mul instruction
140 
141  // We have custom shuffle lowering to expose the shuffle mask
142  if (Subtarget->hasSIMD128()) {
143  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32}) {
145  }
146  if (Subtarget->hasUnimplementedSIMD128()) {
149  }
150  }
151 
152  // Custom lowering since wasm shifts must have a scalar shift amount
153  if (Subtarget->hasSIMD128()) {
154  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
155  for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL})
157  if (Subtarget->hasUnimplementedSIMD128())
158  for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL})
160  }
161 
162  // There are no select instructions for vectors
163  if (Subtarget->hasSIMD128())
164  for (auto Op : {ISD::VSELECT, ISD::SELECT_CC, ISD::SELECT}) {
165  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32})
167  if (Subtarget->hasUnimplementedSIMD128())
168  for (auto T : {MVT::v2i64, MVT::v2f64})
170  }
171 
172  // As a special case, these operators use the type to mean the type to
173  // sign-extend from.
175  if (!Subtarget->hasSignExt()) {
176  // Sign extends are legal only when extending a vector extract
177  auto Action = Subtarget->hasSIMD128() ? Custom : Expand;
178  for (auto T : {MVT::i8, MVT::i16, MVT::i32})
180  }
181  for (auto T : MVT::integer_vector_valuetypes())
183 
184  // Dynamic stack allocation: use the default expansion.
188 
191 
192  // Expand these forms; we pattern-match the forms that we can handle in isel.
193  for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64})
194  for (auto Op : {ISD::BR_CC, ISD::SELECT_CC})
196 
197  // We have custom switch handling.
199 
200  // WebAssembly doesn't have:
201  // - Floating-point extending loads.
202  // - Floating-point truncating stores.
203  // - i1 extending loads.
204  // - extending/truncating SIMD loads/stores
207  for (auto T : MVT::integer_valuetypes())
210  if (Subtarget->hasSIMD128()) {
212  MVT::v2f64}) {
213  for (auto MemT : MVT::vector_valuetypes()) {
214  if (MVT(T) != MemT) {
215  setTruncStoreAction(T, MemT, Expand);
217  setLoadExtAction(Ext, T, MemT, Expand);
218  }
219  }
220  }
221  }
222 
223  // Expand additional SIMD ops that V8 hasn't implemented yet
224  if (Subtarget->hasSIMD128() && !Subtarget->hasUnimplementedSIMD128()) {
227  }
228 
229  // Custom lower lane accesses to expand out variable indices
230  if (Subtarget->hasSIMD128()) {
231  for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32}) {
234  }
235  if (Subtarget->hasUnimplementedSIMD128()) {
236  for (auto T : {MVT::v2i64, MVT::v2f64}) {
239  }
240  }
241  }
242 
243  // Trap lowers to wasm unreachable
245 
246  // Exception handling intrinsics
249 
251 }
252 
254 WebAssemblyTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
255  // We have wasm instructions for these
256  switch (AI->getOperation()) {
257  case AtomicRMWInst::Add:
258  case AtomicRMWInst::Sub:
259  case AtomicRMWInst::And:
260  case AtomicRMWInst::Or:
261  case AtomicRMWInst::Xor:
262  case AtomicRMWInst::Xchg:
264  default:
265  break;
266  }
268 }
269 
270 FastISel *WebAssemblyTargetLowering::createFastISel(
271  FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const {
272  return WebAssembly::createFastISel(FuncInfo, LibInfo);
273 }
274 
275 bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
276  const GlobalAddressSDNode * /*GA*/) const {
277  // All offsets can be folded.
278  return true;
279 }
280 
281 MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/,
282  EVT VT) const {
283  unsigned BitWidth = NextPowerOf2(VT.getSizeInBits() - 1);
284  if (BitWidth > 1 && BitWidth < 8)
285  BitWidth = 8;
286 
287  if (BitWidth > 64) {
288  // The shift will be lowered to a libcall, and compiler-rt libcalls expect
289  // the count to be an i32.
290  BitWidth = 32;
291  assert(BitWidth >= Log2_32_Ceil(VT.getSizeInBits()) &&
292  "32-bit shift counts ought to be enough for anyone");
293  }
294 
295  MVT Result = MVT::getIntegerVT(BitWidth);
297  "Unable to represent scalar shift amount type");
298  return Result;
299 }
300 
301 // Lower an fp-to-int conversion operator from the LLVM opcode, which has an
302 // undefined result on invalid/overflow, to the WebAssembly opcode, which
303 // traps on invalid/overflow.
305  MachineBasicBlock *BB,
306  const TargetInstrInfo &TII,
307  bool IsUnsigned, bool Int64,
308  bool Float64, unsigned LoweredOpcode) {
310 
311  unsigned OutReg = MI.getOperand(0).getReg();
312  unsigned InReg = MI.getOperand(1).getReg();
313 
314  unsigned Abs = Float64 ? WebAssembly::ABS_F64 : WebAssembly::ABS_F32;
315  unsigned FConst = Float64 ? WebAssembly::CONST_F64 : WebAssembly::CONST_F32;
316  unsigned LT = Float64 ? WebAssembly::LT_F64 : WebAssembly::LT_F32;
317  unsigned GE = Float64 ? WebAssembly::GE_F64 : WebAssembly::GE_F32;
318  unsigned IConst = Int64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
319  unsigned Eqz = WebAssembly::EQZ_I32;
320  unsigned And = WebAssembly::AND_I32;
321  int64_t Limit = Int64 ? INT64_MIN : INT32_MIN;
322  int64_t Substitute = IsUnsigned ? 0 : Limit;
323  double CmpVal = IsUnsigned ? -(double)Limit * 2.0 : -(double)Limit;
324  auto &Context = BB->getParent()->getFunction().getContext();
326 
327  const BasicBlock *LLVM_BB = BB->getBasicBlock();
328  MachineFunction *F = BB->getParent();
329  MachineBasicBlock *TrueMBB = F->CreateMachineBasicBlock(LLVM_BB);
330  MachineBasicBlock *FalseMBB = F->CreateMachineBasicBlock(LLVM_BB);
331  MachineBasicBlock *DoneMBB = F->CreateMachineBasicBlock(LLVM_BB);
332 
334  F->insert(It, FalseMBB);
335  F->insert(It, TrueMBB);
336  F->insert(It, DoneMBB);
337 
338  // Transfer the remainder of BB and its successor edges to DoneMBB.
339  DoneMBB->splice(DoneMBB->begin(), BB,
340  std::next(MachineBasicBlock::iterator(MI)), BB->end());
341  DoneMBB->transferSuccessorsAndUpdatePHIs(BB);
342 
343  BB->addSuccessor(TrueMBB);
344  BB->addSuccessor(FalseMBB);
345  TrueMBB->addSuccessor(DoneMBB);
346  FalseMBB->addSuccessor(DoneMBB);
347 
348  unsigned Tmp0, Tmp1, CmpReg, EqzReg, FalseReg, TrueReg;
349  Tmp0 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
350  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
351  CmpReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
352  EqzReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
353  FalseReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
354  TrueReg = MRI.createVirtualRegister(MRI.getRegClass(OutReg));
355 
356  MI.eraseFromParent();
357  // For signed numbers, we can do a single comparison to determine whether
358  // fabs(x) is within range.
359  if (IsUnsigned) {
360  Tmp0 = InReg;
361  } else {
362  BuildMI(BB, DL, TII.get(Abs), Tmp0).addReg(InReg);
363  }
364  BuildMI(BB, DL, TII.get(FConst), Tmp1)
365  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, CmpVal)));
366  BuildMI(BB, DL, TII.get(LT), CmpReg).addReg(Tmp0).addReg(Tmp1);
367 
368  // For unsigned numbers, we have to do a separate comparison with zero.
369  if (IsUnsigned) {
370  Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
371  unsigned SecondCmpReg =
372  MRI.createVirtualRegister(&WebAssembly::I32RegClass);
373  unsigned AndReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
374  BuildMI(BB, DL, TII.get(FConst), Tmp1)
375  .addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, 0.0)));
376  BuildMI(BB, DL, TII.get(GE), SecondCmpReg).addReg(Tmp0).addReg(Tmp1);
377  BuildMI(BB, DL, TII.get(And), AndReg).addReg(CmpReg).addReg(SecondCmpReg);
378  CmpReg = AndReg;
379  }
380 
381  BuildMI(BB, DL, TII.get(Eqz), EqzReg).addReg(CmpReg);
382 
383  // Create the CFG diamond to select between doing the conversion or using
384  // the substitute value.
385  BuildMI(BB, DL, TII.get(WebAssembly::BR_IF)).addMBB(TrueMBB).addReg(EqzReg);
386  BuildMI(FalseMBB, DL, TII.get(LoweredOpcode), FalseReg).addReg(InReg);
387  BuildMI(FalseMBB, DL, TII.get(WebAssembly::BR)).addMBB(DoneMBB);
388  BuildMI(TrueMBB, DL, TII.get(IConst), TrueReg).addImm(Substitute);
389  BuildMI(*DoneMBB, DoneMBB->begin(), DL, TII.get(TargetOpcode::PHI), OutReg)
390  .addReg(FalseReg)
391  .addMBB(FalseMBB)
392  .addReg(TrueReg)
393  .addMBB(TrueMBB);
394 
395  return DoneMBB;
396 }
397 
398 MachineBasicBlock *WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
399  MachineInstr &MI, MachineBasicBlock *BB) const {
400  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
401  DebugLoc DL = MI.getDebugLoc();
402 
403  switch (MI.getOpcode()) {
404  default:
405  llvm_unreachable("Unexpected instr type to insert");
406  case WebAssembly::FP_TO_SINT_I32_F32:
407  return LowerFPToInt(MI, DL, BB, TII, false, false, false,
408  WebAssembly::I32_TRUNC_S_F32);
409  case WebAssembly::FP_TO_UINT_I32_F32:
410  return LowerFPToInt(MI, DL, BB, TII, true, false, false,
411  WebAssembly::I32_TRUNC_U_F32);
412  case WebAssembly::FP_TO_SINT_I64_F32:
413  return LowerFPToInt(MI, DL, BB, TII, false, true, false,
414  WebAssembly::I64_TRUNC_S_F32);
415  case WebAssembly::FP_TO_UINT_I64_F32:
416  return LowerFPToInt(MI, DL, BB, TII, true, true, false,
417  WebAssembly::I64_TRUNC_U_F32);
418  case WebAssembly::FP_TO_SINT_I32_F64:
419  return LowerFPToInt(MI, DL, BB, TII, false, false, true,
420  WebAssembly::I32_TRUNC_S_F64);
421  case WebAssembly::FP_TO_UINT_I32_F64:
422  return LowerFPToInt(MI, DL, BB, TII, true, false, true,
423  WebAssembly::I32_TRUNC_U_F64);
424  case WebAssembly::FP_TO_SINT_I64_F64:
425  return LowerFPToInt(MI, DL, BB, TII, false, true, true,
426  WebAssembly::I64_TRUNC_S_F64);
427  case WebAssembly::FP_TO_UINT_I64_F64:
428  return LowerFPToInt(MI, DL, BB, TII, true, true, true,
429  WebAssembly::I64_TRUNC_U_F64);
430  llvm_unreachable("Unexpected instruction to emit with custom inserter");
431  }
432 }
433 
434 const char *
435 WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {
436  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
438  break;
439 #define HANDLE_NODETYPE(NODE) \
440  case WebAssemblyISD::NODE: \
441  return "WebAssemblyISD::" #NODE;
442 #include "WebAssemblyISD.def"
443 #undef HANDLE_NODETYPE
444  }
445  return nullptr;
446 }
447 
448 std::pair<unsigned, const TargetRegisterClass *>
449 WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
450  const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
451  // First, see if this is a constraint that directly corresponds to a
452  // WebAssembly register class.
453  if (Constraint.size() == 1) {
454  switch (Constraint[0]) {
455  case 'r':
456  assert(VT != MVT::iPTR && "Pointer MVT not expected here");
457  if (Subtarget->hasSIMD128() && VT.isVector()) {
458  if (VT.getSizeInBits() == 128)
459  return std::make_pair(0U, &WebAssembly::V128RegClass);
460  }
461  if (VT.isInteger() && !VT.isVector()) {
462  if (VT.getSizeInBits() <= 32)
463  return std::make_pair(0U, &WebAssembly::I32RegClass);
464  if (VT.getSizeInBits() <= 64)
465  return std::make_pair(0U, &WebAssembly::I64RegClass);
466  }
467  break;
468  default:
469  break;
470  }
471  }
472 
473  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
474 }
475 
476 bool WebAssemblyTargetLowering::isCheapToSpeculateCttz() const {
477  // Assume ctz is a relatively cheap operation.
478  return true;
479 }
480 
481 bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const {
482  // Assume clz is a relatively cheap operation.
483  return true;
484 }
485 
486 bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL,
487  const AddrMode &AM,
488  Type *Ty, unsigned AS,
489  Instruction *I) const {
490  // WebAssembly offsets are added as unsigned without wrapping. The
491  // isLegalAddressingMode gives us no way to determine if wrapping could be
492  // happening, so we approximate this by accepting only non-negative offsets.
493  if (AM.BaseOffs < 0)
494  return false;
495 
496  // WebAssembly has no scale register operands.
497  if (AM.Scale != 0)
498  return false;
499 
500  // Everything else is legal.
501  return true;
502 }
503 
504 bool WebAssemblyTargetLowering::allowsMisalignedMemoryAccesses(
505  EVT /*VT*/, unsigned /*AddrSpace*/, unsigned /*Align*/, bool *Fast) const {
506  // WebAssembly supports unaligned accesses, though it should be declared
507  // with the p2align attribute on loads and stores which do so, and there
508  // may be a performance impact. We tell LLVM they're "fast" because
509  // for the kinds of things that LLVM uses this for (merging adjacent stores
510  // of constants, etc.), WebAssembly implementations will either want the
511  // unaligned access or they'll split anyway.
512  if (Fast)
513  *Fast = true;
514  return true;
515 }
516 
517 bool WebAssemblyTargetLowering::isIntDivCheap(EVT VT,
518  AttributeList Attr) const {
519  // The current thinking is that wasm engines will perform this optimization,
520  // so we can save on code size.
521  return true;
522 }
523 
524 EVT WebAssemblyTargetLowering::getSetCCResultType(const DataLayout &DL,
525  LLVMContext &C,
526  EVT VT) const {
527  if (VT.isVector())
529 
530  return TargetLowering::getSetCCResultType(DL, C, VT);
531 }
532 
533 bool WebAssemblyTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
534  const CallInst &I,
535  MachineFunction &MF,
536  unsigned Intrinsic) const {
537  switch (Intrinsic) {
538  case Intrinsic::wasm_atomic_notify:
540  Info.memVT = MVT::i32;
541  Info.ptrVal = I.getArgOperand(0);
542  Info.offset = 0;
543  Info.align = 4;
544  // atomic.notify instruction does not really load the memory specified with
545  // this argument, but MachineMemOperand should either be load or store, so
546  // we set this to a load.
547  // FIXME Volatile isn't really correct, but currently all LLVM atomic
548  // instructions are treated as volatiles in the backend, so we should be
549  // consistent. The same applies for wasm_atomic_wait intrinsics too.
551  return true;
552  case Intrinsic::wasm_atomic_wait_i32:
554  Info.memVT = MVT::i32;
555  Info.ptrVal = I.getArgOperand(0);
556  Info.offset = 0;
557  Info.align = 4;
559  return true;
560  case Intrinsic::wasm_atomic_wait_i64:
562  Info.memVT = MVT::i64;
563  Info.ptrVal = I.getArgOperand(0);
564  Info.offset = 0;
565  Info.align = 8;
567  return true;
568  default:
569  return false;
570  }
571 }
572 
573 //===----------------------------------------------------------------------===//
574 // WebAssembly Lowering private implementation.
575 //===----------------------------------------------------------------------===//
576 
577 //===----------------------------------------------------------------------===//
578 // Lowering Code
579 //===----------------------------------------------------------------------===//
580 
581 static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *msg) {
583  DAG.getContext()->diagnose(
585 }
586 
587 // Test whether the given calling convention is supported.
588 static bool CallingConvSupported(CallingConv::ID CallConv) {
589  // We currently support the language-independent target-independent
590  // conventions. We don't yet have a way to annotate calls with properties like
591  // "cold", and we don't have any call-clobbered registers, so these are mostly
592  // all handled the same.
593  return CallConv == CallingConv::C || CallConv == CallingConv::Fast ||
594  CallConv == CallingConv::Cold ||
595  CallConv == CallingConv::PreserveMost ||
596  CallConv == CallingConv::PreserveAll ||
597  CallConv == CallingConv::CXX_FAST_TLS;
598 }
599 
600 SDValue
601 WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
602  SmallVectorImpl<SDValue> &InVals) const {
603  SelectionDAG &DAG = CLI.DAG;
604  SDLoc DL = CLI.DL;
605  SDValue Chain = CLI.Chain;
606  SDValue Callee = CLI.Callee;
608  auto Layout = MF.getDataLayout();
609 
610  CallingConv::ID CallConv = CLI.CallConv;
611  if (!CallingConvSupported(CallConv))
612  fail(DL, DAG,
613  "WebAssembly doesn't support language-specific or target-specific "
614  "calling conventions yet");
615  if (CLI.IsPatchPoint)
616  fail(DL, DAG, "WebAssembly doesn't support patch point yet");
617 
618  // WebAssembly doesn't currently support explicit tail calls. If they are
619  // required, fail. Otherwise, just disable them.
620  if ((CallConv == CallingConv::Fast && CLI.IsTailCall &&
622  (CLI.CS && CLI.CS.isMustTailCall()))
623  fail(DL, DAG, "WebAssembly doesn't support tail call yet");
624  CLI.IsTailCall = false;
625 
627  if (Ins.size() > 1)
628  fail(DL, DAG, "WebAssembly doesn't support more than 1 returned value yet");
629 
630  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
631  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
632  unsigned NumFixedArgs = 0;
633  for (unsigned i = 0; i < Outs.size(); ++i) {
634  const ISD::OutputArg &Out = Outs[i];
635  SDValue &OutVal = OutVals[i];
636  if (Out.Flags.isNest())
637  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
638  if (Out.Flags.isInAlloca())
639  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
640  if (Out.Flags.isInConsecutiveRegs())
641  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
642  if (Out.Flags.isInConsecutiveRegsLast())
643  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
644  if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
645  auto &MFI = MF.getFrameInfo();
646  int FI = MFI.CreateStackObject(Out.Flags.getByValSize(),
647  Out.Flags.getByValAlign(),
648  /*isSS=*/false);
649  SDValue SizeNode =
650  DAG.getConstant(Out.Flags.getByValSize(), DL, MVT::i32);
651  SDValue FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
652  Chain = DAG.getMemcpy(
653  Chain, DL, FINode, OutVal, SizeNode, Out.Flags.getByValAlign(),
654  /*isVolatile*/ false, /*AlwaysInline=*/false,
655  /*isTailCall*/ false, MachinePointerInfo(), MachinePointerInfo());
656  OutVal = FINode;
657  }
658  // Count the number of fixed args *after* legalization.
659  NumFixedArgs += Out.IsFixed;
660  }
661 
662  bool IsVarArg = CLI.IsVarArg;
663  auto PtrVT = getPointerTy(Layout);
664 
665  // Analyze operands of the call, assigning locations to each operand.
667  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
668 
669  if (IsVarArg) {
670  // Outgoing non-fixed arguments are placed in a buffer. First
671  // compute their offsets and the total amount of buffer space needed.
672  for (SDValue Arg :
673  make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) {
674  EVT VT = Arg.getValueType();
675  assert(VT != MVT::iPTR && "Legalized args should be concrete");
676  Type *Ty = VT.getTypeForEVT(*DAG.getContext());
677  unsigned Offset = CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty),
678  Layout.getABITypeAlignment(Ty));
679  CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(),
680  Offset, VT.getSimpleVT(),
682  }
683  }
684 
685  unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
686 
687  SDValue FINode;
688  if (IsVarArg && NumBytes) {
689  // For non-fixed arguments, next emit stores to store the argument values
690  // to the stack buffer at the offsets computed above.
691  int FI = MF.getFrameInfo().CreateStackObject(NumBytes,
692  Layout.getStackAlignment(),
693  /*isSS=*/false);
694  unsigned ValNo = 0;
696  for (SDValue Arg :
697  make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) {
698  assert(ArgLocs[ValNo].getValNo() == ValNo &&
699  "ArgLocs should remain in order and only hold varargs args");
700  unsigned Offset = ArgLocs[ValNo++].getLocMemOffset();
701  FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
702  SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, FINode,
703  DAG.getConstant(Offset, DL, PtrVT));
704  Chains.push_back(
705  DAG.getStore(Chain, DL, Arg, Add,
706  MachinePointerInfo::getFixedStack(MF, FI, Offset), 0));
707  }
708  if (!Chains.empty())
709  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
710  } else if (IsVarArg) {
711  FINode = DAG.getIntPtrConstant(0, DL);
712  }
713 
714  // Compute the operands for the CALLn node.
716  Ops.push_back(Chain);
717  Ops.push_back(Callee);
718 
719  // Add all fixed arguments. Note that for non-varargs calls, NumFixedArgs
720  // isn't reliable.
721  Ops.append(OutVals.begin(),
722  IsVarArg ? OutVals.begin() + NumFixedArgs : OutVals.end());
723  // Add a pointer to the vararg buffer.
724  if (IsVarArg)
725  Ops.push_back(FINode);
726 
727  SmallVector<EVT, 8> InTys;
728  for (const auto &In : Ins) {
729  assert(!In.Flags.isByVal() && "byval is not valid for return values");
730  assert(!In.Flags.isNest() && "nest is not valid for return values");
731  if (In.Flags.isInAlloca())
732  fail(DL, DAG, "WebAssembly hasn't implemented inalloca return values");
733  if (In.Flags.isInConsecutiveRegs())
734  fail(DL, DAG, "WebAssembly hasn't implemented cons regs return values");
735  if (In.Flags.isInConsecutiveRegsLast())
736  fail(DL, DAG,
737  "WebAssembly hasn't implemented cons regs last return values");
738  // Ignore In.getOrigAlign() because all our arguments are passed in
739  // registers.
740  InTys.push_back(In.VT);
741  }
742  InTys.push_back(MVT::Other);
743  SDVTList InTyList = DAG.getVTList(InTys);
744  SDValue Res =
745  DAG.getNode(Ins.empty() ? WebAssemblyISD::CALL0 : WebAssemblyISD::CALL1,
746  DL, InTyList, Ops);
747  if (Ins.empty()) {
748  Chain = Res;
749  } else {
750  InVals.push_back(Res);
751  Chain = Res.getValue(1);
752  }
753 
754  return Chain;
755 }
756 
757 bool WebAssemblyTargetLowering::CanLowerReturn(
758  CallingConv::ID /*CallConv*/, MachineFunction & /*MF*/, bool /*IsVarArg*/,
760  LLVMContext & /*Context*/) const {
761  // WebAssembly can't currently handle returning tuples.
762  return Outs.size() <= 1;
763 }
764 
765 SDValue WebAssemblyTargetLowering::LowerReturn(
766  SDValue Chain, CallingConv::ID CallConv, bool /*IsVarArg*/,
768  const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
769  SelectionDAG &DAG) const {
770  assert(Outs.size() <= 1 && "WebAssembly can only return up to one value");
771  if (!CallingConvSupported(CallConv))
772  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
773 
774  SmallVector<SDValue, 4> RetOps(1, Chain);
775  RetOps.append(OutVals.begin(), OutVals.end());
776  Chain = DAG.getNode(WebAssemblyISD::RETURN, DL, MVT::Other, RetOps);
777 
778  // Record the number and types of the return values.
779  for (const ISD::OutputArg &Out : Outs) {
780  assert(!Out.Flags.isByVal() && "byval is not valid for return values");
781  assert(!Out.Flags.isNest() && "nest is not valid for return values");
782  assert(Out.IsFixed && "non-fixed return value is not valid");
783  if (Out.Flags.isInAlloca())
784  fail(DL, DAG, "WebAssembly hasn't implemented inalloca results");
785  if (Out.Flags.isInConsecutiveRegs())
786  fail(DL, DAG, "WebAssembly hasn't implemented cons regs results");
787  if (Out.Flags.isInConsecutiveRegsLast())
788  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results");
789  }
790 
791  return Chain;
792 }
793 
794 SDValue WebAssemblyTargetLowering::LowerFormalArguments(
795  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
796  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
797  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
798  if (!CallingConvSupported(CallConv))
799  fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
800 
802  auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
803 
804  // Set up the incoming ARGUMENTS value, which serves to represent the liveness
805  // of the incoming values before they're represented by virtual registers.
806  MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
807 
808  for (const ISD::InputArg &In : Ins) {
809  if (In.Flags.isInAlloca())
810  fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments");
811  if (In.Flags.isNest())
812  fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
813  if (In.Flags.isInConsecutiveRegs())
814  fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments");
815  if (In.Flags.isInConsecutiveRegsLast())
816  fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
817  // Ignore In.getOrigAlign() because all our arguments are passed in
818  // registers.
819  InVals.push_back(In.Used ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
820  DAG.getTargetConstant(InVals.size(),
821  DL, MVT::i32))
822  : DAG.getUNDEF(In.VT));
823 
824  // Record the number and types of arguments.
825  MFI->addParam(In.VT);
826  }
827 
828  // Varargs are copied into a buffer allocated by the caller, and a pointer to
829  // the buffer is passed as an argument.
830  if (IsVarArg) {
831  MVT PtrVT = getPointerTy(MF.getDataLayout());
832  unsigned VarargVreg =
834  MFI->setVarargBufferVreg(VarargVreg);
835  Chain = DAG.getCopyToReg(
836  Chain, DL, VarargVreg,
837  DAG.getNode(WebAssemblyISD::ARGUMENT, DL, PtrVT,
838  DAG.getTargetConstant(Ins.size(), DL, MVT::i32)));
839  MFI->addParam(PtrVT);
840  }
841 
842  // Record the number and types of arguments and results.
843  SmallVector<MVT, 4> Params;
846  DAG.getTarget(), Params, Results);
847  for (MVT VT : Results)
848  MFI->addResult(VT);
849  // TODO: Use signatures in WebAssemblyMachineFunctionInfo too and unify
850  // the param logic here with ComputeSignatureVTs
851  assert(MFI->getParams().size() == Params.size() &&
852  std::equal(MFI->getParams().begin(), MFI->getParams().end(),
853  Params.begin()));
854 
855  return Chain;
856 }
857 
858 //===----------------------------------------------------------------------===//
859 // Custom lowering hooks.
860 //===----------------------------------------------------------------------===//
861 
862 SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
863  SelectionDAG &DAG) const {
864  SDLoc DL(Op);
865  switch (Op.getOpcode()) {
866  default:
867  llvm_unreachable("unimplemented operation lowering");
868  return SDValue();
869  case ISD::FrameIndex:
870  return LowerFrameIndex(Op, DAG);
871  case ISD::GlobalAddress:
872  return LowerGlobalAddress(Op, DAG);
873  case ISD::ExternalSymbol:
874  return LowerExternalSymbol(Op, DAG);
875  case ISD::JumpTable:
876  return LowerJumpTable(Op, DAG);
877  case ISD::BR_JT:
878  return LowerBR_JT(Op, DAG);
879  case ISD::VASTART:
880  return LowerVASTART(Op, DAG);
881  case ISD::BlockAddress:
882  case ISD::BRIND:
883  fail(DL, DAG, "WebAssembly hasn't implemented computed gotos");
884  return SDValue();
885  case ISD::RETURNADDR: // Probably nothing meaningful can be returned here.
886  fail(DL, DAG, "WebAssembly hasn't implemented __builtin_return_address");
887  return SDValue();
888  case ISD::FRAMEADDR:
889  return LowerFRAMEADDR(Op, DAG);
890  case ISD::CopyToReg:
891  return LowerCopyToReg(Op, DAG);
893  return LowerINTRINSIC_WO_CHAIN(Op, DAG);
896  return LowerAccessVectorElement(Op, DAG);
897  case ISD::INTRINSIC_VOID:
898  return LowerINTRINSIC_VOID(Op, DAG);
900  return LowerSIGN_EXTEND_INREG(Op, DAG);
901  case ISD::VECTOR_SHUFFLE:
902  return LowerVECTOR_SHUFFLE(Op, DAG);
903  case ISD::SHL:
904  case ISD::SRA:
905  case ISD::SRL:
906  return LowerShift(Op, DAG);
907  }
908 }
909 
910 SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op,
911  SelectionDAG &DAG) const {
912  SDValue Src = Op.getOperand(2);
913  if (isa<FrameIndexSDNode>(Src.getNode())) {
914  // CopyToReg nodes don't support FrameIndex operands. Other targets select
915  // the FI to some LEA-like instruction, but since we don't have that, we
916  // need to insert some kind of instruction that can take an FI operand and
917  // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
918  // local.copy between Op and its FI operand.
919  SDValue Chain = Op.getOperand(0);
920  SDLoc DL(Op);
921  unsigned Reg = cast<RegisterSDNode>(Op.getOperand(1))->getReg();
922  EVT VT = Src.getValueType();
923  SDValue Copy(DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_I32
924  : WebAssembly::COPY_I64,
925  DL, VT, Src),
926  0);
927  return Op.getNode()->getNumValues() == 1
928  ? DAG.getCopyToReg(Chain, DL, Reg, Copy)
929  : DAG.getCopyToReg(Chain, DL, Reg, Copy,
930  Op.getNumOperands() == 4 ? Op.getOperand(3)
931  : SDValue());
932  }
933  return SDValue();
934 }
935 
936 SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op,
937  SelectionDAG &DAG) const {
938  int FI = cast<FrameIndexSDNode>(Op)->getIndex();
939  return DAG.getTargetFrameIndex(FI, Op.getValueType());
940 }
941 
942 SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op,
943  SelectionDAG &DAG) const {
944  // Non-zero depths are not supported by WebAssembly currently. Use the
945  // legalizer's default expansion, which is to return 0 (what this function is
946  // documented to do).
947  if (Op.getConstantOperandVal(0) > 0)
948  return SDValue();
949 
951  EVT VT = Op.getValueType();
952  unsigned FP =
954  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT);
955 }
956 
957 SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
958  SelectionDAG &DAG) const {
959  SDLoc DL(Op);
960  const auto *GA = cast<GlobalAddressSDNode>(Op);
961  EVT VT = Op.getValueType();
962  assert(GA->getTargetFlags() == 0 &&
963  "Unexpected target flags on generic GlobalAddressSDNode");
964  if (GA->getAddressSpace() != 0)
965  fail(DL, DAG, "WebAssembly only expects the 0 address space");
966  return DAG.getNode(
967  WebAssemblyISD::Wrapper, DL, VT,
968  DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset()));
969 }
970 
971 SDValue
972 WebAssemblyTargetLowering::LowerExternalSymbol(SDValue Op,
973  SelectionDAG &DAG) const {
974  SDLoc DL(Op);
975  const auto *ES = cast<ExternalSymbolSDNode>(Op);
976  EVT VT = Op.getValueType();
977  assert(ES->getTargetFlags() == 0 &&
978  "Unexpected target flags on generic ExternalSymbolSDNode");
979  // Set the TargetFlags to 0x1 which indicates that this is a "function"
980  // symbol rather than a data symbol. We do this unconditionally even though
981  // we don't know anything about the symbol other than its name, because all
982  // external symbols used in target-independent SelectionDAG code are for
983  // functions.
984  return DAG.getNode(
985  WebAssemblyISD::Wrapper, DL, VT,
986  DAG.getTargetExternalSymbol(ES->getSymbol(), VT,
988 }
989 
990 SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
991  SelectionDAG &DAG) const {
992  // There's no need for a Wrapper node because we always incorporate a jump
993  // table operand into a BR_TABLE instruction, rather than ever
994  // materializing it in a register.
995  const JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
996  return DAG.getTargetJumpTable(JT->getIndex(), Op.getValueType(),
997  JT->getTargetFlags());
998 }
999 
1000 SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op,
1001  SelectionDAG &DAG) const {
1002  SDLoc DL(Op);
1003  SDValue Chain = Op.getOperand(0);
1004  const auto *JT = cast<JumpTableSDNode>(Op.getOperand(1));
1005  SDValue Index = Op.getOperand(2);
1006  assert(JT->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
1007 
1009  Ops.push_back(Chain);
1010  Ops.push_back(Index);
1011 
1013  const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs;
1014 
1015  // Add an operand for each case.
1016  for (auto MBB : MBBs)
1017  Ops.push_back(DAG.getBasicBlock(MBB));
1018 
1019  // TODO: For now, we just pick something arbitrary for a default case for now.
1020  // We really want to sniff out the guard and put in the real default case (and
1021  // delete the guard).
1022  Ops.push_back(DAG.getBasicBlock(MBBs[0]));
1023 
1024  return DAG.getNode(WebAssemblyISD::BR_TABLE, DL, MVT::Other, Ops);
1025 }
1026 
1027 SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op,
1028  SelectionDAG &DAG) const {
1029  SDLoc DL(Op);
1031 
1032  auto *MFI = DAG.getMachineFunction().getInfo<WebAssemblyFunctionInfo>();
1033  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1034 
1035  SDValue ArgN = DAG.getCopyFromReg(DAG.getEntryNode(), DL,
1036  MFI->getVarargBufferVreg(), PtrVT);
1037  return DAG.getStore(Op.getOperand(0), DL, ArgN, Op.getOperand(1),
1038  MachinePointerInfo(SV), 0);
1039 }
1040 
1041 SDValue
1042 WebAssemblyTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
1043  SelectionDAG &DAG) const {
1044  unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1045  SDLoc DL(Op);
1046  switch (IntNo) {
1047  default:
1048  return {}; // Don't custom lower most intrinsics.
1049 
1050  case Intrinsic::wasm_lsda: {
1051  MachineFunction &MF = DAG.getMachineFunction();
1052  EVT VT = Op.getValueType();
1053  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1054  MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
1055  auto &Context = MF.getMMI().getContext();
1056  MCSymbol *S = Context.getOrCreateSymbol(Twine("GCC_except_table") +
1057  Twine(MF.getFunctionNumber()));
1058  return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
1059  DAG.getMCSymbol(S, PtrVT));
1060  }
1061  }
1062 }
1063 
1064 SDValue
1065 WebAssemblyTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
1066  SelectionDAG &DAG) const {
1067  MachineFunction &MF = DAG.getMachineFunction();
1068  unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
1069  SDLoc DL(Op);
1070 
1071  switch (IntNo) {
1072  default:
1073  return {}; // Don't custom lower most intrinsics.
1074 
1075  case Intrinsic::wasm_throw: {
1076  int Tag = cast<ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
1077  switch (Tag) {
1078  case CPP_EXCEPTION: {
1079  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1080  MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
1081  const char *SymName = MF.createExternalSymbolName("__cpp_exception");
1082  SDValue SymNode =
1083  DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
1085  SymName, PtrVT, WebAssemblyII::MO_SYMBOL_EVENT));
1086  return DAG.getNode(WebAssemblyISD::THROW, DL,
1087  MVT::Other, // outchain type
1088  {
1089  Op.getOperand(0), // inchain
1090  SymNode, // exception symbol
1091  Op.getOperand(3) // thrown value
1092  });
1093  }
1094  default:
1095  llvm_unreachable("Invalid tag!");
1096  }
1097  break;
1098  }
1099  }
1100 }
1101 
1102 SDValue
1103 WebAssemblyTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
1104  SelectionDAG &DAG) const {
1105  // If sign extension operations are disabled, allow sext_inreg only if operand
1106  // is a vector extract. SIMD does not depend on sign extension operations, but
1107  // allowing sext_inreg in this context lets us have simple patterns to select
1108  // extract_lane_s instructions. Expanding sext_inreg everywhere would be
1109  // simpler in this file, but would necessitate large and brittle patterns to
1110  // undo the expansion and select extract_lane_s instructions.
1111  assert(!Subtarget->hasSignExt() && Subtarget->hasSIMD128());
1113  return Op;
1114  // Otherwise expand
1115  return SDValue();
1116 }
1117 
1118 SDValue
1119 WebAssemblyTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
1120  SelectionDAG &DAG) const {
1121  SDLoc DL(Op);
1122  ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Op.getNode())->getMask();
1124  assert(VecType.is128BitVector() && "Unexpected shuffle vector type");
1125  size_t LaneBytes = VecType.getVectorElementType().getSizeInBits() / 8;
1126 
1127  // Space for two vector args and sixteen mask indices
1128  SDValue Ops[18];
1129  size_t OpIdx = 0;
1130  Ops[OpIdx++] = Op.getOperand(0);
1131  Ops[OpIdx++] = Op.getOperand(1);
1132 
1133  // Expand mask indices to byte indices and materialize them as operands
1134  for (size_t I = 0, Lanes = Mask.size(); I < Lanes; ++I) {
1135  for (size_t J = 0; J < LaneBytes; ++J) {
1136  // Lower undefs (represented by -1 in mask) to zero
1137  uint64_t ByteIndex =
1138  Mask[I] == -1 ? 0 : (uint64_t)Mask[I] * LaneBytes + J;
1139  Ops[OpIdx++] = DAG.getConstant(ByteIndex, DL, MVT::i32);
1140  }
1141  }
1142 
1143  return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
1144 }
1145 
1146 SDValue
1147 WebAssemblyTargetLowering::LowerAccessVectorElement(SDValue Op,
1148  SelectionDAG &DAG) const {
1149  // Allow constant lane indices, expand variable lane indices
1150  SDNode *IdxNode = Op.getOperand(Op.getNumOperands() - 1).getNode();
1151  if (isa<ConstantSDNode>(IdxNode) || IdxNode->isUndef())
1152  return Op;
1153  else
1154  // Perform default expansion
1155  return SDValue();
1156 }
1157 
1160  // 32-bit and 64-bit unrolled shifts will have proper semantics
1161  if (LaneT.bitsGE(MVT::i32))
1162  return DAG.UnrollVectorOp(Op.getNode());
1163  // Otherwise mask the shift value to get proper semantics from 32-bit shift
1164  SDLoc DL(Op);
1165  SDValue ShiftVal = Op.getOperand(1);
1166  uint64_t MaskVal = LaneT.getSizeInBits() - 1;
1167  SDValue MaskedShiftVal = DAG.getNode(
1168  ISD::AND, // mask opcode
1169  DL, ShiftVal.getValueType(), // masked value type
1170  ShiftVal, // original shift value operand
1171  DAG.getConstant(MaskVal, DL, ShiftVal.getValueType()) // mask operand
1172  );
1173 
1174  return DAG.UnrollVectorOp(
1175  DAG.getNode(Op.getOpcode(), // original shift opcode
1176  DL, Op.getValueType(), // original return type
1177  Op.getOperand(0), // original vector operand,
1178  MaskedShiftVal // new masked shift value operand
1179  )
1180  .getNode());
1181 }
1182 
1183 SDValue WebAssemblyTargetLowering::LowerShift(SDValue Op,
1184  SelectionDAG &DAG) const {
1185  SDLoc DL(Op);
1186 
1187  // Only manually lower vector shifts
1189 
1190  // Expand all vector shifts until V8 fixes its implementation
1191  // TODO: remove this once V8 is fixed
1192  if (!Subtarget->hasUnimplementedSIMD128())
1193  return UnrollVectorShift(Op, DAG);
1194 
1195  // Unroll non-splat vector shifts
1196  BuildVectorSDNode *ShiftVec;
1197  SDValue SplatVal;
1198  if (!(ShiftVec = dyn_cast<BuildVectorSDNode>(Op.getOperand(1).getNode())) ||
1199  !(SplatVal = ShiftVec->getSplatValue()))
1200  return UnrollVectorShift(Op, DAG);
1201 
1202  // All splats except i64x2 const splats are handled by patterns
1203  ConstantSDNode *SplatConst = dyn_cast<ConstantSDNode>(SplatVal);
1204  if (!SplatConst || Op.getSimpleValueType() != MVT::v2i64)
1205  return Op;
1206 
1207  // i64x2 const splats are custom lowered to avoid unnecessary wraps
1208  unsigned Opcode;
1209  switch (Op.getOpcode()) {
1210  case ISD::SHL:
1211  Opcode = WebAssemblyISD::VEC_SHL;
1212  break;
1213  case ISD::SRA:
1214  Opcode = WebAssemblyISD::VEC_SHR_S;
1215  break;
1216  case ISD::SRL:
1217  Opcode = WebAssemblyISD::VEC_SHR_U;
1218  break;
1219  default:
1220  llvm_unreachable("unexpected opcode");
1221  }
1222  APInt Shift = SplatConst->getAPIntValue().zextOrTrunc(32);
1223  return DAG.getNode(Opcode, DL, Op.getValueType(), Op.getOperand(0),
1224  DAG.getConstant(Shift, DL, MVT::i32));
1225 }
1226 
1227 //===----------------------------------------------------------------------===//
1228 // WebAssembly Optimization Hooks
1229 //===----------------------------------------------------------------------===//
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
void setFrameAddressIsTaken(bool T)
uint64_t CallInst * C
static MVT getIntegerVT(unsigned BitWidth)
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:552
This file defines the interfaces that WebAssembly uses to lower LLVM code into a selection DAG...
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isInteger() const
Return true if this is an integer or a vector integer type.
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...
static Type * getDoubleTy(LLVMContext &C)
Definition: Type.cpp:165
const std::vector< MachineJumpTableEntry > & getJumpTables() const
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:35
LLVMContext & Context
Diagnostic information for unsupported feature in backend.
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:650
This class represents lattice values for constants.
Definition: AllocatorList.h:24
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0...
Definition: ISDOpcodes.h:605
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition: ISDOpcodes.h:367
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
bool isVector() const
Return true if this is a vector value type.
void addLiveIn(unsigned Reg, unsigned vreg=0)
addLiveIn - Add the specified register as a live-in.
Carry-setting nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:223
static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *msg)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:383
unsigned getReg() const
getReg - Returns the register number.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain...
Definition: ISDOpcodes.h:699
This class represents a function call, abstracting a target machine&#39;s calling convention.
unsigned Reg
void setHasFloatingPointExceptions(bool FPExceptions=true)
Tells the code generator that this target supports floating point exceptions and cares about preservi...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:253
SDValue getBasicBlock(MachineBasicBlock *MBB)
Function Alias Analysis Results
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
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...
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
Return the register class that should be used for the specified value type.
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:34
F(f)
MachineModuleInfo & getMMI() const
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition: APInt.cpp:876
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
Definition: Instructions.h:692
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
int CreateStackObject(uint64_t Size, unsigned 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...
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:435
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition: ISDOpcodes.h:159
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:210
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1135
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations...
Definition: ISDOpcodes.h:456
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
static SDValue UnrollVectorShift(SDValue Op, SelectionDAG &DAG)
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
const HexagonInstrInfo * TII
static Type * getFloatTy(LLVMContext &C)
Definition: Type.cpp:164
#define INT64_MIN
Definition: DataTypes.h:80
Shift and rotation operations.
Definition: ISDOpcodes.h:410
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:202
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), MachineInstr opcode, and operands.
BinOp getOperation() const
Definition: Instructions.h:745
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
CopyToReg - This node has three operands: a chain, a register number to set to this value...
Definition: ISDOpcodes.h:170
uint64_t getConstantOperandVal(unsigned i) const
void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn&#39;t supported on the target and indicate what to d...
bool isInConsecutiveRegs() const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:460
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...
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:401
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG...
Definition: ISDOpcodes.h:73
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
This represents a list of ValueType&#39;s that has been intern&#39;d by a SelectionDAG.
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:695
unsigned getSizeInBits() const
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:43
This is a fast-path instruction selection class that generates poor code and doesn&#39;t support illegal ...
Definition: FastISel.h:67
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:292
This file declares the WebAssembly-specific subclass of TargetMachine.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:398
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose...
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:628
const TargetMachine & getTarget() const
Definition: SelectionDAG.h:402
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition: ISDOpcodes.h:429
const MCContext & getContext() const
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:201
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
Definition: SelectionDAG.h:852
static mvt_range integer_vector_valuetypes()
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:576
amdgpu Simplify well known AMD library false Value * Callee
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition: ISDOpcodes.h:151
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
MVT getVectorElementType() const
Analysis containing CSE Info
Definition: CSEInfo.cpp:21
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
unsigned getByValSize() const
bool IsFixed
IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
TargetInstrInfo - Interface to description of machine instruction set.
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
The memory access is volatile.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
Definition: ValueTypes.h:235
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition: ISDOpcodes.h:166
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:629
static bool CallingConvSupported(CallingConv::ID CallConv)
unsigned const MachineRegisterInfo * MRI
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...
Machine Value Type.
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE...
Definition: ISDOpcodes.h:728
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:129
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL...
Definition: ISDOpcodes.h:332
SDValue getSplatValue(BitVector *UndefElements=nullptr) const
Returns the splatted value or a null value if this is not a splat.
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:232
This file provides WebAssembly-specific target descriptions.
unsigned char getTargetFlags() const
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:767
const APInt & getAPIntValue() const
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline...
static mvt_range vector_valuetypes()
self_iterator getIterator()
Definition: ilist_node.h:82
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:719
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:193
static unsigned NumFixedArgs
Extended Value Type.
Definition: ValueTypes.h:34
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition: MathExtras.h:640
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:53
This class contains a discriminated union of information about pointers in memory operands...
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
WebAssemblyTargetLowering(const TargetMachine &TM, const WebAssemblySubtarget &STI)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition: ISDOpcodes.h:265
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags=0)
Definition: SelectionDAG.h:633
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:50
static MachineBasicBlock * LowerFPToInt(MachineInstr &MI, DebugLoc DL, MachineBasicBlock *BB, const TargetInstrInfo &TII, bool IsUnsigned, bool Int64, bool Float64, unsigned LoweredOpcode)
This file declares the WebAssembly-specific subclass of TargetSubtarget.
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:404
Iterator for intrusive lists based on ilist_node.
CCState - This class holds information needed while lowering arguments and return values...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition: ISDOpcodes.h:339
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:222
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
Provides information about what library functions are available for the current target.
const DebugLoc & getDebugLoc() const
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition: ValueTypes.h:96
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:413
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition: ISDOpcodes.h:581
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
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:685
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:679
const Function & getFunction() const
Return the LLVM function that this machine code represents.
static mvt_range integer_valuetypes()
unsigned getFrameRegister(const MachineFunction &MF) const override
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:164
void ComputeSignatureVTs(const FunctionType *Ty, const Function &F, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
Class for arbitrary precision integers.
Definition: APInt.h:70
unsigned getByValAlign() const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
A "pseudo-class" with methods for operating on BUILD_VECTORs.
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:420
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:394
const WebAssemblyRegisterInfo * getRegisterInfo() const override
amdgpu Simplify well known AMD library false Value Value * Arg
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:638
Representation of each machine instruction.
Definition: MachineInstr.h:64
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the source.
Definition: ISDOpcodes.h:724
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:133
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:151
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:387
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB &#39;Other&#39; at the position From, and insert it into this MBB right before &#39;...
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:705
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:206
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:486
bool isInConsecutiveRegsLast() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
TargetOptions Options
Definition: TargetMachine.h:97
#define I(x, y, z)
Definition: MD5.cpp:58
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
This file declares WebAssembly-specific per-machine-function information.
void setStackPointerRegisterToSaveRestore(unsigned R)
If set to a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save and restore.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
unsigned getOpcode() const
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:608
SDValue getValue(unsigned R) const
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LLVM Value Representation.
Definition: Value.h:73
FMA - Perform a * b + c with no intermediate rounding step.
Definition: ISDOpcodes.h:302
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:81
bool isUndef() const
Return true if the type of the node type undefined.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
const WebAssemblyInstrInfo * getInstrInfo() const override
unsigned getNumOperands() const
const SDValue & getOperand(unsigned i) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
LLVMContext * getContext() const
Definition: SelectionDAG.h:407
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
Definition: SelectionDAG.h:622
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:380
BRIND - Indirect branch.
Definition: ISDOpcodes.h:634
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary...
Definition: ISDOpcodes.h:623