LLVM  16.0.0git
XCoreISelLowering.cpp
Go to the documentation of this file.
1 //===-- XCoreISelLowering.cpp - XCore 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 // This file implements the XCoreTargetLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "XCoreISelLowering.h"
14 #include "XCore.h"
16 #include "XCoreSubtarget.h"
17 #include "XCoreTargetMachine.h"
18 #include "XCoreTargetObjectFile.h"
26 #include "llvm/IR/CallingConv.h"
27 #include "llvm/IR/Constants.h"
28 #include "llvm/IR/DerivedTypes.h"
29 #include "llvm/IR/Function.h"
30 #include "llvm/IR/GlobalAlias.h"
31 #include "llvm/IR/GlobalVariable.h"
32 #include "llvm/IR/Intrinsics.h"
33 #include "llvm/IR/IntrinsicsXCore.h"
34 #include "llvm/Support/Debug.h"
36 #include "llvm/Support/KnownBits.h"
38 #include <algorithm>
39 
40 using namespace llvm;
41 
42 #define DEBUG_TYPE "xcore-lower"
43 
44 const char *XCoreTargetLowering::
45 getTargetNodeName(unsigned Opcode) const
46 {
47  switch ((XCoreISD::NodeType)Opcode)
48  {
49  case XCoreISD::FIRST_NUMBER : break;
50  case XCoreISD::BL : return "XCoreISD::BL";
51  case XCoreISD::PCRelativeWrapper : return "XCoreISD::PCRelativeWrapper";
52  case XCoreISD::DPRelativeWrapper : return "XCoreISD::DPRelativeWrapper";
53  case XCoreISD::CPRelativeWrapper : return "XCoreISD::CPRelativeWrapper";
54  case XCoreISD::LDWSP : return "XCoreISD::LDWSP";
55  case XCoreISD::STWSP : return "XCoreISD::STWSP";
56  case XCoreISD::RETSP : return "XCoreISD::RETSP";
57  case XCoreISD::LADD : return "XCoreISD::LADD";
58  case XCoreISD::LSUB : return "XCoreISD::LSUB";
59  case XCoreISD::LMUL : return "XCoreISD::LMUL";
60  case XCoreISD::MACCU : return "XCoreISD::MACCU";
61  case XCoreISD::MACCS : return "XCoreISD::MACCS";
62  case XCoreISD::CRC8 : return "XCoreISD::CRC8";
63  case XCoreISD::BR_JT : return "XCoreISD::BR_JT";
64  case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32";
65  case XCoreISD::FRAME_TO_ARGS_OFFSET : return "XCoreISD::FRAME_TO_ARGS_OFFSET";
66  case XCoreISD::EH_RETURN : return "XCoreISD::EH_RETURN";
67  case XCoreISD::MEMBARRIER : return "XCoreISD::MEMBARRIER";
68  }
69  return nullptr;
70 }
71 
73  const XCoreSubtarget &Subtarget)
74  : TargetLowering(TM), TM(TM), Subtarget(Subtarget) {
75 
76  // Set up the register classes.
77  addRegisterClass(MVT::i32, &XCore::GRRegsRegClass);
78 
79  // Compute derived properties from the register classes
81 
83 
85 
86  // Use i32 for setcc operations results (slt, sgt, ...).
88  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
89 
90  // XCore does not have the NodeTypes below.
93 
94  // 64bit
104 
105  // Bit Manipulation
110 
112 
113  // Jump tables.
115 
118 
119  // Conversion of i64 -> double produces constantpool nodes
121 
122  // Loads
123  for (MVT VT : MVT::integer_valuetypes()) {
127 
130  }
131 
132  // Custom expand misaligned loads / stores.
135 
136  // Varargs
141 
142  // Dynamic stack
146 
147  // Exception handling
150 
151  // Atomic operations
152  // We request a fence for ATOMIC_* instructions, to reduce them to Monotonic.
153  // As we are always Sequential Consistent, an ATOMIC_FENCE becomes a no OP.
157 
158  // TRAMPOLINE is custom lowered.
161 
162  // We want to custom lower some of our intrinsics.
164 
168 
169  // We have target-specific dag combine patterns for the following nodes:
172 
175 }
176 
178  if (Val.getOpcode() != ISD::LOAD)
179  return false;
180 
181  EVT VT1 = Val.getValueType();
182  if (!VT1.isSimple() || !VT1.isInteger() ||
183  !VT2.isSimple() || !VT2.isInteger())
184  return false;
185 
186  switch (VT1.getSimpleVT().SimpleTy) {
187  default: break;
188  case MVT::i8:
189  return true;
190  }
191 
192  return false;
193 }
194 
197  switch (Op.getOpcode())
198  {
199  case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
200  case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
201  case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
202  case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
203  case ISD::BR_JT: return LowerBR_JT(Op, DAG);
204  case ISD::LOAD: return LowerLOAD(Op, DAG);
205  case ISD::STORE: return LowerSTORE(Op, DAG);
206  case ISD::VAARG: return LowerVAARG(Op, DAG);
207  case ISD::VASTART: return LowerVASTART(Op, DAG);
208  case ISD::SMUL_LOHI: return LowerSMUL_LOHI(Op, DAG);
209  case ISD::UMUL_LOHI: return LowerUMUL_LOHI(Op, DAG);
210  // FIXME: Remove these when LegalizeDAGTypes lands.
211  case ISD::ADD:
212  case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG);
213  case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
214  case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
215  case ISD::FRAME_TO_ARGS_OFFSET: return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
216  case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG);
217  case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG);
218  case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
219  case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
220  case ISD::ATOMIC_LOAD: return LowerATOMIC_LOAD(Op, DAG);
221  case ISD::ATOMIC_STORE: return LowerATOMIC_STORE(Op, DAG);
222  default:
223  llvm_unreachable("unimplemented operand");
224  }
225 }
226 
227 /// ReplaceNodeResults - Replace the results of node with an illegal result
228 /// type with new values built out of custom code.
231  SelectionDAG &DAG) const {
232  switch (N->getOpcode()) {
233  default:
234  llvm_unreachable("Don't know how to custom expand this!");
235  case ISD::ADD:
236  case ISD::SUB:
237  Results.push_back(ExpandADDSUB(N, DAG));
238  return;
239  }
240 }
241 
242 //===----------------------------------------------------------------------===//
243 // Misc Lower Operation implementation
244 //===----------------------------------------------------------------------===//
245 
246 SDValue XCoreTargetLowering::getGlobalAddressWrapper(SDValue GA,
247  const GlobalValue *GV,
248  SelectionDAG &DAG) const {
249  // FIXME there is no actual debug info here
250  SDLoc dl(GA);
251 
252  if (GV->getValueType()->isFunctionTy())
253  return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA);
254 
255  const auto *GVar = dyn_cast<GlobalVariable>(GV);
256  if ((GV->hasSection() && GV->getSection().startswith(".cp.")) ||
257  (GVar && GVar->isConstant() && GV->hasLocalLinkage()))
258  return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA);
259 
260  return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA);
261 }
262 
263 static bool IsSmallObject(const GlobalValue *GV, const XCoreTargetLowering &XTL) {
265  return true;
266 
267  Type *ObjType = GV->getValueType();
268  if (!ObjType->isSized())
269  return false;
270 
271  auto &DL = GV->getParent()->getDataLayout();
272  unsigned ObjSize = DL.getTypeAllocSize(ObjType);
273  return ObjSize < CodeModelLargeSize && ObjSize != 0;
274 }
275 
276 SDValue XCoreTargetLowering::
277 LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
278 {
279  const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
280  const GlobalValue *GV = GN->getGlobal();
281  SDLoc DL(GN);
282  int64_t Offset = GN->getOffset();
283  if (IsSmallObject(GV, *this)) {
284  // We can only fold positive offsets that are a multiple of the word size.
285  int64_t FoldedOffset = std::max(Offset & ~3, (int64_t)0);
286  SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, FoldedOffset);
287  GA = getGlobalAddressWrapper(GA, GV, DAG);
288  // Handle the rest of the offset.
289  if (Offset != FoldedOffset) {
290  SDValue Remaining = DAG.getConstant(Offset - FoldedOffset, DL, MVT::i32);
291  GA = DAG.getNode(ISD::ADD, DL, MVT::i32, GA, Remaining);
292  }
293  return GA;
294  } else {
295  // Ideally we would not fold in offset with an index <= 11.
296  Type *Ty = Type::getInt8PtrTy(*DAG.getContext());
297  Constant *GA = ConstantExpr::getBitCast(const_cast<GlobalValue*>(GV), Ty);
298  Ty = Type::getInt32Ty(*DAG.getContext());
299  Constant *Idx = ConstantInt::get(Ty, Offset);
301  Type::getInt8Ty(*DAG.getContext()), GA, Idx);
302  SDValue CP = DAG.getConstantPool(GAI, MVT::i32);
303  return DAG.getLoad(getPointerTy(DAG.getDataLayout()), DL,
305  }
306 }
307 
308 SDValue XCoreTargetLowering::
309 LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
310 {
311  SDLoc DL(Op);
312  auto PtrVT = getPointerTy(DAG.getDataLayout());
313  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
314  SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT);
315 
316  return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, PtrVT, Result);
317 }
318 
319 SDValue XCoreTargetLowering::
320 LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
321 {
322  ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
323  // FIXME there isn't really debug info here
324  SDLoc dl(CP);
325  EVT PtrVT = Op.getValueType();
326  SDValue Res;
327  if (CP->isMachineConstantPoolEntry()) {
328  Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT,
329  CP->getAlign(), CP->getOffset());
330  } else {
331  Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
332  CP->getOffset());
333  }
334  return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, Res);
335 }
336 
339 }
340 
341 SDValue XCoreTargetLowering::
342 LowerBR_JT(SDValue Op, SelectionDAG &DAG) const
343 {
344  SDValue Chain = Op.getOperand(0);
345  SDValue Table = Op.getOperand(1);
346  SDValue Index = Op.getOperand(2);
347  SDLoc dl(Op);
348  JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
349  unsigned JTI = JT->getIndex();
351  const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
352  SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
353 
354  unsigned NumEntries = MJTI->getJumpTables()[JTI].MBBs.size();
355  if (NumEntries <= 32) {
356  return DAG.getNode(XCoreISD::BR_JT, dl, MVT::Other, Chain, TargetJT, Index);
357  }
358  assert((NumEntries >> 31) == 0);
359  SDValue ScaledIndex = DAG.getNode(ISD::SHL, dl, MVT::i32, Index,
360  DAG.getConstant(1, dl, MVT::i32));
361  return DAG.getNode(XCoreISD::BR_JT32, dl, MVT::Other, Chain, TargetJT,
362  ScaledIndex);
363 }
364 
365 SDValue XCoreTargetLowering::lowerLoadWordFromAlignedBasePlusOffset(
366  const SDLoc &DL, SDValue Chain, SDValue Base, int64_t Offset,
367  SelectionDAG &DAG) const {
368  auto PtrVT = getPointerTy(DAG.getDataLayout());
369  if ((Offset & 0x3) == 0) {
370  return DAG.getLoad(PtrVT, DL, Chain, Base, MachinePointerInfo());
371  }
372  // Lower to pair of consecutive word aligned loads plus some bit shifting.
373  int32_t HighOffset = alignTo(Offset, 4);
374  int32_t LowOffset = HighOffset - 4;
375  SDValue LowAddr, HighAddr;
376  if (GlobalAddressSDNode *GASD =
377  dyn_cast<GlobalAddressSDNode>(Base.getNode())) {
378  LowAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(),
379  LowOffset);
380  HighAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(),
381  HighOffset);
382  } else {
383  LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
384  DAG.getConstant(LowOffset, DL, MVT::i32));
385  HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
386  DAG.getConstant(HighOffset, DL, MVT::i32));
387  }
388  SDValue LowShift = DAG.getConstant((Offset - LowOffset) * 8, DL, MVT::i32);
389  SDValue HighShift = DAG.getConstant((HighOffset - Offset) * 8, DL, MVT::i32);
390 
391  SDValue Low = DAG.getLoad(PtrVT, DL, Chain, LowAddr, MachinePointerInfo());
392  SDValue High = DAG.getLoad(PtrVT, DL, Chain, HighAddr, MachinePointerInfo());
393  SDValue LowShifted = DAG.getNode(ISD::SRL, DL, MVT::i32, Low, LowShift);
394  SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, HighShift);
395  SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, LowShifted, HighShifted);
396  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1),
397  High.getValue(1));
398  SDValue Ops[] = { Result, Chain };
399  return DAG.getMergeValues(Ops, DL);
400 }
401 
403 {
404  KnownBits Known = DAG.computeKnownBits(Value);
405  return Known.countMinTrailingZeros() >= 2;
406 }
407 
408 SDValue XCoreTargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
409  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
410  LLVMContext &Context = *DAG.getContext();
411  LoadSDNode *LD = cast<LoadSDNode>(Op);
412  assert(LD->getExtensionType() == ISD::NON_EXTLOAD &&
413  "Unexpected extension type");
414  assert(LD->getMemoryVT() == MVT::i32 && "Unexpected load EVT");
415 
417  LD->getMemoryVT(), *LD->getMemOperand()))
418  return SDValue();
419 
420  SDValue Chain = LD->getChain();
421  SDValue BasePtr = LD->getBasePtr();
422  SDLoc DL(Op);
423 
424  if (!LD->isVolatile()) {
425  const GlobalValue *GV;
426  int64_t Offset = 0;
427  if (DAG.isBaseWithConstantOffset(BasePtr) &&
428  isWordAligned(BasePtr->getOperand(0), DAG)) {
429  SDValue NewBasePtr = BasePtr->getOperand(0);
430  Offset = cast<ConstantSDNode>(BasePtr->getOperand(1))->getSExtValue();
431  return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr,
432  Offset, DAG);
433  }
434  if (TLI.isGAPlusOffset(BasePtr.getNode(), GV, Offset) &&
435  GV->getPointerAlignment(DAG.getDataLayout()) >= 4) {
436  SDValue NewBasePtr = DAG.getGlobalAddress(GV, DL,
437  BasePtr->getValueType(0));
438  return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr,
439  Offset, DAG);
440  }
441  }
442 
443  if (LD->getAlign() == Align(2)) {
444  SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, DL, MVT::i32, Chain, BasePtr,
445  LD->getPointerInfo(), MVT::i16, Align(2),
446  LD->getMemOperand()->getFlags());
447  SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
448  DAG.getConstant(2, DL, MVT::i32));
449  SDValue High =
450  DAG.getExtLoad(ISD::EXTLOAD, DL, MVT::i32, Chain, HighAddr,
451  LD->getPointerInfo().getWithOffset(2), MVT::i16,
452  Align(2), LD->getMemOperand()->getFlags());
453  SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High,
454  DAG.getConstant(16, DL, MVT::i32));
455  SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Low, HighShifted);
456  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1),
457  High.getValue(1));
458  SDValue Ops[] = { Result, Chain };
459  return DAG.getMergeValues(Ops, DL);
460  }
461 
462  // Lower to a call to __misaligned_load(BasePtr).
463  Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(Context);
465  TargetLowering::ArgListEntry Entry;
466 
467  Entry.Ty = IntPtrTy;
468  Entry.Node = BasePtr;
469  Args.push_back(Entry);
470 
472  CLI.setDebugLoc(DL).setChain(Chain).setLibCallee(
473  CallingConv::C, IntPtrTy,
474  DAG.getExternalSymbol("__misaligned_load",
475  getPointerTy(DAG.getDataLayout())),
476  std::move(Args));
477 
478  std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
479  SDValue Ops[] = { CallResult.first, CallResult.second };
480  return DAG.getMergeValues(Ops, DL);
481 }
482 
483 SDValue XCoreTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
484  LLVMContext &Context = *DAG.getContext();
485  StoreSDNode *ST = cast<StoreSDNode>(Op);
486  assert(!ST->isTruncatingStore() && "Unexpected store type");
487  assert(ST->getMemoryVT() == MVT::i32 && "Unexpected store EVT");
488 
490  ST->getMemoryVT(), *ST->getMemOperand()))
491  return SDValue();
492 
493  SDValue Chain = ST->getChain();
494  SDValue BasePtr = ST->getBasePtr();
495  SDValue Value = ST->getValue();
496  SDLoc dl(Op);
497 
498  if (ST->getAlign() == Align(2)) {
499  SDValue Low = Value;
501  DAG.getConstant(16, dl, MVT::i32));
502  SDValue StoreLow =
503  DAG.getTruncStore(Chain, dl, Low, BasePtr, ST->getPointerInfo(),
504  MVT::i16, Align(2), ST->getMemOperand()->getFlags());
505  SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr,
506  DAG.getConstant(2, dl, MVT::i32));
507  SDValue StoreHigh = DAG.getTruncStore(
508  Chain, dl, High, HighAddr, ST->getPointerInfo().getWithOffset(2),
509  MVT::i16, Align(2), ST->getMemOperand()->getFlags());
510  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, StoreLow, StoreHigh);
511  }
512 
513  // Lower to a call to __misaligned_store(BasePtr, Value).
514  Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(Context);
516  TargetLowering::ArgListEntry Entry;
517 
518  Entry.Ty = IntPtrTy;
519  Entry.Node = BasePtr;
520  Args.push_back(Entry);
521 
522  Entry.Node = Value;
523  Args.push_back(Entry);
524 
526  CLI.setDebugLoc(dl).setChain(Chain).setCallee(
528  DAG.getExternalSymbol("__misaligned_store",
529  getPointerTy(DAG.getDataLayout())),
530  std::move(Args));
531 
532  std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
533  return CallResult.second;
534 }
535 
536 SDValue XCoreTargetLowering::
537 LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const
538 {
539  assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::SMUL_LOHI &&
540  "Unexpected operand to lower!");
541  SDLoc dl(Op);
542  SDValue LHS = Op.getOperand(0);
543  SDValue RHS = Op.getOperand(1);
544  SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
545  SDValue Hi = DAG.getNode(XCoreISD::MACCS, dl,
546  DAG.getVTList(MVT::i32, MVT::i32), Zero, Zero,
547  LHS, RHS);
548  SDValue Lo(Hi.getNode(), 1);
549  SDValue Ops[] = { Lo, Hi };
550  return DAG.getMergeValues(Ops, dl);
551 }
552 
553 SDValue XCoreTargetLowering::
554 LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const
555 {
556  assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::UMUL_LOHI &&
557  "Unexpected operand to lower!");
558  SDLoc dl(Op);
559  SDValue LHS = Op.getOperand(0);
560  SDValue RHS = Op.getOperand(1);
561  SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
562  SDValue Hi = DAG.getNode(XCoreISD::LMUL, dl,
564  Zero, Zero);
565  SDValue Lo(Hi.getNode(), 1);
566  SDValue Ops[] = { Lo, Hi };
567  return DAG.getMergeValues(Ops, dl);
568 }
569 
570 /// isADDADDMUL - Return whether Op is in a form that is equivalent to
571 /// add(add(mul(x,y),a),b). If requireIntermediatesHaveOneUse is true then
572 /// each intermediate result in the calculation must also have a single use.
573 /// If the Op is in the correct form the constituent parts are written to Mul0,
574 /// Mul1, Addend0 and Addend1.
575 static bool
576 isADDADDMUL(SDValue Op, SDValue &Mul0, SDValue &Mul1, SDValue &Addend0,
577  SDValue &Addend1, bool requireIntermediatesHaveOneUse)
578 {
579  if (Op.getOpcode() != ISD::ADD)
580  return false;
581  SDValue N0 = Op.getOperand(0);
582  SDValue N1 = Op.getOperand(1);
583  SDValue AddOp;
584  SDValue OtherOp;
585  if (N0.getOpcode() == ISD::ADD) {
586  AddOp = N0;
587  OtherOp = N1;
588  } else if (N1.getOpcode() == ISD::ADD) {
589  AddOp = N1;
590  OtherOp = N0;
591  } else {
592  return false;
593  }
594  if (requireIntermediatesHaveOneUse && !AddOp.hasOneUse())
595  return false;
596  if (OtherOp.getOpcode() == ISD::MUL) {
597  // add(add(a,b),mul(x,y))
598  if (requireIntermediatesHaveOneUse && !OtherOp.hasOneUse())
599  return false;
600  Mul0 = OtherOp.getOperand(0);
601  Mul1 = OtherOp.getOperand(1);
602  Addend0 = AddOp.getOperand(0);
603  Addend1 = AddOp.getOperand(1);
604  return true;
605  }
606  if (AddOp.getOperand(0).getOpcode() == ISD::MUL) {
607  // add(add(mul(x,y),a),b)
608  if (requireIntermediatesHaveOneUse && !AddOp.getOperand(0).hasOneUse())
609  return false;
610  Mul0 = AddOp.getOperand(0).getOperand(0);
611  Mul1 = AddOp.getOperand(0).getOperand(1);
612  Addend0 = AddOp.getOperand(1);
613  Addend1 = OtherOp;
614  return true;
615  }
616  if (AddOp.getOperand(1).getOpcode() == ISD::MUL) {
617  // add(add(a,mul(x,y)),b)
618  if (requireIntermediatesHaveOneUse && !AddOp.getOperand(1).hasOneUse())
619  return false;
620  Mul0 = AddOp.getOperand(1).getOperand(0);
621  Mul1 = AddOp.getOperand(1).getOperand(1);
622  Addend0 = AddOp.getOperand(0);
623  Addend1 = OtherOp;
624  return true;
625  }
626  return false;
627 }
628 
629 SDValue XCoreTargetLowering::
630 TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) const
631 {
632  SDValue Mul;
633  SDValue Other;
634  if (N->getOperand(0).getOpcode() == ISD::MUL) {
635  Mul = N->getOperand(0);
636  Other = N->getOperand(1);
637  } else if (N->getOperand(1).getOpcode() == ISD::MUL) {
638  Mul = N->getOperand(1);
639  Other = N->getOperand(0);
640  } else {
641  return SDValue();
642  }
643  SDLoc dl(N);
644  SDValue LL, RL, AddendL, AddendH;
645  LL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
646  Mul.getOperand(0), DAG.getConstant(0, dl, MVT::i32));
647  RL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
648  Mul.getOperand(1), DAG.getConstant(0, dl, MVT::i32));
649  AddendL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
650  Other, DAG.getConstant(0, dl, MVT::i32));
651  AddendH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
652  Other, DAG.getConstant(1, dl, MVT::i32));
653  APInt HighMask = APInt::getHighBitsSet(64, 32);
654  unsigned LHSSB = DAG.ComputeNumSignBits(Mul.getOperand(0));
655  unsigned RHSSB = DAG.ComputeNumSignBits(Mul.getOperand(1));
656  if (DAG.MaskedValueIsZero(Mul.getOperand(0), HighMask) &&
657  DAG.MaskedValueIsZero(Mul.getOperand(1), HighMask)) {
658  // The inputs are both zero-extended.
659  SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl,
660  DAG.getVTList(MVT::i32, MVT::i32), AddendH,
661  AddendL, LL, RL);
662  SDValue Lo(Hi.getNode(), 1);
663  return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
664  }
665  if (LHSSB > 32 && RHSSB > 32) {
666  // The inputs are both sign-extended.
667  SDValue Hi = DAG.getNode(XCoreISD::MACCS, dl,
668  DAG.getVTList(MVT::i32, MVT::i32), AddendH,
669  AddendL, LL, RL);
670  SDValue Lo(Hi.getNode(), 1);
671  return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
672  }
673  SDValue LH, RH;
674  LH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
675  Mul.getOperand(0), DAG.getConstant(1, dl, MVT::i32));
676  RH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
677  Mul.getOperand(1), DAG.getConstant(1, dl, MVT::i32));
678  SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl,
679  DAG.getVTList(MVT::i32, MVT::i32), AddendH,
680  AddendL, LL, RL);
681  SDValue Lo(Hi.getNode(), 1);
682  RH = DAG.getNode(ISD::MUL, dl, MVT::i32, LL, RH);
683  LH = DAG.getNode(ISD::MUL, dl, MVT::i32, LH, RL);
684  Hi = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, RH);
685  Hi = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, LH);
686  return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
687 }
688 
689 SDValue XCoreTargetLowering::
690 ExpandADDSUB(SDNode *N, SelectionDAG &DAG) const
691 {
692  assert(N->getValueType(0) == MVT::i64 &&
693  (N->getOpcode() == ISD::ADD || N->getOpcode() == ISD::SUB) &&
694  "Unknown operand to lower!");
695 
696  if (N->getOpcode() == ISD::ADD)
697  if (SDValue Result = TryExpandADDWithMul(N, DAG))
698  return Result;
699 
700  SDLoc dl(N);
701 
702  // Extract components
704  N->getOperand(0),
705  DAG.getConstant(0, dl, MVT::i32));
707  N->getOperand(0),
708  DAG.getConstant(1, dl, MVT::i32));
710  N->getOperand(1),
711  DAG.getConstant(0, dl, MVT::i32));
713  N->getOperand(1),
714  DAG.getConstant(1, dl, MVT::i32));
715 
716  // Expand
717  unsigned Opcode = (N->getOpcode() == ISD::ADD) ? XCoreISD::LADD :
719  SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
720  SDValue Lo = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
721  LHSL, RHSL, Zero);
722  SDValue Carry(Lo.getNode(), 1);
723 
724  SDValue Hi = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
725  LHSH, RHSH, Carry);
726  SDValue Ignored(Hi.getNode(), 1);
727  // Merge the pieces
728  return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
729 }
730 
731 SDValue XCoreTargetLowering::
732 LowerVAARG(SDValue Op, SelectionDAG &DAG) const
733 {
734  // Whist llvm does not support aggregate varargs we can ignore
735  // the possibility of the ValueType being an implicit byVal vararg.
736  SDNode *Node = Op.getNode();
737  EVT VT = Node->getValueType(0); // not an aggregate
738  SDValue InChain = Node->getOperand(0);
739  SDValue VAListPtr = Node->getOperand(1);
740  EVT PtrVT = VAListPtr.getValueType();
741  const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
742  SDLoc dl(Node);
743  SDValue VAList =
744  DAG.getLoad(PtrVT, dl, InChain, VAListPtr, MachinePointerInfo(SV));
745  // Increment the pointer, VAList, to the next vararg
746  SDValue nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, VAList,
747  DAG.getIntPtrConstant(VT.getSizeInBits() / 8,
748  dl));
749  // Store the incremented VAList to the legalized pointer
750  InChain = DAG.getStore(VAList.getValue(1), dl, nextPtr, VAListPtr,
751  MachinePointerInfo(SV));
752  // Load the actual argument out of the pointer VAList
753  return DAG.getLoad(VT, dl, InChain, VAList, MachinePointerInfo());
754 }
755 
756 SDValue XCoreTargetLowering::
757 LowerVASTART(SDValue Op, SelectionDAG &DAG) const
758 {
759  SDLoc dl(Op);
760  // vastart stores the address of the VarArgsFrameIndex slot into the
761  // memory location argument
765  return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1),
767 }
768 
769 SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op,
770  SelectionDAG &DAG) const {
771  // This nodes represent llvm.frameaddress on the DAG.
772  // It takes one operand, the index of the frame address to return.
773  // An index of zero corresponds to the current function's frame address.
774  // An index of one to the parent's frame address, and so on.
775  // Depths > 0 not supported yet!
776  if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0)
777  return SDValue();
778 
780  const TargetRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
781  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op),
782  RegInfo->getFrameRegister(MF), MVT::i32);
783 }
784 
785 SDValue XCoreTargetLowering::
786 LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const {
787  // This nodes represent llvm.returnaddress on the DAG.
788  // It takes one operand, the index of the return address to return.
789  // An index of zero corresponds to the current function's return address.
790  // An index of one to the parent's return address, and so on.
791  // Depths > 0 not supported yet!
792  if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0)
793  return SDValue();
794 
797  int FI = XFI->createLRSpillSlot(MF);
798  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
799  return DAG.getLoad(getPointerTy(DAG.getDataLayout()), SDLoc(Op),
800  DAG.getEntryNode(), FIN,
802 }
803 
804 SDValue XCoreTargetLowering::
805 LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const {
806  // This node represents offset from frame pointer to first on-stack argument.
807  // This is needed for correct stack adjustment during unwind.
808  // However, we don't know the offset until after the frame has be finalised.
809  // This is done during the XCoreFTAOElim pass.
811 }
812 
813 SDValue XCoreTargetLowering::
814 LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
815  // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER)
816  // This node represents 'eh_return' gcc dwarf builtin, which is used to
817  // return from exception. The general meaning is: adjust stack by OFFSET and
818  // pass execution to HANDLER.
820  SDValue Chain = Op.getOperand(0);
821  SDValue Offset = Op.getOperand(1);
822  SDValue Handler = Op.getOperand(2);
823  SDLoc dl(Op);
824 
825  // Absolute SP = (FP + FrameToArgs) + Offset
826  const TargetRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
827  SDValue Stack = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
828  RegInfo->getFrameRegister(MF), MVT::i32);
829  SDValue FrameToArgs = DAG.getNode(XCoreISD::FRAME_TO_ARGS_OFFSET, dl,
830  MVT::i32);
831  Stack = DAG.getNode(ISD::ADD, dl, MVT::i32, Stack, FrameToArgs);
832  Stack = DAG.getNode(ISD::ADD, dl, MVT::i32, Stack, Offset);
833 
834  // R0=ExceptionPointerRegister R1=ExceptionSelectorRegister
835  // which leaves 2 caller saved registers, R2 & R3 for us to use.
836  unsigned StackReg = XCore::R2;
837  unsigned HandlerReg = XCore::R3;
838 
839  SDValue OutChains[] = {
840  DAG.getCopyToReg(Chain, dl, StackReg, Stack),
841  DAG.getCopyToReg(Chain, dl, HandlerReg, Handler)
842  };
843 
844  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
845 
846  return DAG.getNode(XCoreISD::EH_RETURN, dl, MVT::Other, Chain,
847  DAG.getRegister(StackReg, MVT::i32),
848  DAG.getRegister(HandlerReg, MVT::i32));
849 
850 }
851 
852 SDValue XCoreTargetLowering::
853 LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const {
854  return Op.getOperand(0);
855 }
856 
857 SDValue XCoreTargetLowering::
858 LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const {
859  SDValue Chain = Op.getOperand(0);
860  SDValue Trmp = Op.getOperand(1); // trampoline
861  SDValue FPtr = Op.getOperand(2); // nested function
862  SDValue Nest = Op.getOperand(3); // 'nest' parameter value
863 
864  const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
865 
866  // .align 4
867  // LDAPF_u10 r11, nest
868  // LDW_2rus r11, r11[0]
869  // STWSP_ru6 r11, sp[0]
870  // LDAPF_u10 r11, fptr
871  // LDW_2rus r11, r11[0]
872  // BAU_1r r11
873  // nest:
874  // .word nest
875  // fptr:
876  // .word fptr
877  SDValue OutChains[5];
878 
879  SDValue Addr = Trmp;
880 
881  SDLoc dl(Op);
882  OutChains[0] =
883  DAG.getStore(Chain, dl, DAG.getConstant(0x0a3cd805, dl, MVT::i32), Addr,
884  MachinePointerInfo(TrmpAddr));
885 
886  Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
887  DAG.getConstant(4, dl, MVT::i32));
888  OutChains[1] =
889  DAG.getStore(Chain, dl, DAG.getConstant(0xd80456c0, dl, MVT::i32), Addr,
890  MachinePointerInfo(TrmpAddr, 4));
891 
892  Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
893  DAG.getConstant(8, dl, MVT::i32));
894  OutChains[2] =
895  DAG.getStore(Chain, dl, DAG.getConstant(0x27fb0a3c, dl, MVT::i32), Addr,
896  MachinePointerInfo(TrmpAddr, 8));
897 
898  Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
899  DAG.getConstant(12, dl, MVT::i32));
900  OutChains[3] =
901  DAG.getStore(Chain, dl, Nest, Addr, MachinePointerInfo(TrmpAddr, 12));
902 
903  Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
904  DAG.getConstant(16, dl, MVT::i32));
905  OutChains[4] =
906  DAG.getStore(Chain, dl, FPtr, Addr, MachinePointerInfo(TrmpAddr, 16));
907 
908  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
909 }
910 
911 SDValue XCoreTargetLowering::
912 LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const {
913  SDLoc DL(Op);
914  unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
915  switch (IntNo) {
916  case Intrinsic::xcore_crc8:
917  EVT VT = Op.getValueType();
918  SDValue Data =
919  DAG.getNode(XCoreISD::CRC8, DL, DAG.getVTList(VT, VT),
920  Op.getOperand(1), Op.getOperand(2) , Op.getOperand(3));
921  SDValue Crc(Data.getNode(), 1);
922  SDValue Results[] = { Crc, Data };
923  return DAG.getMergeValues(Results, DL);
924  }
925  return SDValue();
926 }
927 
928 SDValue XCoreTargetLowering::
929 LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const {
930  SDLoc DL(Op);
931  return DAG.getNode(XCoreISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
932 }
933 
934 SDValue XCoreTargetLowering::
935 LowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const {
936  AtomicSDNode *N = cast<AtomicSDNode>(Op);
937  assert(N->getOpcode() == ISD::ATOMIC_LOAD && "Bad Atomic OP");
938  assert((N->getSuccessOrdering() == AtomicOrdering::Unordered ||
939  N->getSuccessOrdering() == AtomicOrdering::Monotonic) &&
940  "setInsertFencesForAtomic(true) expects unordered / monotonic");
941  if (N->getMemoryVT() == MVT::i32) {
942  if (N->getAlign() < Align(4))
943  report_fatal_error("atomic load must be aligned");
944  return DAG.getLoad(getPointerTy(DAG.getDataLayout()), SDLoc(Op),
945  N->getChain(), N->getBasePtr(), N->getPointerInfo(),
946  N->getAlign(), N->getMemOperand()->getFlags(),
947  N->getAAInfo(), N->getRanges());
948  }
949  if (N->getMemoryVT() == MVT::i16) {
950  if (N->getAlign() < Align(2))
951  report_fatal_error("atomic load must be aligned");
952  return DAG.getExtLoad(ISD::EXTLOAD, SDLoc(Op), MVT::i32, N->getChain(),
953  N->getBasePtr(), N->getPointerInfo(), MVT::i16,
954  N->getAlign(), N->getMemOperand()->getFlags(),
955  N->getAAInfo());
956  }
957  if (N->getMemoryVT() == MVT::i8)
958  return DAG.getExtLoad(ISD::EXTLOAD, SDLoc(Op), MVT::i32, N->getChain(),
959  N->getBasePtr(), N->getPointerInfo(), MVT::i8,
960  N->getAlign(), N->getMemOperand()->getFlags(),
961  N->getAAInfo());
962  return SDValue();
963 }
964 
965 SDValue XCoreTargetLowering::
966 LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const {
967  AtomicSDNode *N = cast<AtomicSDNode>(Op);
968  assert(N->getOpcode() == ISD::ATOMIC_STORE && "Bad Atomic OP");
969  assert((N->getSuccessOrdering() == AtomicOrdering::Unordered ||
970  N->getSuccessOrdering() == AtomicOrdering::Monotonic) &&
971  "setInsertFencesForAtomic(true) expects unordered / monotonic");
972  if (N->getMemoryVT() == MVT::i32) {
973  if (N->getAlign() < Align(4))
974  report_fatal_error("atomic store must be aligned");
975  return DAG.getStore(N->getChain(), SDLoc(Op), N->getVal(), N->getBasePtr(),
976  N->getPointerInfo(), N->getAlign(),
977  N->getMemOperand()->getFlags(), N->getAAInfo());
978  }
979  if (N->getMemoryVT() == MVT::i16) {
980  if (N->getAlign() < Align(2))
981  report_fatal_error("atomic store must be aligned");
982  return DAG.getTruncStore(N->getChain(), SDLoc(Op), N->getVal(),
983  N->getBasePtr(), N->getPointerInfo(), MVT::i16,
984  N->getAlign(), N->getMemOperand()->getFlags(),
985  N->getAAInfo());
986  }
987  if (N->getMemoryVT() == MVT::i8)
988  return DAG.getTruncStore(N->getChain(), SDLoc(Op), N->getVal(),
989  N->getBasePtr(), N->getPointerInfo(), MVT::i8,
990  N->getAlign(), N->getMemOperand()->getFlags(),
991  N->getAAInfo());
992  return SDValue();
993 }
994 
996 XCoreTargetLowering::getTargetMMOFlags(const Instruction &I) const {
997  // Because of how we convert atomic_load and atomic_store to normal loads and
998  // stores in the DAG, we need to ensure that the MMOs are marked volatile
999  // since DAGCombine hasn't been updated to account for atomic, but non
1000  // volatile loads. (See D57601)
1001  if (auto *SI = dyn_cast<StoreInst>(&I))
1002  if (SI->isAtomic())
1004  if (auto *LI = dyn_cast<LoadInst>(&I))
1005  if (LI->isAtomic())
1007  if (auto *AI = dyn_cast<AtomicRMWInst>(&I))
1008  if (AI->isAtomic())
1010  if (auto *AI = dyn_cast<AtomicCmpXchgInst>(&I))
1011  if (AI->isAtomic())
1014 }
1015 
1016 //===----------------------------------------------------------------------===//
1017 // Calling Convention Implementation
1018 //===----------------------------------------------------------------------===//
1019 
1020 #include "XCoreGenCallingConv.inc"
1021 
1022 //===----------------------------------------------------------------------===//
1023 // Call Calling Convention Implementation
1024 //===----------------------------------------------------------------------===//
1025 
1026 /// XCore call implementation
1027 SDValue
1028 XCoreTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
1029  SmallVectorImpl<SDValue> &InVals) const {
1030  SelectionDAG &DAG = CLI.DAG;
1031  SDLoc &dl = CLI.DL;
1033  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
1035  SDValue Chain = CLI.Chain;
1036  SDValue Callee = CLI.Callee;
1037  bool &isTailCall = CLI.IsTailCall;
1038  CallingConv::ID CallConv = CLI.CallConv;
1039  bool isVarArg = CLI.IsVarArg;
1040 
1041  // XCore target does not yet support tail call optimization.
1042  isTailCall = false;
1043 
1044  // For now, only CallingConv::C implemented
1045  switch (CallConv)
1046  {
1047  default:
1048  report_fatal_error("Unsupported calling convention");
1049  case CallingConv::Fast:
1050  case CallingConv::C:
1051  return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
1052  Outs, OutVals, Ins, dl, DAG, InVals);
1053  }
1054 }
1055 
1056 /// LowerCallResult - Lower the result values of a call into the
1057 /// appropriate copies out of appropriate physical registers / memory locations.
1059  const SmallVectorImpl<CCValAssign> &RVLocs,
1060  const SDLoc &dl, SelectionDAG &DAG,
1061  SmallVectorImpl<SDValue> &InVals) {
1062  SmallVector<std::pair<int, unsigned>, 4> ResultMemLocs;
1063  // Copy results out of physical registers.
1064  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
1065  const CCValAssign &VA = RVLocs[i];
1066  if (VA.isRegLoc()) {
1067  Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getValVT(),
1068  InFlag).getValue(1);
1069  InFlag = Chain.getValue(2);
1070  InVals.push_back(Chain.getValue(0));
1071  } else {
1072  assert(VA.isMemLoc());
1073  ResultMemLocs.push_back(std::make_pair(VA.getLocMemOffset(),
1074  InVals.size()));
1075  // Reserve space for this result.
1076  InVals.push_back(SDValue());
1077  }
1078  }
1079 
1080  // Copy results out of memory.
1081  SmallVector<SDValue, 4> MemOpChains;
1082  for (unsigned i = 0, e = ResultMemLocs.size(); i != e; ++i) {
1083  int offset = ResultMemLocs[i].first;
1084  unsigned index = ResultMemLocs[i].second;
1085  SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
1086  SDValue Ops[] = { Chain, DAG.getConstant(offset / 4, dl, MVT::i32) };
1087  SDValue load = DAG.getNode(XCoreISD::LDWSP, dl, VTs, Ops);
1088  InVals[index] = load;
1089  MemOpChains.push_back(load.getValue(1));
1090  }
1091 
1092  // Transform all loads nodes into one single node because
1093  // all load nodes are independent of each other.
1094  if (!MemOpChains.empty())
1095  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
1096 
1097  return Chain;
1098 }
1099 
1100 /// LowerCCCCallTo - functions arguments are copied from virtual
1101 /// regs to (physical regs)/(stack frame), CALLSEQ_START and
1102 /// CALLSEQ_END are emitted.
1103 /// TODO: isTailCall, sret.
1104 SDValue XCoreTargetLowering::LowerCCCCallTo(
1105  SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
1106  bool isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs,
1107  const SmallVectorImpl<SDValue> &OutVals,
1108  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
1109  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
1110 
1111  // Analyze operands of the call, assigning locations to each operand.
1113  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
1114  *DAG.getContext());
1115 
1116  // The ABI dictates there should be one stack slot available to the callee
1117  // on function entry (for saving lr).
1118  CCInfo.AllocateStack(4, Align(4));
1119 
1120  CCInfo.AnalyzeCallOperands(Outs, CC_XCore);
1121 
1123  // Analyze return values to determine the number of bytes of stack required.
1124  CCState RetCCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1125  *DAG.getContext());
1126  RetCCInfo.AllocateStack(CCInfo.getNextStackOffset(), Align(4));
1127  RetCCInfo.AnalyzeCallResult(Ins, RetCC_XCore);
1128 
1129  // Get a count of how many bytes are to be pushed on the stack.
1130  unsigned NumBytes = RetCCInfo.getNextStackOffset();
1131 
1132  Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
1133 
1135  SmallVector<SDValue, 12> MemOpChains;
1136 
1137  // Walk the register/memloc assignments, inserting copies/loads.
1138  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1139  CCValAssign &VA = ArgLocs[i];
1140  SDValue Arg = OutVals[i];
1141 
1142  // Promote the value if needed.
1143  switch (VA.getLocInfo()) {
1144  default: llvm_unreachable("Unknown loc info!");
1145  case CCValAssign::Full: break;
1146  case CCValAssign::SExt:
1147  Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
1148  break;
1149  case CCValAssign::ZExt:
1150  Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
1151  break;
1152  case CCValAssign::AExt:
1153  Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
1154  break;
1155  }
1156 
1157  // Arguments that can be passed on register must be kept at
1158  // RegsToPass vector
1159  if (VA.isRegLoc()) {
1160  RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
1161  } else {
1162  assert(VA.isMemLoc());
1163 
1164  int Offset = VA.getLocMemOffset();
1165 
1166  MemOpChains.push_back(DAG.getNode(XCoreISD::STWSP, dl, MVT::Other,
1167  Chain, Arg,
1168  DAG.getConstant(Offset/4, dl,
1169  MVT::i32)));
1170  }
1171  }
1172 
1173  // Transform all store nodes into one single node because
1174  // all store nodes are independent of each other.
1175  if (!MemOpChains.empty())
1176  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
1177 
1178  // Build a sequence of copy-to-reg nodes chained together with token
1179  // chain and flag operands which copy the outgoing args into registers.
1180  // The InFlag in necessary since all emitted instructions must be
1181  // stuck together.
1182  SDValue InFlag;
1183  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1184  Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
1185  RegsToPass[i].second, InFlag);
1186  InFlag = Chain.getValue(1);
1187  }
1188 
1189  // If the callee is a GlobalAddress node (quite common, every direct call is)
1190  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
1191  // Likewise ExternalSymbol -> TargetExternalSymbol.
1192  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1193  Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
1194  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
1195  Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
1196 
1197  // XCoreBranchLink = #chain, #target_address, #opt_in_flags...
1198  // = Chain, Callee, Reg#1, Reg#2, ...
1199  //
1200  // Returns a chain & a flag for retval copy to use.
1201  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1203  Ops.push_back(Chain);
1204  Ops.push_back(Callee);
1205 
1206  // Add argument registers to the end of the list so that they are
1207  // known live into the call.
1208  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1209  Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1210  RegsToPass[i].second.getValueType()));
1211 
1212  if (InFlag.getNode())
1213  Ops.push_back(InFlag);
1214 
1215  Chain = DAG.getNode(XCoreISD::BL, dl, NodeTys, Ops);
1216  InFlag = Chain.getValue(1);
1217 
1218  // Create the CALLSEQ_END node.
1219  Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InFlag, dl);
1220  InFlag = Chain.getValue(1);
1221 
1222  // Handle result values, copying them out of physregs into vregs that we
1223  // return.
1224  return LowerCallResult(Chain, InFlag, RVLocs, dl, DAG, InVals);
1225 }
1226 
1227 //===----------------------------------------------------------------------===//
1228 // Formal Arguments Calling Convention Implementation
1229 //===----------------------------------------------------------------------===//
1230 
1231 namespace {
1232  struct ArgDataPair { SDValue SDV; ISD::ArgFlagsTy Flags; };
1233 }
1234 
1235 /// XCore formal arguments implementation
1236 SDValue XCoreTargetLowering::LowerFormalArguments(
1237  SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
1238  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
1239  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
1240  switch (CallConv)
1241  {
1242  default:
1243  report_fatal_error("Unsupported calling convention");
1244  case CallingConv::C:
1245  case CallingConv::Fast:
1246  return LowerCCCArguments(Chain, CallConv, isVarArg,
1247  Ins, dl, DAG, InVals);
1248  }
1249 }
1250 
1251 /// LowerCCCArguments - transform physical registers into
1252 /// virtual registers and generate load operations for
1253 /// arguments places on the stack.
1254 /// TODO: sret
1255 SDValue XCoreTargetLowering::LowerCCCArguments(
1256  SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
1257  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
1258  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
1259  MachineFunction &MF = DAG.getMachineFunction();
1260  MachineFrameInfo &MFI = MF.getFrameInfo();
1261  MachineRegisterInfo &RegInfo = MF.getRegInfo();
1263 
1264  // Assign locations to all of the incoming arguments.
1266  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
1267  *DAG.getContext());
1268 
1269  CCInfo.AnalyzeFormalArguments(Ins, CC_XCore);
1270 
1271  unsigned StackSlotSize = XCoreFrameLowering::stackSlotSize();
1272 
1273  unsigned LRSaveSize = StackSlotSize;
1274 
1275  if (!isVarArg)
1276  XFI->setReturnStackOffset(CCInfo.getNextStackOffset() + LRSaveSize);
1277 
1278  // All getCopyFromReg ops must precede any getMemcpys to prevent the
1279  // scheduler clobbering a register before it has been copied.
1280  // The stages are:
1281  // 1. CopyFromReg (and load) arg & vararg registers.
1282  // 2. Chain CopyFromReg nodes into a TokenFactor.
1283  // 3. Memcpy 'byVal' args & push final InVals.
1284  // 4. Chain mem ops nodes into a TokenFactor.
1285  SmallVector<SDValue, 4> CFRegNode;
1287  SmallVector<SDValue, 4> MemOps;
1288 
1289  // 1a. CopyFromReg (and load) arg registers.
1290  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1291 
1292  CCValAssign &VA = ArgLocs[i];
1293  SDValue ArgIn;
1294 
1295  if (VA.isRegLoc()) {
1296  // Arguments passed in registers
1297  EVT RegVT = VA.getLocVT();
1298  switch (RegVT.getSimpleVT().SimpleTy) {
1299  default:
1300  {
1301 #ifndef NDEBUG
1302  errs() << "LowerFormalArguments Unhandled argument type: "
1303  << RegVT.getEVTString() << "\n";
1304 #endif
1305  llvm_unreachable(nullptr);
1306  }
1307  case MVT::i32:
1308  Register VReg = RegInfo.createVirtualRegister(&XCore::GRRegsRegClass);
1309  RegInfo.addLiveIn(VA.getLocReg(), VReg);
1310  ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
1311  CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1));
1312  }
1313  } else {
1314  // Only arguments passed on the stack should make it here.
1315  assert(VA.isMemLoc());
1316  // Load the argument to a virtual register
1317  unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
1318  if (ObjSize > StackSlotSize) {
1319  errs() << "LowerFormalArguments Unhandled argument type: "
1320  << EVT(VA.getLocVT()).getEVTString()
1321  << "\n";
1322  }
1323  // Create the frame index object for this incoming parameter...
1324  int FI = MFI.CreateFixedObject(ObjSize,
1325  LRSaveSize + VA.getLocMemOffset(),
1326  true);
1327 
1328  // Create the SelectionDAG nodes corresponding to a load
1329  //from this parameter
1330  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
1331  ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
1333  }
1334  const ArgDataPair ADP = { ArgIn, Ins[i].Flags };
1335  ArgData.push_back(ADP);
1336  }
1337 
1338  // 1b. CopyFromReg vararg registers.
1339  if (isVarArg) {
1340  // Argument registers
1341  static const MCPhysReg ArgRegs[] = {
1342  XCore::R0, XCore::R1, XCore::R2, XCore::R3
1343  };
1345  unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
1346  if (FirstVAReg < std::size(ArgRegs)) {
1347  int offset = 0;
1348  // Save remaining registers, storing higher register numbers at a higher
1349  // address
1350  for (int i = std::size(ArgRegs) - 1; i >= (int)FirstVAReg; --i) {
1351  // Create a stack slot
1352  int FI = MFI.CreateFixedObject(4, offset, true);
1353  if (i == (int)FirstVAReg) {
1354  XFI->setVarArgsFrameIndex(FI);
1355  }
1356  offset -= StackSlotSize;
1357  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
1358  // Move argument from phys reg -> virt reg
1359  Register VReg = RegInfo.createVirtualRegister(&XCore::GRRegsRegClass);
1360  RegInfo.addLiveIn(ArgRegs[i], VReg);
1361  SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
1362  CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1));
1363  // Move argument from virt reg -> stack
1364  SDValue Store =
1365  DAG.getStore(Val.getValue(1), dl, Val, FIN, MachinePointerInfo());
1366  MemOps.push_back(Store);
1367  }
1368  } else {
1369  // This will point to the next argument passed via stack.
1370  XFI->setVarArgsFrameIndex(
1371  MFI.CreateFixedObject(4, LRSaveSize + CCInfo.getNextStackOffset(),
1372  true));
1373  }
1374  }
1375 
1376  // 2. chain CopyFromReg nodes into a TokenFactor.
1377  if (!CFRegNode.empty())
1378  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, CFRegNode);
1379 
1380  // 3. Memcpy 'byVal' args & push final InVals.
1381  // Aggregates passed "byVal" need to be copied by the callee.
1382  // The callee will use a pointer to this copy, rather than the original
1383  // pointer.
1384  for (const ArgDataPair &ArgDI : ArgData) {
1385  if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
1386  unsigned Size = ArgDI.Flags.getByValSize();
1387  Align Alignment =
1388  std::max(Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign());
1389  // Create a new object on the stack and copy the pointee into it.
1390  int FI = MFI.CreateStackObject(Size, Alignment, false);
1391  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
1392  InVals.push_back(FIN);
1393  MemOps.push_back(DAG.getMemcpy(
1394  Chain, dl, FIN, ArgDI.SDV, DAG.getConstant(Size, dl, MVT::i32),
1395  Alignment, false, false, false, MachinePointerInfo(),
1396  MachinePointerInfo()));
1397  } else {
1398  InVals.push_back(ArgDI.SDV);
1399  }
1400  }
1401 
1402  // 4, chain mem ops nodes into a TokenFactor.
1403  if (!MemOps.empty()) {
1404  MemOps.push_back(Chain);
1405  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
1406  }
1407 
1408  return Chain;
1409 }
1410 
1411 //===----------------------------------------------------------------------===//
1412 // Return Value Calling Convention Implementation
1413 //===----------------------------------------------------------------------===//
1414 
1415 bool XCoreTargetLowering::
1416 CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
1417  bool isVarArg,
1418  const SmallVectorImpl<ISD::OutputArg> &Outs,
1419  LLVMContext &Context) const {
1421  CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
1422  if (!CCInfo.CheckReturn(Outs, RetCC_XCore))
1423  return false;
1424  if (CCInfo.getNextStackOffset() != 0 && isVarArg)
1425  return false;
1426  return true;
1427 }
1428 
1429 SDValue
1430 XCoreTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
1431  bool isVarArg,
1432  const SmallVectorImpl<ISD::OutputArg> &Outs,
1433  const SmallVectorImpl<SDValue> &OutVals,
1434  const SDLoc &dl, SelectionDAG &DAG) const {
1435 
1436  XCoreFunctionInfo *XFI =
1439 
1440  // CCValAssign - represent the assignment of
1441  // the return value to a location
1443 
1444  // CCState - Info about the registers and stack slot.
1445  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1446  *DAG.getContext());
1447 
1448  // Analyze return values.
1449  if (!isVarArg)
1450  CCInfo.AllocateStack(XFI->getReturnStackOffset(), Align(4));
1451 
1452  CCInfo.AnalyzeReturn(Outs, RetCC_XCore);
1453 
1454  SDValue Flag;
1455  SmallVector<SDValue, 4> RetOps(1, Chain);
1456 
1457  // Return on XCore is always a "retsp 0"
1458  RetOps.push_back(DAG.getConstant(0, dl, MVT::i32));
1459 
1460  SmallVector<SDValue, 4> MemOpChains;
1461  // Handle return values that must be copied to memory.
1462  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
1463  CCValAssign &VA = RVLocs[i];
1464  if (VA.isRegLoc())
1465  continue;
1466  assert(VA.isMemLoc());
1467  if (isVarArg) {
1468  report_fatal_error("Can't return value from vararg function in memory");
1469  }
1470 
1471  int Offset = VA.getLocMemOffset();
1472  unsigned ObjSize = VA.getLocVT().getSizeInBits() / 8;
1473  // Create the frame index object for the memory location.
1474  int FI = MFI.CreateFixedObject(ObjSize, Offset, false);
1475 
1476  // Create a SelectionDAG node corresponding to a store
1477  // to this memory location.
1478  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
1479  MemOpChains.push_back(DAG.getStore(
1480  Chain, dl, OutVals[i], FIN,
1482  }
1483 
1484  // Transform all store nodes into one single node because
1485  // all stores are independent of each other.
1486  if (!MemOpChains.empty())
1487  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
1488 
1489  // Now handle return values copied to registers.
1490  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
1491  CCValAssign &VA = RVLocs[i];
1492  if (!VA.isRegLoc())
1493  continue;
1494  // Copy the result values into the output registers.
1495  Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag);
1496 
1497  // guarantee that all emitted copies are
1498  // stuck together, avoiding something bad
1499  Flag = Chain.getValue(1);
1500  RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
1501  }
1502 
1503  RetOps[0] = Chain; // Update chain.
1504 
1505  // Add the flag if we have it.
1506  if (Flag.getNode())
1507  RetOps.push_back(Flag);
1508 
1509  return DAG.getNode(XCoreISD::RETSP, dl, MVT::Other, RetOps);
1510 }
1511 
1512 //===----------------------------------------------------------------------===//
1513 // Other Lowering Code
1514 //===----------------------------------------------------------------------===//
1515 
1518  MachineBasicBlock *BB) const {
1519  const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
1520  DebugLoc dl = MI.getDebugLoc();
1521  assert((MI.getOpcode() == XCore::SELECT_CC) &&
1522  "Unexpected instr type to insert");
1523 
1524  // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
1525  // control-flow pattern. The incoming instruction knows the destination vreg
1526  // to set, the condition code register to branch on, the true/false values to
1527  // select between, and a branch opcode to use.
1528  const BasicBlock *LLVM_BB = BB->getBasicBlock();
1529  MachineFunction::iterator It = ++BB->getIterator();
1530 
1531  // thisMBB:
1532  // ...
1533  // TrueVal = ...
1534  // cmpTY ccX, r1, r2
1535  // bCC copy1MBB
1536  // fallthrough --> copy0MBB
1537  MachineBasicBlock *thisMBB = BB;
1538  MachineFunction *F = BB->getParent();
1539  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1540  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1541  F->insert(It, copy0MBB);
1542  F->insert(It, sinkMBB);
1543 
1544  // Transfer the remainder of BB and its successor edges to sinkMBB.
1545  sinkMBB->splice(sinkMBB->begin(), BB,
1546  std::next(MachineBasicBlock::iterator(MI)), BB->end());
1548 
1549  // Next, add the true and fallthrough blocks as its successors.
1550  BB->addSuccessor(copy0MBB);
1551  BB->addSuccessor(sinkMBB);
1552 
1553  BuildMI(BB, dl, TII.get(XCore::BRFT_lru6))
1554  .addReg(MI.getOperand(1).getReg())
1555  .addMBB(sinkMBB);
1556 
1557  // copy0MBB:
1558  // %FalseValue = ...
1559  // # fallthrough to sinkMBB
1560  BB = copy0MBB;
1561 
1562  // Update machine-CFG edges
1563  BB->addSuccessor(sinkMBB);
1564 
1565  // sinkMBB:
1566  // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1567  // ...
1568  BB = sinkMBB;
1569  BuildMI(*BB, BB->begin(), dl, TII.get(XCore::PHI), MI.getOperand(0).getReg())
1570  .addReg(MI.getOperand(3).getReg())
1571  .addMBB(copy0MBB)
1572  .addReg(MI.getOperand(2).getReg())
1573  .addMBB(thisMBB);
1574 
1575  MI.eraseFromParent(); // The pseudo instruction is gone now.
1576  return BB;
1577 }
1578 
1579 //===----------------------------------------------------------------------===//
1580 // Target Optimization Hooks
1581 //===----------------------------------------------------------------------===//
1582 
1583 SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
1584  DAGCombinerInfo &DCI) const {
1585  SelectionDAG &DAG = DCI.DAG;
1586  SDLoc dl(N);
1587  switch (N->getOpcode()) {
1588  default: break;
1589  case ISD::INTRINSIC_VOID:
1590  switch (cast<ConstantSDNode>(N->getOperand(1))->getZExtValue()) {
1591  case Intrinsic::xcore_outt:
1592  case Intrinsic::xcore_outct:
1593  case Intrinsic::xcore_chkct: {
1594  SDValue OutVal = N->getOperand(3);
1595  // These instructions ignore the high bits.
1596  if (OutVal.hasOneUse()) {
1597  unsigned BitWidth = OutVal.getValueSizeInBits();
1598  APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8);
1599  KnownBits Known;
1600  TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
1601  !DCI.isBeforeLegalizeOps());
1602  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1603  if (TLI.ShrinkDemandedConstant(OutVal, DemandedMask, TLO) ||
1604  TLI.SimplifyDemandedBits(OutVal, DemandedMask, Known, TLO))
1605  DCI.CommitTargetLoweringOpt(TLO);
1606  }
1607  break;
1608  }
1609  case Intrinsic::xcore_setpt: {
1610  SDValue Time = N->getOperand(3);
1611  // This instruction ignores the high bits.
1612  if (Time.hasOneUse()) {
1613  unsigned BitWidth = Time.getValueSizeInBits();
1614  APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
1615  KnownBits Known;
1616  TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
1617  !DCI.isBeforeLegalizeOps());
1618  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1619  if (TLI.ShrinkDemandedConstant(Time, DemandedMask, TLO) ||
1620  TLI.SimplifyDemandedBits(Time, DemandedMask, Known, TLO))
1621  DCI.CommitTargetLoweringOpt(TLO);
1622  }
1623  break;
1624  }
1625  }
1626  break;
1627  case XCoreISD::LADD: {
1628  SDValue N0 = N->getOperand(0);
1629  SDValue N1 = N->getOperand(1);
1630  SDValue N2 = N->getOperand(2);
1631  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
1632  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
1633  EVT VT = N0.getValueType();
1634 
1635  // canonicalize constant to RHS
1636  if (N0C && !N1C)
1637  return DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N1, N0, N2);
1638 
1639  // fold (ladd 0, 0, x) -> 0, x & 1
1640  if (N0C && N0C->isZero() && N1C && N1C->isZero()) {
1641  SDValue Carry = DAG.getConstant(0, dl, VT);
1642  SDValue Result = DAG.getNode(ISD::AND, dl, VT, N2,
1643  DAG.getConstant(1, dl, VT));
1644  SDValue Ops[] = { Result, Carry };
1645  return DAG.getMergeValues(Ops, dl);
1646  }
1647 
1648  // fold (ladd x, 0, y) -> 0, add x, y iff carry is unused and y has only the
1649  // low bit set
1650  if (N1C && N1C->isZero() && N->hasNUsesOfValue(0, 1)) {
1652  VT.getSizeInBits() - 1);
1653  KnownBits Known = DAG.computeKnownBits(N2);
1654  if ((Known.Zero & Mask) == Mask) {
1655  SDValue Carry = DAG.getConstant(0, dl, VT);
1656  SDValue Result = DAG.getNode(ISD::ADD, dl, VT, N0, N2);
1657  SDValue Ops[] = { Result, Carry };
1658  return DAG.getMergeValues(Ops, dl);
1659  }
1660  }
1661  }
1662  break;
1663  case XCoreISD::LSUB: {
1664  SDValue N0 = N->getOperand(0);
1665  SDValue N1 = N->getOperand(1);
1666  SDValue N2 = N->getOperand(2);
1667  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
1668  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
1669  EVT VT = N0.getValueType();
1670 
1671  // fold (lsub 0, 0, x) -> x, -x iff x has only the low bit set
1672  if (N0C && N0C->isZero() && N1C && N1C->isZero()) {
1674  VT.getSizeInBits() - 1);
1675  KnownBits Known = DAG.computeKnownBits(N2);
1676  if ((Known.Zero & Mask) == Mask) {
1677  SDValue Borrow = N2;
1678  SDValue Result = DAG.getNode(ISD::SUB, dl, VT,
1679  DAG.getConstant(0, dl, VT), N2);
1680  SDValue Ops[] = { Result, Borrow };
1681  return DAG.getMergeValues(Ops, dl);
1682  }
1683  }
1684 
1685  // fold (lsub x, 0, y) -> 0, sub x, y iff borrow is unused and y has only the
1686  // low bit set
1687  if (N1C && N1C->isZero() && N->hasNUsesOfValue(0, 1)) {
1689  VT.getSizeInBits() - 1);
1690  KnownBits Known = DAG.computeKnownBits(N2);
1691  if ((Known.Zero & Mask) == Mask) {
1692  SDValue Borrow = DAG.getConstant(0, dl, VT);
1693  SDValue Result = DAG.getNode(ISD::SUB, dl, VT, N0, N2);
1694  SDValue Ops[] = { Result, Borrow };
1695  return DAG.getMergeValues(Ops, dl);
1696  }
1697  }
1698  }
1699  break;
1700  case XCoreISD::LMUL: {
1701  SDValue N0 = N->getOperand(0);
1702  SDValue N1 = N->getOperand(1);
1703  SDValue N2 = N->getOperand(2);
1704  SDValue N3 = N->getOperand(3);
1705  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
1706  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
1707  EVT VT = N0.getValueType();
1708  // Canonicalize multiplicative constant to RHS. If both multiplicative
1709  // operands are constant canonicalize smallest to RHS.
1710  if ((N0C && !N1C) ||
1711  (N0C && N1C && N0C->getZExtValue() < N1C->getZExtValue()))
1712  return DAG.getNode(XCoreISD::LMUL, dl, DAG.getVTList(VT, VT),
1713  N1, N0, N2, N3);
1714 
1715  // lmul(x, 0, a, b)
1716  if (N1C && N1C->isZero()) {
1717  // If the high result is unused fold to add(a, b)
1718  if (N->hasNUsesOfValue(0, 0)) {
1719  SDValue Lo = DAG.getNode(ISD::ADD, dl, VT, N2, N3);
1720  SDValue Ops[] = { Lo, Lo };
1721  return DAG.getMergeValues(Ops, dl);
1722  }
1723  // Otherwise fold to ladd(a, b, 0)
1724  SDValue Result =
1725  DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N2, N3, N1);
1726  SDValue Carry(Result.getNode(), 1);
1727  SDValue Ops[] = { Carry, Result };
1728  return DAG.getMergeValues(Ops, dl);
1729  }
1730  }
1731  break;
1732  case ISD::ADD: {
1733  // Fold 32 bit expressions such as add(add(mul(x,y),a),b) ->
1734  // lmul(x, y, a, b). The high result of lmul will be ignored.
1735  // This is only profitable if the intermediate results are unused
1736  // elsewhere.
1737  SDValue Mul0, Mul1, Addend0, Addend1;
1738  if (N->getValueType(0) == MVT::i32 &&
1739  isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, true)) {
1740  SDValue Ignored = DAG.getNode(XCoreISD::LMUL, dl,
1741  DAG.getVTList(MVT::i32, MVT::i32), Mul0,
1742  Mul1, Addend0, Addend1);
1743  SDValue Result(Ignored.getNode(), 1);
1744  return Result;
1745  }
1746  APInt HighMask = APInt::getHighBitsSet(64, 32);
1747  // Fold 64 bit expression such as add(add(mul(x,y),a),b) ->
1748  // lmul(x, y, a, b) if all operands are zero-extended. We do this
1749  // before type legalization as it is messy to match the operands after
1750  // that.
1751  if (N->getValueType(0) == MVT::i64 &&
1752  isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, false) &&
1753  DAG.MaskedValueIsZero(Mul0, HighMask) &&
1754  DAG.MaskedValueIsZero(Mul1, HighMask) &&
1755  DAG.MaskedValueIsZero(Addend0, HighMask) &&
1756  DAG.MaskedValueIsZero(Addend1, HighMask)) {
1757  SDValue Mul0L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
1758  Mul0, DAG.getConstant(0, dl, MVT::i32));
1759  SDValue Mul1L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
1760  Mul1, DAG.getConstant(0, dl, MVT::i32));
1761  SDValue Addend0L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
1762  Addend0, DAG.getConstant(0, dl, MVT::i32));
1763  SDValue Addend1L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
1764  Addend1, DAG.getConstant(0, dl, MVT::i32));
1765  SDValue Hi = DAG.getNode(XCoreISD::LMUL, dl,
1766  DAG.getVTList(MVT::i32, MVT::i32), Mul0L, Mul1L,
1767  Addend0L, Addend1L);
1768  SDValue Lo(Hi.getNode(), 1);
1769  return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
1770  }
1771  }
1772  break;
1773  case ISD::STORE: {
1774  // Replace unaligned store of unaligned load with memmove.
1775  StoreSDNode *ST = cast<StoreSDNode>(N);
1776  if (!DCI.isBeforeLegalize() ||
1778  ST->getMemoryVT(),
1779  *ST->getMemOperand()) ||
1780  ST->isVolatile() || ST->isIndexed()) {
1781  break;
1782  }
1783  SDValue Chain = ST->getChain();
1784 
1785  unsigned StoreBits = ST->getMemoryVT().getStoreSizeInBits();
1786  assert((StoreBits % 8) == 0 &&
1787  "Store size in bits must be a multiple of 8");
1788  Align Alignment = ST->getAlign();
1789 
1790  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(ST->getValue())) {
1791  if (LD->hasNUsesOfValue(1, 0) && ST->getMemoryVT() == LD->getMemoryVT() &&
1792  LD->getAlign() == Alignment &&
1793  !LD->isVolatile() && !LD->isIndexed() &&
1795  bool isTail = isInTailCallPosition(DAG, ST, Chain);
1796  return DAG.getMemmove(Chain, dl, ST->getBasePtr(), LD->getBasePtr(),
1797  DAG.getConstant(StoreBits / 8, dl, MVT::i32),
1798  Alignment, false, isTail,
1799  ST->getPointerInfo(), LD->getPointerInfo());
1800  }
1801  }
1802  break;
1803  }
1804  }
1805  return SDValue();
1806 }
1807 
1808 void XCoreTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1809  KnownBits &Known,
1810  const APInt &DemandedElts,
1811  const SelectionDAG &DAG,
1812  unsigned Depth) const {
1813  Known.resetAll();
1814  switch (Op.getOpcode()) {
1815  default: break;
1816  case XCoreISD::LADD:
1817  case XCoreISD::LSUB:
1818  if (Op.getResNo() == 1) {
1819  // Top bits of carry / borrow are clear.
1820  Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
1821  Known.getBitWidth() - 1);
1822  }
1823  break;
1825  {
1826  unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
1827  switch (IntNo) {
1828  case Intrinsic::xcore_getts:
1829  // High bits are known to be zero.
1830  Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
1831  Known.getBitWidth() - 16);
1832  break;
1833  case Intrinsic::xcore_int:
1834  case Intrinsic::xcore_inct:
1835  // High bits are known to be zero.
1836  Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
1837  Known.getBitWidth() - 8);
1838  break;
1839  case Intrinsic::xcore_testct:
1840  // Result is either 0 or 1.
1841  Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
1842  Known.getBitWidth() - 1);
1843  break;
1844  case Intrinsic::xcore_testwct:
1845  // Result is in the range 0 - 4.
1846  Known.Zero = APInt::getHighBitsSet(Known.getBitWidth(),
1847  Known.getBitWidth() - 3);
1848  break;
1849  }
1850  }
1851  break;
1852  }
1853 }
1854 
1855 //===----------------------------------------------------------------------===//
1856 // Addressing mode description hooks
1857 //===----------------------------------------------------------------------===//
1858 
1859 static inline bool isImmUs(int64_t val)
1860 {
1861  return (val >= 0 && val <= 11);
1862 }
1863 
1864 static inline bool isImmUs2(int64_t val)
1865 {
1866  return (val%2 == 0 && isImmUs(val/2));
1867 }
1868 
1869 static inline bool isImmUs4(int64_t val)
1870 {
1871  return (val%4 == 0 && isImmUs(val/4));
1872 }
1873 
1874 /// isLegalAddressingMode - Return true if the addressing mode represented
1875 /// by AM is legal for this target, for a load/store of the specified type.
1877  const AddrMode &AM, Type *Ty,
1878  unsigned AS,
1879  Instruction *I) const {
1880  if (Ty->getTypeID() == Type::VoidTyID)
1881  return AM.Scale == 0 && isImmUs(AM.BaseOffs) && isImmUs4(AM.BaseOffs);
1882 
1883  unsigned Size = DL.getTypeAllocSize(Ty);
1884  if (AM.BaseGV) {
1885  return Size >= 4 && !AM.HasBaseReg && AM.Scale == 0 &&
1886  AM.BaseOffs%4 == 0;
1887  }
1888 
1889  switch (Size) {
1890  case 1:
1891  // reg + imm
1892  if (AM.Scale == 0) {
1893  return isImmUs(AM.BaseOffs);
1894  }
1895  // reg + reg
1896  return AM.Scale == 1 && AM.BaseOffs == 0;
1897  case 2:
1898  case 3:
1899  // reg + imm
1900  if (AM.Scale == 0) {
1901  return isImmUs2(AM.BaseOffs);
1902  }
1903  // reg + reg<<1
1904  return AM.Scale == 2 && AM.BaseOffs == 0;
1905  default:
1906  // reg + imm
1907  if (AM.Scale == 0) {
1908  return isImmUs4(AM.BaseOffs);
1909  }
1910  // reg + reg<<2
1911  return AM.Scale == 4 && AM.BaseOffs == 0;
1912  }
1913 }
1914 
1915 //===----------------------------------------------------------------------===//
1916 // XCore Inline Assembly Support
1917 //===----------------------------------------------------------------------===//
1918 
1919 std::pair<unsigned, const TargetRegisterClass *>
1920 XCoreTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
1921  StringRef Constraint,
1922  MVT VT) const {
1923  if (Constraint.size() == 1) {
1924  switch (Constraint[0]) {
1925  default : break;
1926  case 'r':
1927  return std::make_pair(0U, &XCore::GRRegsRegClass);
1928  }
1929  }
1930  // Use the default implementation in TargetLowering to convert the register
1931  // constraint into a member of a register class.
1932  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
1933 }
llvm::ISD::SUB
@ SUB
Definition: ISDOpcodes.h:240
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::CCValAssign::getLocVT
MVT getLocVT() const
Definition: CallingConvLower.h:151
llvm::MachineRegisterInfo::addLiveIn
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Definition: MachineRegisterInfo.h:959
llvm::SelectionDAG::getMemcpy
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
Definition: SelectionDAG.cpp:7268
i
i
Definition: README.txt:29
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:156
llvm::TargetLoweringBase::MaxStoresPerMemsetOptSize
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
Definition: TargetLowering.h:3369
llvm::CCValAssign::ZExt
@ ZExt
Definition: CallingConvLower.h:36
ValueTypes.h
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1581
llvm::Type::isSized
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:269
llvm::TargetLoweringBase::setSchedulingPreference
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
Definition: TargetLowering.h:2272
llvm::SelectionDAG::getCALLSEQ_START
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
Definition: SelectionDAG.h:957
llvm::ISD::INTRINSIC_VOID
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition: ISDOpcodes.h:199
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
XCoreISelLowering.h
llvm::XCoreISD::CPRelativeWrapper
@ CPRelativeWrapper
Definition: XCoreISelLowering.h:41
llvm::Value::getPointerAlignment
Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition: Value.cpp:918
llvm::XCoreFunctionInfo::createLRSpillSlot
int createLRSpillSlot(MachineFunction &MF)
Definition: XCoreMachineFunctionInfo.cpp:41
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1103
llvm::CCValAssign::Full
@ Full
Definition: CallingConvLower.h:34
llvm::TargetLoweringBase::Legal
@ Legal
Definition: TargetLowering.h:195
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::ISD::OR
@ OR
Definition: ISDOpcodes.h:667
LowerCallResult
static SDValue LowerCallResult(SDValue Chain, SDValue InFlag, const SmallVectorImpl< CCValAssign > &RVLocs, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals)
LowerCallResult - Lower the result values of a call into the appropriate copies out of appropriate ph...
Definition: XCoreISelLowering.cpp:1058
llvm::Type::getInt8PtrTy
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:291
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:156
llvm::ISD::BR_JT
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:991
PHI
Rewrite undef for PHI
Definition: AMDGPURewriteUndefForPHI.cpp:101
llvm::KnownBits::resetAll
void resetAll()
Resets the known state of all bits.
Definition: KnownBits.h:66
llvm::ISD::NON_EXTLOAD
@ NON_EXTLOAD
Definition: ISDOpcodes.h:1404
llvm::CCState
CCState - This class holds information needed while lowering arguments and return values.
Definition: CallingConvLower.h:189
llvm::XCoreISD::NodeType
NodeType
Definition: XCoreISelLowering.h:27
llvm::SelectionDAG::getCopyToReg
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:764
llvm::XCoreTargetLowering::getJumpTableEncoding
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
Definition: XCoreISelLowering.cpp:337
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
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:159
llvm::Type::VoidTyID
@ VoidTyID
type with no size
Definition: Type.h:63
llvm::ISD::DYNAMIC_STACKALLOC
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:976
XCore.h
llvm::ARM_MB::LD
@ LD
Definition: ARMBaseInfo.h:72
llvm::KnownBits::Zero
APInt Zero
Definition: KnownBits.h:24
llvm::ISD::INIT_TRAMPOLINE
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
Definition: ISDOpcodes.h:1124
llvm::TargetLoweringBase::MaxStoresPerMemset
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
Definition: TargetLowering.h:3367
High
uint64_t High
Definition: NVVMIntrRange.cpp:61
llvm::SelectionDAG::getFrameIndex
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
Definition: SelectionDAG.cpp:1725
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1181
llvm::CallingConv::Fast
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
llvm::ISD::STACKRESTORE
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1057
llvm::XCoreISD::PCRelativeWrapper
@ PCRelativeWrapper
Definition: XCoreISelLowering.h:35
llvm::XCoreFrameLowering::stackSlotSize
static int stackSlotSize()
Stack slot size (4 bytes)
Definition: XCoreFrameLowering.h:58
llvm::SelectionDAG::getVTList
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
Definition: SelectionDAG.cpp:9316
llvm::MipsISD::Lo
@ Lo
Definition: MipsISelLowering.h:79
llvm::XCoreISD::STWSP
@ STWSP
Definition: XCoreISelLowering.h:47
ErrorHandling.h
llvm::ConstantExpr::getBitCast
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2202
llvm::ISD::ANY_EXTEND
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:766
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:462
llvm::Type::getTypeID
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:136
llvm::TargetLowering::SimplifyDemandedBits
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Op.
Definition: TargetLowering.cpp:1061
llvm::LoadSDNode
This class is used to represent ISD::LOAD nodes.
Definition: SelectionDAGNodes.h:2342
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:272
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:237
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
MachineJumpTableInfo.h
llvm::XCoreISD::MACCU
@ MACCU
Definition: XCoreISelLowering.h:62
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::ISD::SHL_PARTS
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:749
llvm::SelectionDAG::getStore
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
Definition: SelectionDAG.cpp:7976
llvm::SelectionDAG::isBaseWithConstantOffset
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
Definition: SelectionDAG.cpp:4666
llvm::GlobalValue::hasSection
bool hasSection() const
Definition: GlobalValue.h:284
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
llvm::TargetLoweringBase::setMinFunctionAlignment
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
Definition: TargetLowering.h:2482
llvm::TargetLowering::LowerCallTo
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
Definition: SelectionDAGBuilder.cpp:9731
Results
Function Alias Analysis Results
Definition: AliasAnalysis.cpp:830
llvm::ConstantSDNode::isZero
bool isZero() const
Definition: SelectionDAGNodes.h:1605
XCoreTargetObjectFile.h
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:891
llvm::ISD::VAEND
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1086
llvm::ISD::EXTLOAD
@ EXTLOAD
Definition: ISDOpcodes.h:1404
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::Type::getInt8Ty
static IntegerType * getInt8Ty(LLVMContext &C)
Definition: Type.cpp:237
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::XCoreTargetLowering::ReplaceNodeResults
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
Definition: XCoreISelLowering.cpp:229
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:239
llvm::SelectionDAG::getContext
LLVMContext * getContext() const
Definition: SelectionDAG.h:476
F
#define F(x, y, z)
Definition: MD5.cpp:55
MachineRegisterInfo.h
KnownBits.h
llvm::AtomicOrdering::Monotonic
@ Monotonic
llvm::SelectionDAG::getRegister
SDValue getRegister(unsigned Reg, EVT VT)
Definition: SelectionDAG.cpp:2107
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
llvm::MipsISD::Hi
@ Hi
Definition: MipsISelLowering.h:75
llvm::KnownBits::countMinTrailingZeros
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
Definition: KnownBits.h:233
llvm::XCoreTargetLowering
Definition: XCoreISelLowering.h:91
llvm::EVT::isSimple
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:129
llvm::GlobalValue::getSection
StringRef getSection() const
Definition: Globals.cpp:171
isImmUs
static bool isImmUs(int64_t val)
Definition: XCoreISelLowering.cpp:1859
llvm::ISD::ROTL
@ ROTL
Definition: ISDOpcodes.h:694
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::TargetLoweringBase::setTargetDAGCombine
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
Definition: TargetLowering.h:2474
llvm::TargetLowering::isInTailCallPosition
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
Definition: TargetLowering.cpp:51
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
llvm::MVT::integer_valuetypes
static auto integer_valuetypes()
Definition: MachineValueType.h:1472
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::ISD::BR_CC
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1008
x3
In x86 we generate this spiffy xmm0 xmm0 ret in x86 we generate this which could be xmm1 movss xmm1 xmm0 ret In sse4 we could use insertps to make both better Here s another testcase that could use x3
Definition: README-SSE.txt:547
llvm::SelectionDAG::getLoad
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Definition: SelectionDAG.cpp:7926
R2
#define R2(n)
llvm::MVT::i1
@ i1
Definition: MachineValueType.h:43
llvm::TargetLowering::CallLoweringInfo::IsVarArg
bool IsVarArg
Definition: TargetLowering.h:4084
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:666
llvm::CCValAssign::AExt
@ AExt
Definition: CallingConvLower.h:37
IsSmallObject
static bool IsSmallObject(const GlobalValue *GV, const XCoreTargetLowering &XTL)
Definition: XCoreISelLowering.cpp:263
llvm::ISD::GlobalAddress
@ GlobalAddress
Definition: ISDOpcodes.h:78
llvm::ISD::SELECT_CC
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:728
llvm::ExternalSymbolSDNode
Definition: SelectionDAGNodes.h:2235
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:98
llvm::SDValue::getValueType
EVT getValueType() const
Return the ValueType of the referenced return value.
Definition: SelectionDAGNodes.h:1138
llvm::CCValAssign
CCValAssign - Represent assignment of one arg/retval to a location.
Definition: CallingConvLower.h:31
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
llvm::StringRef::startswith
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:256
llvm::SelectionDAG
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:220
Constants.h
llvm::ISD::ZERO_EXTEND
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:763
llvm::SelectionDAG::getTargetBlockAddress
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:759
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::SelectionDAG::getTruncStore
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Definition: SelectionDAG.cpp:8028
llvm::CCValAssign::getLocReg
Register getLocReg() const
Definition: CallingConvLower.h:148
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:754
llvm::SDValue::reachesChainWithoutSideEffects
bool reachesChainWithoutSideEffects(SDValue Dest, unsigned Depth=2) const
Return true if this operand (which must be a chain) reaches the specified operand without crossing an...
Definition: SelectionDAG.cpp:11097
llvm::SelectionDAG::getTargetLoweringInfo
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:472
llvm::XCoreISD::LSUB
@ LSUB
Definition: XCoreISelLowering.h:56
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:34
Intrinsics.h
llvm::TargetLoweringBase::AddrMode::HasBaseReg
bool HasBaseReg
Definition: TargetLowering.h:2555
llvm::SelectionDAG::getConstant
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
Definition: SelectionDAG.cpp:1495
llvm::JumpTableSDNode
Definition: SelectionDAGNodes.h:1860
int
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Definition: README.txt:536
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition: TargetLowering.h:3446
llvm::SelectionDAG::MaskedValueIsZero
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
Definition: SelectionDAG.cpp:2518
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::MVT::SimpleTy
SimpleValueType SimpleTy
Definition: MachineValueType.h:331
llvm::SPII::Store
@ Store
Definition: SparcInstrInfo.h:33
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::TargetLoweringBase::addRegisterClass
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
Definition: TargetLowering.h:2319
llvm::XCoreISD::DPRelativeWrapper
@ DPRelativeWrapper
Definition: XCoreISelLowering.h:38
llvm::CodeModel::Small
@ Small
Definition: CodeGen.h:28
llvm::XCoreSubtarget::getRegisterInfo
const TargetRegisterInfo * getRegisterInfo() const override
Definition: XCoreSubtarget.h:59
llvm::EVT::isInteger
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:144
llvm::Instruction
Definition: Instruction.h:42
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
XCoreMachineFunctionInfo.h
llvm::APInt::getHighBitsSet
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition: APInt.h:279
llvm::codeview::EncodedFramePtrReg::BasePtr
@ BasePtr
llvm::ISD::ATOMIC_STORE
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
Definition: ISDOpcodes.h:1163
llvm::ThreadPriority::Low
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:879
llvm::TargetLoweringBase::MaxStoresPerMemcpy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
Definition: TargetLowering.h:3382
llvm::ISD::AND
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:666
llvm::CCValAssign::getLocInfo
LocInfo getLocInfo() const
Definition: CallingConvLower.h:153
XCoreSubtarget.h
Align
uint64_t Align
Definition: ELFObjHandler.cpp:81
llvm::GlobalAddressSDNode::getGlobal
const GlobalValue * getGlobal() const
Definition: SelectionDAGNodes.h:1769
llvm::CCValAssign::getLocMemOffset
unsigned getLocMemOffset() const
Definition: CallingConvLower.h:149
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::TargetLoweringBase::setBooleanVectorContents
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
Definition: TargetLowering.h:2267
llvm::Type::isFunctionTy
bool isFunctionTy() const
True if this is an instance of FunctionType.
Definition: Type.h:214
llvm::SDValue::getValueSizeInBits
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
Definition: SelectionDAGNodes.h:199
llvm::XCoreFunctionInfo::setVarArgsFrameIndex
void setVarArgsFrameIndex(int off)
Definition: XCoreMachineFunctionInfo.h:55
llvm::XCoreISD::FIRST_NUMBER
@ FIRST_NUMBER
Definition: XCoreISelLowering.h:29
llvm::CCValAssign::isRegLoc
bool isRegLoc() const
Definition: CallingConvLower.h:143
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::XCoreTargetLowering::isZExtFree
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
Definition: XCoreISelLowering.cpp:177
llvm::SelectionDAG::getTargetGlobalAddress
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:712
llvm::TargetLowering::TargetLoweringOpt
A convenience struct that encapsulates a DAG, and two SDValues for returning information from TargetL...
Definition: TargetLowering.h:3570
llvm::ISD::BlockAddress
@ BlockAddress
Definition: ISDOpcodes.h:84
llvm::TargetLowering::CallLoweringInfo::Outs
SmallVector< ISD::OutputArg, 32 > Outs
Definition: TargetLowering.h:4107
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
llvm::TargetLoweringBase::setOperationAction
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
Definition: TargetLowering.h:2336
llvm::TargetLoweringBase::MaxStoresPerMemcpyOptSize
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
Definition: TargetLowering.h:3384
val
The initial backend is deliberately restricted to z10 We should add support for later architectures at some point If an asm ties an i32 r result to an i64 the input will be treated as an leaving the upper bits uninitialised For i64 store i32 val
Definition: README.txt:15
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::MachineJumpTableInfo::getJumpTables
const std::vector< MachineJumpTableEntry > & getJumpTables() const
Definition: MachineJumpTableInfo.h:99
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::EVT::getSizeInBits
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:340
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
llvm::CCValAssign::SExt
@ SExt
Definition: CallingConvLower.h:35
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
index
splat index
Definition: README_ALTIVEC.txt:181
llvm::ISD::ATOMIC_FENCE
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition: ISDOpcodes.h:1155
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:650
llvm::ISD::LOAD
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:966
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:78
llvm::TargetLowering::CallLoweringInfo::Chain
SDValue Chain
Definition: TargetLowering.h:4080
llvm::SelectionDAG::getIntPtrConstant
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Definition: SelectionDAG.cpp:1618
llvm::XCoreISD::LDWSP
@ LDWSP
Definition: XCoreISelLowering.h:44
llvm::TargetLoweringBase::Promote
@ Promote
Definition: TargetLowering.h:196
llvm::ISD::TRAP
@ TRAP
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:1133
llvm::MachinePointerInfo
This class contains a discriminated union of information about pointers in memory operands,...
Definition: MachineMemOperand.h:39
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
llvm::TargetRegisterInfo::getFrameRegister
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
llvm::SelectionDAG::getConstantPool
SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=None, int Offs=0, bool isT=false, unsigned TargetFlags=0)
Definition: SelectionDAG.cpp:1759
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:53
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:790
llvm::TargetLowering::CallLoweringInfo::CallConv
CallingConv::ID CallConv
Definition: TargetLowering.h:4101
llvm::TargetLoweringBase::setStackPointerRegisterToSaveRestore
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
Definition: TargetLowering.h:2285
llvm::AtomicOrdering::Unordered
@ Unordered
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::MCPhysReg
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:21
llvm::SelectionDAG::getNode
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
Definition: SelectionDAG.cpp:9010
llvm::TargetLoweringBase::setPrefFunctionAlignment
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
Definition: TargetLowering.h:2488
size
i< reg-> size
Definition: README.txt:166
llvm::TargetLowering::CallLoweringInfo::DL
SDLoc DL
Definition: TargetLowering.h:4105
llvm::XCoreTargetLowering::getTargetNodeName
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName - This method returns the name of a target specific
Definition: XCoreISelLowering.cpp:45
llvm::XCoreSubtarget::getInstrInfo
const XCoreInstrInfo * getInstrInfo() const override
Definition: XCoreSubtarget.h:49
llvm::GlobalAddressSDNode::getOffset
int64_t getOffset() const
Definition: SelectionDAGNodes.h:1770
llvm::pdb::PDB_MemoryType::Stack
@ Stack
llvm::MachineMemOperand::Flags
Flags
Flags values. These may be or'd together.
Definition: MachineMemOperand.h:130
llvm::StoreSDNode
This class is used to represent ISD::STORE nodes.
Definition: SelectionDAGNodes.h:2370
llvm::ISD::ZEXTLOAD
@ ZEXTLOAD
Definition: ISDOpcodes.h:1404
llvm::SDValue::getValue
SDValue getValue(unsigned R) const
Definition: SelectionDAGNodes.h:179
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:46
llvm::TargetLowering::CallLoweringInfo
This structure contains all information that is necessary for lowering calls.
Definition: TargetLowering.h:4079
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
llvm::ISD::ADJUST_TRAMPOLINE
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
Definition: ISDOpcodes.h:1130
llvm::ISD::MULHS
@ MULHS
Definition: ISDOpcodes.h:638
llvm::MachineFrameInfo::CreateFixedObject
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
Definition: MachineFrameInfo.cpp:83
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:42
llvm::MVT::getSizeInBits
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
Definition: MachineValueType.h:890
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:672
load
LLVM currently emits rax rax movq rax rax ret It could narrow the loads and stores to emit rax rax movq rax rax ret The trouble is that there is a TokenFactor between the store and the load
Definition: README.txt:1531
SI
StandardInstrumentations SI(Debug, VerifyEach)
llvm::ConstantSDNode::getZExtValue
uint64_t getZExtValue() const
Definition: SelectionDAGNodes.h:1596
llvm::GlobalValue::hasLocalLinkage
bool hasLocalLinkage() const
Definition: GlobalValue.h:521
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::ISD::SRA_PARTS
@ SRA_PARTS
Definition: ISDOpcodes.h:750
llvm::ISD::VASTART
@ VASTART
Definition: ISDOpcodes.h:1087
llvm::SelectionDAG::getGlobalAddress
SDValue getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, bool isTargetGA=false, unsigned TargetFlags=0)
Definition: SelectionDAG.cpp:1692
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::XCoreFunctionInfo
XCoreFunctionInfo - This class is derived from MachineFunction private XCore target-specific informat...
Definition: XCoreMachineFunctionInfo.h:27
llvm::SelectionDAG::getCALLSEQ_END
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
Definition: SelectionDAG.h:969
llvm::TargetLowering::CallLoweringInfo::Ins
SmallVector< ISD::InputArg, 32 > Ins
Definition: TargetLowering.h:4109
llvm::ISD::ConstantPool
@ ConstantPool
Definition: ISDOpcodes.h:82
llvm::BlockAddress
The address of a basic block.
Definition: Constants.h:849
llvm::TargetLowering::CallLoweringInfo::DAG
SelectionDAG & DAG
Definition: TargetLowering.h:4104
llvm::SelectionDAG::getTargetConstantPool
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=None, int Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:728
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:98
llvm::ConstantPoolSDNode
Definition: SelectionDAGNodes.h:1881
Mul
BinaryOperator * Mul
Definition: X86PartialReduction.cpp:70
llvm::MVT::i64
@ i64
Definition: MachineValueType.h:49
llvm::MachineFrameInfo::CreateStackObject
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
Definition: MachineFrameInfo.cpp:51
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::MachineBasicBlock::splice
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
Definition: MachineBasicBlock.h:1009
llvm::XCoreFunctionInfo::setReturnStackOffset
void setReturnStackOffset(unsigned value)
Definition: XCoreMachineFunctionInfo.h:79
isImmUs4
static bool isImmUs4(int64_t val)
Definition: XCoreISelLowering.cpp:1869
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::ISD::UMUL_LOHI
@ UMUL_LOHI
Definition: ISDOpcodes.h:251
llvm::TargetLoweringBase::AddrMode::BaseGV
GlobalValue * BaseGV
Definition: TargetLowering.h:2553
llvm::ISD::ArgFlagsTy
Definition: TargetCallingConv.h:27
llvm::TargetLoweringBase::MaxStoresPerMemmoveOptSize
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
Definition: TargetLowering.h:3419
llvm::SDValue::getOperand
const SDValue & getOperand(unsigned i) const
Definition: SelectionDAGNodes.h:1146
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::TargetLowering::isGAPlusOffset
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
Definition: TargetLowering.cpp:5080
llvm::XCoreFunctionInfo::getVarArgsFrameIndex
int getVarArgsFrameIndex() const
Definition: XCoreMachineFunctionInfo.h:56
llvm::SDValue::hasOneUse
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
Definition: SelectionDAGNodes.h:1182
llvm::XCoreISD::MEMBARRIER
@ MEMBARRIER
Definition: XCoreISelLowering.h:84
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::XCoreISD::LADD
@ LADD
Definition: XCoreISelLowering.h:53
llvm::TargetLowering::getRegForInlineAsmConstraint
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
Definition: TargetLowering.cpp:5266
llvm::SelectionDAG::getMemmove
SDValue getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
Definition: SelectionDAG.cpp:7382
llvm::SDVTList
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
Definition: SelectionDAGNodes.h:79
llvm::MachineMemOperand::MOVolatile
@ MOVolatile
The memory access is volatile.
Definition: MachineMemOperand.h:138
llvm::ISD::SEXTLOAD
@ SEXTLOAD
Definition: ISDOpcodes.h:1404
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::TargetLoweringBase::ArgListTy
std::vector< ArgListEntry > ArgListTy
Definition: TargetLowering.h:311
llvm::SelectionDAG::getTargetJumpTable
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:722
llvm::ISD::FRAMEADDR
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:94
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:187
llvm::AtomicSDNode
This is an SDNode representing atomic operations.
Definition: SelectionDAGNodes.h:1441
llvm::EVT::getEVTString
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
Definition: ValueTypes.cpp:152
llvm::CodeModelLargeSize
static const unsigned CodeModelLargeSize
Definition: XCoreTargetObjectFile.h:16
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
CallingConv.h
llvm::HexagonISD::CP
@ CP
Definition: HexagonISelLowering.h:53
llvm::TargetLoweringBase::getTargetMachine
const TargetMachine & getTargetMachine() const
Definition: TargetLowering.h:346
llvm::TargetLowering::CallLoweringInfo::IsTailCall
bool IsTailCall
Definition: TargetLowering.h:4095
llvm::DataLayout::getIntPtrType
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Definition: DataLayout.cpp:842
llvm::TargetLoweringBase::AddrMode::BaseOffs
int64_t BaseOffs
Definition: TargetLowering.h:2554
llvm::CCValAssign::isMemLoc
bool isMemLoc() const
Definition: CallingConvLower.h:144
llvm::XCoreISD::MACCS
@ MACCS
Definition: XCoreISelLowering.h:65
llvm::SelectionDAG::computeKnownBits
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
Definition: SelectionDAG.cpp:2894
llvm::TargetLoweringBase::setLoadExtAction
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
Definition: TargetLowering.h:2353
llvm::GlobalAddressSDNode
Definition: SelectionDAGNodes.h:1757
llvm::KnownBits
Definition: KnownBits.h:23
llvm::TargetLoweringBase::AddrMode::Scale
int64_t Scale
Definition: TargetLowering.h:2556
CallingConvLower.h
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::XCoreISD::RETSP
@ RETSP
Definition: XCoreISelLowering.h:50
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
MachineFrameInfo.h
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:545
GlobalVariable.h
llvm::MachineJumpTableInfo::EK_Inline
@ EK_Inline
EK_Inline - Jump table entries are emitted inline at their point of use.
Definition: MachineJumpTableInfo.h:72
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:466
llvm::XCoreTargetLowering::XCoreTargetLowering
XCoreTargetLowering(const TargetMachine &TM, const XCoreSubtarget &Subtarget)
Definition: XCoreISelLowering.cpp:72
llvm::ISD::FRAME_TO_ARGS_OFFSET
@ FRAME_TO_ARGS_OFFSET
FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to first (possible) on-stack ar...
Definition: ISDOpcodes.h:124
Function.h
llvm::TargetLoweringBase::Custom
@ Custom
Definition: TargetLowering.h:199
llvm::XCoreTargetLowering::isLegalAddressingMode
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
Definition: XCoreISelLowering.cpp:1876
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:1875
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:48
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:145
llvm::SDNode::getNumValues
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
Definition: SelectionDAGNodes.h:980
llvm::ISD::EH_RETURN
@ EH_RETURN
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin,...
Definition: ISDOpcodes.h:135
llvm::ConstantExpr::getGetElementPtr
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
Definition: Constants.h:1218
llvm::TargetLoweringBase::ZeroOrOneBooleanContent
@ ZeroOrOneBooleanContent
Definition: TargetLowering.h:231
XCoreTargetMachine.h
llvm::XCoreISD::FRAME_TO_ARGS_OFFSET
@ FRAME_TO_ARGS_OFFSET
Definition: XCoreISelLowering.h:77
llvm::XCoreTargetLowering::LowerOperation
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
Definition: XCoreISelLowering.cpp:196
llvm::XCoreISD::LMUL
@ LMUL
Definition: XCoreISelLowering.h:59
llvm::ISD::STORE
@ STORE
Definition: ISDOpcodes.h:967
llvm::ISD::VACOPY
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1082
llvm::ISD::SRL_PARTS
@ SRL_PARTS
Definition: ISDOpcodes.h:751
GlobalAlias.h
llvm::XCoreISD::CRC8
@ CRC8
Definition: XCoreISelLowering.h:68
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
llvm::XCoreFunctionInfo::getReturnStackOffset
unsigned getReturnStackOffset() const
Definition: XCoreMachineFunctionInfo.h:85
llvm::XCoreISD::BR_JT
@ BR_JT
Definition: XCoreISelLowering.h:71
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:222
llvm::XCoreISD::EH_RETURN
@ EH_RETURN
Definition: XCoreISelLowering.h:81
llvm::TargetLoweringBase::setBooleanContents
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
Definition: TargetLowering.h:2253
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:105
llvm::ISD::SHL
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:691
llvm::TargetLoweringBase::allowsMemoryAccessForAlignment
bool allowsMemoryAccessForAlignment(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, bool *Fast=nullptr) const
This function returns true if the memory access is aligned or if the target allows this specific unal...
Definition: TargetLoweringBase.cpp:1717
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
llvm::MachinePointerInfo::getFixedStack
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Definition: MachineOperand.cpp:1018
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:305
MachineInstrBuilder.h
llvm::ISD::MUL
@ MUL
Definition: ISDOpcodes.h:241
llvm::TargetLoweringBase::Expand
@ Expand
Definition: TargetLowering.h:197
llvm::CCValAssign::getValVT
MVT getValVT() const
Definition: CallingConvLower.h:141
N
#define N
llvm::TargetLoweringBase::computeRegisterProperties
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
Definition: TargetLoweringBase.cpp:1284
llvm::ISD::BITREVERSE
@ BITREVERSE
Definition: ISDOpcodes.h:704
llvm::ISD::SRL
@ SRL
Definition: ISDOpcodes.h:693
isADDADDMUL
static bool isADDADDMUL(SDValue Op, SDValue &Mul0, SDValue &Mul1, SDValue &Addend0, SDValue &Addend1, bool requireIntermediatesHaveOneUse)
isADDADDMUL - Return whether Op is in a form that is equivalent to add(add(mul(x,y),...
Definition: XCoreISelLowering.cpp:576
llvm::TargetLoweringBase::AddrMode
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
Definition: TargetLowering.h:2552
isWordAligned
static bool isWordAligned(SDValue Value, SelectionDAG &DAG)
Definition: XCoreISelLowering.cpp:402
llvm::MipsISD::Ins
@ Ins
Definition: MipsISelLowering.h:160
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::ISD::MULHU
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:637
llvm::TargetLowering::CallLoweringInfo::OutVals
SmallVector< SDValue, 32 > OutVals
Definition: TargetLowering.h:4108
llvm::MachineBasicBlock::transferSuccessorsAndUpdatePHIs
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
Definition: MachineBasicBlock.cpp:901
llvm::SDValue::getOpcode
unsigned getOpcode() const
Definition: SelectionDAGNodes.h:1134
llvm::Module::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:398
DerivedTypes.h
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition: GlobalValue.h:290
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::TargetLowering::CallLoweringInfo::Callee
SDValue Callee
Definition: TargetLowering.h:4102
llvm::APInt::getLowBitsSet
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition: APInt.h:289
llvm::MVT::i16
@ i16
Definition: MachineValueType.h:47
llvm::ISD::INTRINSIC_W_CHAIN
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition: ISDOpcodes.h:192
llvm::SelectionDAG::getMachineFunction
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:463
llvm::SelectionDAG::ComputeNumSignBits
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
Definition: SelectionDAG.cpp:3916
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::TargetMachine::getCodeModel
CodeModel::Model getCodeModel() const
Returns the code model.
Definition: TargetMachine.h:225
llvm::ISD::BUILD_PAIR
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition: ISDOpcodes.h:229
llvm::ISD::VAARG
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1077
llvm::KnownBits::getBitWidth
unsigned getBitWidth() const
Get the bit width of this value.
Definition: KnownBits.h:40
llvm::SelectionDAG::getExternalSymbol
SDValue getExternalSymbol(const char *Sym, EVT VT)
Definition: SelectionDAG.cpp:1858
llvm::MachineFunction::getJumpTableInfo
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
Definition: MachineFunction.h:679
llvm::TargetLowering::ShrinkDemandedConstant
bool ShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, TargetLoweringOpt &TLO) const
Check to see if the specified operand of the specified instruction is a constant integer.
Definition: TargetLowering.cpp:499
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition: User.h:169
llvm::MachineJumpTableInfo
Definition: MachineJumpTableInfo.h:42
llvm::ISD::SIGN_EXTEND
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:760
raw_ostream.h
MachineFunction.h
llvm::XCoreTargetLowering::EmitInstrWithCustomInserter
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Definition: XCoreISelLowering.cpp:1517
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineMemOperand::MONone
@ MONone
Definition: MachineMemOperand.h:132
llvm::XCoreSubtarget
Definition: XCoreSubtarget.h:31
llvm::ISD::STACKSAVE
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1053
llvm::TargetLoweringBase::MaxStoresPerMemmove
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
Definition: TargetLowering.h:3417
llvm::SelectionDAG::getExtLoad
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Definition: SelectionDAG.cpp:7943
llvm::XCoreISD::BL
@ BL
Definition: XCoreISelLowering.h:32
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::ISD::ROTR
@ ROTR
Definition: ISDOpcodes.h:695
Debug.h
llvm::ISD::ATOMIC_LOAD
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
Definition: ISDOpcodes.h:1159
llvm::TargetLoweringBase::getPointerTy
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Definition: TargetLowering.h:353
llvm::ISD::CTPOP
@ CTPOP
Definition: ISDOpcodes.h:703
isImmUs2
static bool isImmUs2(int64_t val)
Definition: XCoreISelLowering.cpp:1864
llvm::XCoreISD::BR_JT32
@ BR_JT32
Definition: XCoreISelLowering.h:74
llvm::ISD::TokenFactor
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
llvm::SelectionDAG::getMergeValues
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
Definition: SelectionDAG.cpp:7690
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1247
llvm::ISD::EXTRACT_ELEMENT
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
Definition: ISDOpcodes.h:222
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:288