LLVM  16.0.0git
LoongArchISelLowering.cpp
Go to the documentation of this file.
1 //=- LoongArchISelLowering.cpp - LoongArch 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 defines the interfaces that LoongArch uses to lower LLVM code into
10 // a selection DAG.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "LoongArchISelLowering.h"
15 #include "LoongArch.h"
17 #include "LoongArchRegisterInfo.h"
18 #include "LoongArchSubtarget.h"
19 #include "LoongArchTargetMachine.h"
22 #include "llvm/ADT/Statistic.h"
25 #include "llvm/IR/IRBuilder.h"
26 #include "llvm/IR/IntrinsicsLoongArch.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/KnownBits.h"
29 
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "loongarch-isel-lowering"
33 
34 STATISTIC(NumTailCalls, "Number of tail calls");
35 
37  "loongarch-check-zero-division", cl::Hidden,
38  cl::desc("Trap on integer division by zero."),
39  cl::init(false));
40 
42  const LoongArchSubtarget &STI)
43  : TargetLowering(TM), Subtarget(STI) {
44 
45  MVT GRLenVT = Subtarget.getGRLenVT();
46  // Set up the register classes.
47  addRegisterClass(GRLenVT, &LoongArch::GPRRegClass);
48  if (Subtarget.hasBasicF())
49  addRegisterClass(MVT::f32, &LoongArch::FPR32RegClass);
50  if (Subtarget.hasBasicD())
51  addRegisterClass(MVT::f64, &LoongArch::FPR64RegClass);
52 
54  MVT::i1, Promote);
55 
56  // TODO: add necessary setOperationAction calls later.
66 
69  GRLenVT, Custom);
70 
72 
74 
76  if (Subtarget.is64Bit())
78 
83 
84  if (Subtarget.is64Bit()) {
98  if (Subtarget.hasBasicF() && !Subtarget.hasBasicD())
100  if (Subtarget.hasBasicF())
102  if (Subtarget.hasBasicD())
104  }
105 
106  // LA32 does not have REVB.2W and REVB.D due to the 64-bit operands, and
107  // the narrower REVB.W does not exist. But LA32 does have REVB.2H, so i16
108  // and i32 could still be byte-swapped relatively cheaply.
110  if (Subtarget.is64Bit()) {
112  }
113 
114  // Expand bitreverse.i16 with native-width bitrev and shift for now, before
115  // we get to know which of sll and revb.2h is faster.
117  if (Subtarget.is64Bit()) {
120  } else {
125  }
126 
127  static const ISD::CondCode FPCCToExpand[] = {
130 
131  if (Subtarget.hasBasicF()) {
132  setCondCodeAction(FPCCToExpand, MVT::f32, Expand);
145  }
146  if (Subtarget.hasBasicD()) {
147  setCondCodeAction(FPCCToExpand, MVT::f64, Expand);
162  }
163 
165 
170  if (!Subtarget.is64Bit())
171  setLibcallName(RTLIB::MUL_I128, nullptr);
172 
175  if ((Subtarget.is64Bit() && Subtarget.hasBasicF() &&
176  !Subtarget.hasBasicD())) {
179  }
180 
181  // Compute derived properties from the register classes.
183 
185 
187 
189 
191 
192  // Function alignments.
193  const Align FunctionAlignment(4);
194  setMinFunctionAlignment(FunctionAlignment);
195 
199 }
200 
202  const GlobalAddressSDNode *GA) const {
203  // In order to maximise the opportunity for common subexpression elimination,
204  // keep a separate ADD node for the global address offset instead of folding
205  // it in the global address node. Later peephole optimisations may choose to
206  // fold it back in when profitable.
207  return false;
208 }
209 
211  SelectionDAG &DAG) const {
212  switch (Op.getOpcode()) {
213  case ISD::EH_DWARF_CFA:
214  return lowerEH_DWARF_CFA(Op, DAG);
215  case ISD::GlobalAddress:
216  return lowerGlobalAddress(Op, DAG);
218  return lowerGlobalTLSAddress(Op, DAG);
220  return lowerINTRINSIC_WO_CHAIN(Op, DAG);
222  return lowerINTRINSIC_W_CHAIN(Op, DAG);
223  case ISD::INTRINSIC_VOID:
224  return lowerINTRINSIC_VOID(Op, DAG);
225  case ISD::BlockAddress:
226  return lowerBlockAddress(Op, DAG);
227  case ISD::JumpTable:
228  return lowerJumpTable(Op, DAG);
229  case ISD::SHL_PARTS:
230  return lowerShiftLeftParts(Op, DAG);
231  case ISD::SRA_PARTS:
232  return lowerShiftRightParts(Op, DAG, true);
233  case ISD::SRL_PARTS:
234  return lowerShiftRightParts(Op, DAG, false);
235  case ISD::ConstantPool:
236  return lowerConstantPool(Op, DAG);
237  case ISD::FP_TO_SINT:
238  return lowerFP_TO_SINT(Op, DAG);
239  case ISD::BITCAST:
240  return lowerBITCAST(Op, DAG);
241  case ISD::UINT_TO_FP:
242  return lowerUINT_TO_FP(Op, DAG);
243  case ISD::SINT_TO_FP:
244  return lowerSINT_TO_FP(Op, DAG);
245  case ISD::VASTART:
246  return lowerVASTART(Op, DAG);
247  case ISD::FRAMEADDR:
248  return lowerFRAMEADDR(Op, DAG);
249  case ISD::RETURNADDR:
250  return lowerRETURNADDR(Op, DAG);
251  case ISD::WRITE_REGISTER:
252  return lowerWRITE_REGISTER(Op, DAG);
253  }
254  return SDValue();
255 }
256 
257 SDValue LoongArchTargetLowering::lowerWRITE_REGISTER(SDValue Op,
258  SelectionDAG &DAG) const {
259 
260  if (Subtarget.is64Bit() && Op.getOperand(2).getValueType() == MVT::i32) {
261  DAG.getContext()->emitError(
262  "On LA64, only 64-bit registers can be written.");
263  return Op.getOperand(0);
264  }
265 
266  if (!Subtarget.is64Bit() && Op.getOperand(2).getValueType() == MVT::i64) {
267  DAG.getContext()->emitError(
268  "On LA32, only 32-bit registers can be written.");
269  return Op.getOperand(0);
270  }
271 
272  return Op;
273 }
274 
275 SDValue LoongArchTargetLowering::lowerFRAMEADDR(SDValue Op,
276  SelectionDAG &DAG) const {
277  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
278  DAG.getContext()->emitError("argument to '__builtin_frame_address' must "
279  "be a constant integer");
280  return SDValue();
281  }
282 
285  Register FrameReg = Subtarget.getRegisterInfo()->getFrameRegister(MF);
286  EVT VT = Op.getValueType();
287  SDLoc DL(Op);
288  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameReg, VT);
289  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
290  int GRLenInBytes = Subtarget.getGRLen() / 8;
291 
292  while (Depth--) {
293  int Offset = -(GRLenInBytes * 2);
294  SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
295  DAG.getIntPtrConstant(Offset, DL));
296  FrameAddr =
297  DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
298  }
299  return FrameAddr;
300 }
301 
302 SDValue LoongArchTargetLowering::lowerRETURNADDR(SDValue Op,
303  SelectionDAG &DAG) const {
305  return SDValue();
306 
307  // Currently only support lowering return address for current frame.
308  if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() != 0) {
309  DAG.getContext()->emitError(
310  "return address can only be determined for the current frame");
311  return SDValue();
312  }
313 
316  MVT GRLenVT = Subtarget.getGRLenVT();
317 
318  // Return the value of the return address register, marking it an implicit
319  // live-in.
320  Register Reg = MF.addLiveIn(Subtarget.getRegisterInfo()->getRARegister(),
321  getRegClassFor(GRLenVT));
322  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Reg, GRLenVT);
323 }
324 
325 SDValue LoongArchTargetLowering::lowerEH_DWARF_CFA(SDValue Op,
326  SelectionDAG &DAG) const {
328  auto Size = Subtarget.getGRLen() / 8;
329  auto FI = MF.getFrameInfo().CreateFixedObject(Size, 0, false);
330  return DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
331 }
332 
333 SDValue LoongArchTargetLowering::lowerVASTART(SDValue Op,
334  SelectionDAG &DAG) const {
336  auto *FuncInfo = MF.getInfo<LoongArchMachineFunctionInfo>();
337 
338  SDLoc DL(Op);
339  SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
341 
342  // vastart just stores the address of the VarArgsFrameIndex slot into the
343  // memory location argument.
344  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
345  return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
346  MachinePointerInfo(SV));
347 }
348 
349 SDValue LoongArchTargetLowering::lowerUINT_TO_FP(SDValue Op,
350  SelectionDAG &DAG) const {
351  assert(Subtarget.is64Bit() && Subtarget.hasBasicF() &&
352  !Subtarget.hasBasicD() && "unexpected target features");
353 
354  SDLoc DL(Op);
355  SDValue Op0 = Op.getOperand(0);
356  if (Op0->getOpcode() == ISD::AND) {
357  auto *C = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
358  if (C && C->getZExtValue() < UINT64_C(0xFFFFFFFF))
359  return Op;
360  }
361 
362  if (Op0->getOpcode() == LoongArchISD::BSTRPICK &&
363  Op0.getConstantOperandVal(1) < UINT64_C(0X1F) &&
364  Op0.getConstantOperandVal(2) == UINT64_C(0))
365  return Op;
366 
367  if (Op0.getOpcode() == ISD::AssertZext &&
368  dyn_cast<VTSDNode>(Op0.getOperand(1))->getVT().bitsLT(MVT::i32))
369  return Op;
370 
371  EVT OpVT = Op0.getValueType();
372  EVT RetVT = Op.getValueType();
373  RTLIB::Libcall LC = RTLIB::getUINTTOFP(OpVT, RetVT);
374  MakeLibCallOptions CallOptions;
375  CallOptions.setTypeListBeforeSoften(OpVT, RetVT, true);
376  SDValue Chain = SDValue();
377  SDValue Result;
378  std::tie(Result, Chain) =
379  makeLibCall(DAG, LC, Op.getValueType(), Op0, CallOptions, DL, Chain);
380  return Result;
381 }
382 
383 SDValue LoongArchTargetLowering::lowerSINT_TO_FP(SDValue Op,
384  SelectionDAG &DAG) const {
385  assert(Subtarget.is64Bit() && Subtarget.hasBasicF() &&
386  !Subtarget.hasBasicD() && "unexpected target features");
387 
388  SDLoc DL(Op);
389  SDValue Op0 = Op.getOperand(0);
390 
391  if ((Op0.getOpcode() == ISD::AssertSext ||
392  Op0.getOpcode() == ISD::SIGN_EXTEND_INREG) &&
393  dyn_cast<VTSDNode>(Op0.getOperand(1))->getVT().bitsLE(MVT::i32))
394  return Op;
395 
396  EVT OpVT = Op0.getValueType();
397  EVT RetVT = Op.getValueType();
398  RTLIB::Libcall LC = RTLIB::getSINTTOFP(OpVT, RetVT);
399  MakeLibCallOptions CallOptions;
400  CallOptions.setTypeListBeforeSoften(OpVT, RetVT, true);
401  SDValue Chain = SDValue();
402  SDValue Result;
403  std::tie(Result, Chain) =
404  makeLibCall(DAG, LC, Op.getValueType(), Op0, CallOptions, DL, Chain);
405  return Result;
406 }
407 
408 SDValue LoongArchTargetLowering::lowerBITCAST(SDValue Op,
409  SelectionDAG &DAG) const {
410 
411  SDLoc DL(Op);
412  SDValue Op0 = Op.getOperand(0);
413 
414  if (Op.getValueType() == MVT::f32 && Op0.getValueType() == MVT::i32 &&
415  Subtarget.is64Bit() && Subtarget.hasBasicF()) {
416  SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0);
417  return DAG.getNode(LoongArchISD::MOVGR2FR_W_LA64, DL, MVT::f32, NewOp0);
418  }
419  return Op;
420 }
421 
422 SDValue LoongArchTargetLowering::lowerFP_TO_SINT(SDValue Op,
423  SelectionDAG &DAG) const {
424 
425  SDLoc DL(Op);
426 
427  if (Op.getValueSizeInBits() > 32 && Subtarget.hasBasicF() &&
428  !Subtarget.hasBasicD()) {
429  SDValue Dst =
430  DAG.getNode(LoongArchISD::FTINT, DL, MVT::f32, Op.getOperand(0));
432  }
433 
434  EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits());
435  SDValue Trunc = DAG.getNode(LoongArchISD::FTINT, DL, FPTy, Op.getOperand(0));
436  return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Trunc);
437 }
438 
440  SelectionDAG &DAG, unsigned Flags) {
441  return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);
442 }
443 
445  SelectionDAG &DAG, unsigned Flags) {
446  return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(),
447  Flags);
448 }
449 
451  SelectionDAG &DAG, unsigned Flags) {
452  return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
453  N->getOffset(), Flags);
454 }
455 
457  SelectionDAG &DAG, unsigned Flags) {
458  return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
459 }
460 
461 template <class NodeTy>
462 SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
463  bool IsLocal) const {
464  SDLoc DL(N);
465  EVT Ty = getPointerTy(DAG.getDataLayout());
466  SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
467  // TODO: Check CodeModel.
468  if (IsLocal)
469  // This generates the pattern (PseudoLA_PCREL sym), which expands to
470  // (addi.w/d (pcalau12i %pc_hi20(sym)) %pc_lo12(sym)).
471  return SDValue(DAG.getMachineNode(LoongArch::PseudoLA_PCREL, DL, Ty, Addr),
472  0);
473 
474  // This generates the pattern (PseudoLA_GOT sym), which expands to (ld.w/d
475  // (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)).
476  return SDValue(DAG.getMachineNode(LoongArch::PseudoLA_GOT, DL, Ty, Addr), 0);
477 }
478 
479 SDValue LoongArchTargetLowering::lowerBlockAddress(SDValue Op,
480  SelectionDAG &DAG) const {
481  return getAddr(cast<BlockAddressSDNode>(Op), DAG);
482 }
483 
484 SDValue LoongArchTargetLowering::lowerJumpTable(SDValue Op,
485  SelectionDAG &DAG) const {
486  return getAddr(cast<JumpTableSDNode>(Op), DAG);
487 }
488 
489 SDValue LoongArchTargetLowering::lowerConstantPool(SDValue Op,
490  SelectionDAG &DAG) const {
491  return getAddr(cast<ConstantPoolSDNode>(Op), DAG);
492 }
493 
494 SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
495  SelectionDAG &DAG) const {
496  GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
497  assert(N->getOffset() == 0 && "unexpected offset in global node");
498  return getAddr(N, DAG, N->getGlobal()->isDSOLocal());
499 }
500 
501 SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
502  SelectionDAG &DAG,
503  unsigned Opc) const {
504  SDLoc DL(N);
505  EVT Ty = getPointerTy(DAG.getDataLayout());
506  MVT GRLenVT = Subtarget.getGRLenVT();
507 
508  SDValue Addr = DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, 0);
509  SDValue Offset = SDValue(DAG.getMachineNode(Opc, DL, Ty, Addr), 0);
510 
511  // Add the thread pointer.
512  return DAG.getNode(ISD::ADD, DL, Ty, Offset,
513  DAG.getRegister(LoongArch::R2, GRLenVT));
514 }
515 
516 SDValue LoongArchTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N,
517  SelectionDAG &DAG,
518  unsigned Opc) const {
519  SDLoc DL(N);
520  EVT Ty = getPointerTy(DAG.getDataLayout());
521  IntegerType *CallTy = Type::getIntNTy(*DAG.getContext(), Ty.getSizeInBits());
522 
523  // Use a PC-relative addressing mode to access the dynamic GOT address.
524  SDValue Addr = DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, 0);
525  SDValue Load = SDValue(DAG.getMachineNode(Opc, DL, Ty, Addr), 0);
526 
527  // Prepare argument list to generate call.
528  ArgListTy Args;
529  ArgListEntry Entry;
530  Entry.Node = Load;
531  Entry.Ty = CallTy;
532  Args.push_back(Entry);
533 
534  // Setup call to __tls_get_addr.
536  CLI.setDebugLoc(DL)
537  .setChain(DAG.getEntryNode())
538  .setLibCallee(CallingConv::C, CallTy,
539  DAG.getExternalSymbol("__tls_get_addr", Ty),
540  std::move(Args));
541 
542  return LowerCallTo(CLI).first;
543 }
544 
545 SDValue
546 LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
547  SelectionDAG &DAG) const {
548  GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
549  assert(N->getOffset() == 0 && "unexpected offset in global node");
550 
551  SDValue Addr;
553 
554  switch (Model) {
556  // In this model, application code calls the dynamic linker function
557  // __tls_get_addr to locate TLS offsets into the dynamic thread vector at
558  // runtime.
559  Addr = getDynamicTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_GD);
560  break;
562  // Same as GeneralDynamic, except for assembly modifiers and relocation
563  // records.
564  Addr = getDynamicTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LD);
565  break;
567  // This model uses the GOT to resolve TLS offsets.
568  Addr = getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_IE);
569  break;
570  case TLSModel::LocalExec:
571  // This model is used when static linking as the TLS offsets are resolved
572  // during program linking.
573  Addr = getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LE);
574  break;
575  }
576 
577  return Addr;
578 }
579 
580 SDValue
581 LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
582  SelectionDAG &DAG) const {
583  switch (Op.getConstantOperandVal(0)) {
584  default:
585  return SDValue(); // Don't custom lower most intrinsics.
586  case Intrinsic::thread_pointer: {
587  EVT PtrVT = getPointerTy(DAG.getDataLayout());
588  return DAG.getRegister(LoongArch::R2, PtrVT);
589  }
590  }
591 }
592 
593 SDValue
594 LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
595  SelectionDAG &DAG) const {
596 
597  switch (Op.getConstantOperandVal(1)) {
598  default:
599  return Op;
600  case Intrinsic::loongarch_crc_w_d_w: {
601  DAG.getContext()->emitError(
602  "llvm.loongarch.crc.w.d.w requires target: loongarch64");
603  return DAG.getMergeValues(
604  {DAG.getUNDEF(Op.getValueType()), Op.getOperand(0)}, SDLoc(Op));
605  }
606  }
607 }
608 
609 // Helper function that emits error message for intrinsics with void return
610 // value.
612  SelectionDAG &DAG) {
613 
614  DAG.getContext()->emitError("argument to '" + Op->getOperationName(0) + "' " +
615  ErrorMsg);
616  return Op.getOperand(0);
617 }
618 
619 SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op,
620  SelectionDAG &DAG) const {
621  SDLoc DL(Op);
622  MVT GRLenVT = Subtarget.getGRLenVT();
623  SDValue Op0 = Op.getOperand(0);
624  SDValue Op2 = Op.getOperand(2);
625  const StringRef ErrorMsgOOR = "out of range";
626 
627  switch (Op.getConstantOperandVal(1)) {
628  default:
629  // TODO: Add more Intrinsics.
630  return SDValue();
631  case Intrinsic::loongarch_dbar: {
632  unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
633  if (!isUInt<15>(Imm))
634  return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
635 
636  return DAG.getNode(LoongArchISD::DBAR, DL, MVT::Other, Op0,
637  DAG.getConstant(Imm, DL, GRLenVT));
638  }
639  case Intrinsic::loongarch_ibar: {
640  unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
641  if (!isUInt<15>(Imm))
642  return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
643 
644  return DAG.getNode(LoongArchISD::IBAR, DL, MVT::Other, Op0,
645  DAG.getConstant(Imm, DL, GRLenVT));
646  }
647  case Intrinsic::loongarch_break: {
648  unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
649  if (!isUInt<15>(Imm))
650  return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
651 
652  return DAG.getNode(LoongArchISD::BREAK, DL, MVT::Other, Op0,
653  DAG.getConstant(Imm, DL, GRLenVT));
654  }
655  case Intrinsic::loongarch_syscall: {
656  unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
657  if (!isUInt<15>(Imm))
658  return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG);
659 
660  return DAG.getNode(LoongArchISD::SYSCALL, DL, MVT::Other, Op0,
661  DAG.getConstant(Imm, DL, GRLenVT));
662  }
663  }
664 }
665 
666 SDValue LoongArchTargetLowering::lowerShiftLeftParts(SDValue Op,
667  SelectionDAG &DAG) const {
668  SDLoc DL(Op);
669  SDValue Lo = Op.getOperand(0);
670  SDValue Hi = Op.getOperand(1);
671  SDValue Shamt = Op.getOperand(2);
672  EVT VT = Lo.getValueType();
673 
674  // if Shamt-GRLen < 0: // Shamt < GRLen
675  // Lo = Lo << Shamt
676  // Hi = (Hi << Shamt) | ((Lo >>u 1) >>u (GRLen-1 ^ Shamt))
677  // else:
678  // Lo = 0
679  // Hi = Lo << (Shamt-GRLen)
680 
681  SDValue Zero = DAG.getConstant(0, DL, VT);
682  SDValue One = DAG.getConstant(1, DL, VT);
683  SDValue MinusGRLen = DAG.getConstant(-(int)Subtarget.getGRLen(), DL, VT);
684  SDValue GRLenMinus1 = DAG.getConstant(Subtarget.getGRLen() - 1, DL, VT);
685  SDValue ShamtMinusGRLen = DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusGRLen);
686  SDValue GRLenMinus1Shamt = DAG.getNode(ISD::XOR, DL, VT, Shamt, GRLenMinus1);
687 
688  SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
689  SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo, One);
690  SDValue ShiftRightLo =
691  DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, GRLenMinus1Shamt);
692  SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt);
693  SDValue HiTrue = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
694  SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusGRLen);
695 
696  SDValue CC = DAG.getSetCC(DL, VT, ShamtMinusGRLen, Zero, ISD::SETLT);
697 
698  Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, Zero);
699  Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse);
700 
701  SDValue Parts[2] = {Lo, Hi};
702  return DAG.getMergeValues(Parts, DL);
703 }
704 
705 SDValue LoongArchTargetLowering::lowerShiftRightParts(SDValue Op,
706  SelectionDAG &DAG,
707  bool IsSRA) const {
708  SDLoc DL(Op);
709  SDValue Lo = Op.getOperand(0);
710  SDValue Hi = Op.getOperand(1);
711  SDValue Shamt = Op.getOperand(2);
712  EVT VT = Lo.getValueType();
713 
714  // SRA expansion:
715  // if Shamt-GRLen < 0: // Shamt < GRLen
716  // Lo = (Lo >>u Shamt) | ((Hi << 1) << (ShAmt ^ GRLen-1))
717  // Hi = Hi >>s Shamt
718  // else:
719  // Lo = Hi >>s (Shamt-GRLen);
720  // Hi = Hi >>s (GRLen-1)
721  //
722  // SRL expansion:
723  // if Shamt-GRLen < 0: // Shamt < GRLen
724  // Lo = (Lo >>u Shamt) | ((Hi << 1) << (ShAmt ^ GRLen-1))
725  // Hi = Hi >>u Shamt
726  // else:
727  // Lo = Hi >>u (Shamt-GRLen);
728  // Hi = 0;
729 
730  unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;
731 
732  SDValue Zero = DAG.getConstant(0, DL, VT);
733  SDValue One = DAG.getConstant(1, DL, VT);
734  SDValue MinusGRLen = DAG.getConstant(-(int)Subtarget.getGRLen(), DL, VT);
735  SDValue GRLenMinus1 = DAG.getConstant(Subtarget.getGRLen() - 1, DL, VT);
736  SDValue ShamtMinusGRLen = DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusGRLen);
737  SDValue GRLenMinus1Shamt = DAG.getNode(ISD::XOR, DL, VT, Shamt, GRLenMinus1);
738 
739  SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt);
740  SDValue ShiftLeftHi1 = DAG.getNode(ISD::SHL, DL, VT, Hi, One);
741  SDValue ShiftLeftHi =
742  DAG.getNode(ISD::SHL, DL, VT, ShiftLeftHi1, GRLenMinus1Shamt);
743  SDValue LoTrue = DAG.getNode(ISD::OR, DL, VT, ShiftRightLo, ShiftLeftHi);
744  SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt);
745  SDValue LoFalse = DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusGRLen);
746  SDValue HiFalse =
747  IsSRA ? DAG.getNode(ISD::SRA, DL, VT, Hi, GRLenMinus1) : Zero;
748 
749  SDValue CC = DAG.getSetCC(DL, VT, ShamtMinusGRLen, Zero, ISD::SETLT);
750 
751  Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, LoFalse);
752  Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse);
753 
754  SDValue Parts[2] = {Lo, Hi};
755  return DAG.getMergeValues(Parts, DL);
756 }
757 
758 // Returns the opcode of the target-specific SDNode that implements the 32-bit
759 // form of the given Opcode.
761  switch (Opcode) {
762  default:
763  llvm_unreachable("Unexpected opcode");
764  case ISD::SHL:
765  return LoongArchISD::SLL_W;
766  case ISD::SRA:
767  return LoongArchISD::SRA_W;
768  case ISD::SRL:
769  return LoongArchISD::SRL_W;
770  case ISD::ROTR:
771  return LoongArchISD::ROTR_W;
772  case ISD::ROTL:
773  return LoongArchISD::ROTL_W;
774  case ISD::CTTZ:
775  return LoongArchISD::CTZ_W;
776  case ISD::CTLZ:
777  return LoongArchISD::CLZ_W;
778  }
779 }
780 
781 // Converts the given i8/i16/i32 operation to a target-specific SelectionDAG
782 // node. Because i8/i16/i32 isn't a legal type for LA64, these operations would
783 // otherwise be promoted to i64, making it difficult to select the
784 // SLL_W/.../*W later one because the fact the operation was originally of
785 // type i8/i16/i32 is lost.
787  unsigned ExtOpc = ISD::ANY_EXTEND) {
788  SDLoc DL(N);
789  LoongArchISD::NodeType WOpcode = getLoongArchWOpcode(N->getOpcode());
790  SDValue NewOp0, NewRes;
791 
792  switch (NumOp) {
793  default:
794  llvm_unreachable("Unexpected NumOp");
795  case 1: {
796  NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0));
797  NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0);
798  break;
799  }
800  case 2: {
801  NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0));
802  SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1));
803  NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1);
804  break;
805  }
806  // TODO:Handle more NumOp.
807  }
808 
809  // ReplaceNodeResults requires we maintain the same type for the return
810  // value.
811  return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewRes);
812 }
813 
816  SDLoc DL(N);
817  switch (N->getOpcode()) {
818  default:
819  llvm_unreachable("Don't know how to legalize this operation");
820  case ISD::SHL:
821  case ISD::SRA:
822  case ISD::SRL:
823  case ISD::ROTR:
824  assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
825  "Unexpected custom legalisation");
826  if (N->getOperand(1).getOpcode() != ISD::Constant) {
827  Results.push_back(customLegalizeToWOp(N, DAG, 2));
828  break;
829  }
830  break;
831  case ISD::ROTL:
832  ConstantSDNode *CN;
833  if ((CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))) {
834  Results.push_back(customLegalizeToWOp(N, DAG, 2));
835  break;
836  }
837  break;
838  case ISD::FP_TO_SINT: {
839  assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
840  "Unexpected custom legalisation");
841  SDValue Src = N->getOperand(0);
842  EVT VT = EVT::getFloatingPointVT(N->getValueSizeInBits(0));
843  if (getTypeAction(*DAG.getContext(), Src.getValueType()) !=
845  SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, VT, Src);
846  Results.push_back(DAG.getNode(ISD::BITCAST, DL, N->getValueType(0), Dst));
847  return;
848  }
849  // If the FP type needs to be softened, emit a library call using the 'si'
850  // version. If we left it to default legalization we'd end up with 'di'.
851  RTLIB::Libcall LC;
852  LC = RTLIB::getFPTOSINT(Src.getValueType(), N->getValueType(0));
853  MakeLibCallOptions CallOptions;
854  EVT OpVT = Src.getValueType();
855  CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true);
856  SDValue Chain = SDValue();
857  SDValue Result;
858  std::tie(Result, Chain) =
859  makeLibCall(DAG, LC, N->getValueType(0), Src, CallOptions, DL, Chain);
860  Results.push_back(Result);
861  break;
862  }
863  case ISD::BITCAST: {
864  EVT VT = N->getValueType(0);
865  SDValue Src = N->getOperand(0);
866  EVT SrcVT = Src.getValueType();
867  if (VT == MVT::i32 && SrcVT == MVT::f32 && Subtarget.is64Bit() &&
868  Subtarget.hasBasicF()) {
869  SDValue Dst =
871  Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Dst));
872  }
873  break;
874  }
875  case ISD::FP_TO_UINT: {
876  assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
877  "Unexpected custom legalisation");
878  auto &TLI = DAG.getTargetLoweringInfo();
879  SDValue Tmp1, Tmp2;
880  TLI.expandFP_TO_UINT(N, Tmp1, Tmp2, DAG);
881  Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Tmp1));
882  break;
883  }
884  case ISD::BSWAP: {
885  SDValue Src = N->getOperand(0);
886  EVT VT = N->getValueType(0);
887  assert((VT == MVT::i16 || VT == MVT::i32) &&
888  "Unexpected custom legalization");
889  MVT GRLenVT = Subtarget.getGRLenVT();
890  SDValue NewSrc = DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT, Src);
891  SDValue Tmp;
892  switch (VT.getSizeInBits()) {
893  default:
894  llvm_unreachable("Unexpected operand width");
895  case 16:
896  Tmp = DAG.getNode(LoongArchISD::REVB_2H, DL, GRLenVT, NewSrc);
897  break;
898  case 32:
899  // Only LA64 will get to here due to the size mismatch between VT and
900  // GRLenVT, LA32 lowering is directly defined in LoongArchInstrInfo.
901  Tmp = DAG.getNode(LoongArchISD::REVB_2W, DL, GRLenVT, NewSrc);
902  break;
903  }
904  Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, Tmp));
905  break;
906  }
907  case ISD::BITREVERSE: {
908  SDValue Src = N->getOperand(0);
909  EVT VT = N->getValueType(0);
910  assert((VT == MVT::i8 || (VT == MVT::i32 && Subtarget.is64Bit())) &&
911  "Unexpected custom legalization");
912  MVT GRLenVT = Subtarget.getGRLenVT();
913  SDValue NewSrc = DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT, Src);
914  SDValue Tmp;
915  switch (VT.getSizeInBits()) {
916  default:
917  llvm_unreachable("Unexpected operand width");
918  case 8:
919  Tmp = DAG.getNode(LoongArchISD::BITREV_4B, DL, GRLenVT, NewSrc);
920  break;
921  case 32:
922  Tmp = DAG.getNode(LoongArchISD::BITREV_W, DL, GRLenVT, NewSrc);
923  break;
924  }
925  Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, Tmp));
926  break;
927  }
928  case ISD::CTLZ:
929  case ISD::CTTZ: {
930  assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
931  "Unexpected custom legalisation");
932  Results.push_back(customLegalizeToWOp(N, DAG, 1));
933  break;
934  }
935  case ISD::INTRINSIC_W_CHAIN: {
936  assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
937  "Unexpected custom legalisation");
938 
939  switch (N->getConstantOperandVal(1)) {
940  default:
941  llvm_unreachable("Unexpected Intrinsic.");
942  case Intrinsic::loongarch_crc_w_d_w: {
943  Results.push_back(DAG.getNode(
944  ISD::TRUNCATE, DL, N->getValueType(0),
945  DAG.getNode(
946  LoongArchISD::CRC_W_D_W, DL, MVT::i64, N->getOperand(2),
947  DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3)))));
948  Results.push_back(N->getOperand(0));
949  break;
950  }
951  }
952  break;
953  }
954  case ISD::READ_REGISTER: {
955  if (Subtarget.is64Bit())
956  DAG.getContext()->emitError(
957  "On LA64, only 64-bit registers can be read.");
958  else
959  DAG.getContext()->emitError(
960  "On LA32, only 32-bit registers can be read.");
961  Results.push_back(DAG.getUNDEF(N->getValueType(0)));
962  Results.push_back(N->getOperand(0));
963  break;
964  }
965  }
966 }
967 
970  const LoongArchSubtarget &Subtarget) {
971  if (DCI.isBeforeLegalizeOps())
972  return SDValue();
973 
974  SDValue FirstOperand = N->getOperand(0);
975  SDValue SecondOperand = N->getOperand(1);
976  unsigned FirstOperandOpc = FirstOperand.getOpcode();
977  EVT ValTy = N->getValueType(0);
978  SDLoc DL(N);
979  uint64_t lsb, msb;
980  unsigned SMIdx, SMLen;
981  ConstantSDNode *CN;
982  SDValue NewOperand;
983  MVT GRLenVT = Subtarget.getGRLenVT();
984 
985  // Op's second operand must be a shifted mask.
986  if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand)) ||
987  !isShiftedMask_64(CN->getZExtValue(), SMIdx, SMLen))
988  return SDValue();
989 
990  if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL) {
991  // Pattern match BSTRPICK.
992  // $dst = and ((sra or srl) $src , lsb), (2**len - 1)
993  // => BSTRPICK $dst, $src, msb, lsb
994  // where msb = lsb + len - 1
995 
996  // The second operand of the shift must be an immediate.
997  if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))))
998  return SDValue();
999 
1000  lsb = CN->getZExtValue();
1001 
1002  // Return if the shifted mask does not start at bit 0 or the sum of its
1003  // length and lsb exceeds the word's size.
1004  if (SMIdx != 0 || lsb + SMLen > ValTy.getSizeInBits())
1005  return SDValue();
1006 
1007  NewOperand = FirstOperand.getOperand(0);
1008  } else {
1009  // Pattern match BSTRPICK.
1010  // $dst = and $src, (2**len- 1) , if len > 12
1011  // => BSTRPICK $dst, $src, msb, lsb
1012  // where lsb = 0 and msb = len - 1
1013 
1014  // If the mask is <= 0xfff, andi can be used instead.
1015  if (CN->getZExtValue() <= 0xfff)
1016  return SDValue();
1017 
1018  // Return if the mask doesn't start at position 0.
1019  if (SMIdx)
1020  return SDValue();
1021 
1022  lsb = 0;
1023  NewOperand = FirstOperand;
1024  }
1025  msb = lsb + SMLen - 1;
1026  return DAG.getNode(LoongArchISD::BSTRPICK, DL, ValTy, NewOperand,
1027  DAG.getConstant(msb, DL, GRLenVT),
1028  DAG.getConstant(lsb, DL, GRLenVT));
1029 }
1030 
1033  const LoongArchSubtarget &Subtarget) {
1034  if (DCI.isBeforeLegalizeOps())
1035  return SDValue();
1036 
1037  // $dst = srl (and $src, Mask), Shamt
1038  // =>
1039  // BSTRPICK $dst, $src, MaskIdx+MaskLen-1, Shamt
1040  // when Mask is a shifted mask, and MaskIdx <= Shamt <= MaskIdx+MaskLen-1
1041  //
1042 
1043  SDValue FirstOperand = N->getOperand(0);
1044  ConstantSDNode *CN;
1045  EVT ValTy = N->getValueType(0);
1046  SDLoc DL(N);
1047  MVT GRLenVT = Subtarget.getGRLenVT();
1048  unsigned MaskIdx, MaskLen;
1049  uint64_t Shamt;
1050 
1051  // The first operand must be an AND and the second operand of the AND must be
1052  // a shifted mask.
1053  if (FirstOperand.getOpcode() != ISD::AND ||
1054  !(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))) ||
1055  !isShiftedMask_64(CN->getZExtValue(), MaskIdx, MaskLen))
1056  return SDValue();
1057 
1058  // The second operand (shift amount) must be an immediate.
1059  if (!(CN = dyn_cast<ConstantSDNode>(N->getOperand(1))))
1060  return SDValue();
1061 
1062  Shamt = CN->getZExtValue();
1063  if (MaskIdx <= Shamt && Shamt <= MaskIdx + MaskLen - 1)
1064  return DAG.getNode(LoongArchISD::BSTRPICK, DL, ValTy,
1065  FirstOperand->getOperand(0),
1066  DAG.getConstant(MaskIdx + MaskLen - 1, DL, GRLenVT),
1067  DAG.getConstant(Shamt, DL, GRLenVT));
1068 
1069  return SDValue();
1070 }
1071 
1074  const LoongArchSubtarget &Subtarget) {
1075  MVT GRLenVT = Subtarget.getGRLenVT();
1076  EVT ValTy = N->getValueType(0);
1077  SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
1078  ConstantSDNode *CN0, *CN1;
1079  SDLoc DL(N);
1080  unsigned ValBits = ValTy.getSizeInBits();
1081  unsigned MaskIdx0, MaskLen0, MaskIdx1, MaskLen1;
1082  unsigned Shamt;
1083  bool SwapAndRetried = false;
1084 
1085  if (DCI.isBeforeLegalizeOps())
1086  return SDValue();
1087 
1088  if (ValBits != 32 && ValBits != 64)
1089  return SDValue();
1090 
1091 Retry:
1092  // 1st pattern to match BSTRINS:
1093  // R = or (and X, mask0), (and (shl Y, lsb), mask1)
1094  // where mask1 = (2**size - 1) << lsb, mask0 = ~mask1
1095  // =>
1096  // R = BSTRINS X, Y, msb, lsb (where msb = lsb + size - 1)
1097  if (N0.getOpcode() == ISD::AND &&
1098  (CN0 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) &&
1099  isShiftedMask_64(~CN0->getSExtValue(), MaskIdx0, MaskLen0) &&
1100  N1.getOpcode() == ISD::AND && N1.getOperand(0).getOpcode() == ISD::SHL &&
1101  (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
1102  isShiftedMask_64(CN1->getZExtValue(), MaskIdx1, MaskLen1) &&
1103  MaskIdx0 == MaskIdx1 && MaskLen0 == MaskLen1 &&
1104  (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
1105  (Shamt = CN1->getZExtValue()) == MaskIdx0 &&
1106  (MaskIdx0 + MaskLen0 <= ValBits)) {
1107  LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 1\n");
1108  return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0),
1109  N1.getOperand(0).getOperand(0),
1110  DAG.getConstant((MaskIdx0 + MaskLen0 - 1), DL, GRLenVT),
1111  DAG.getConstant(MaskIdx0, DL, GRLenVT));
1112  }
1113 
1114  // 2nd pattern to match BSTRINS:
1115  // R = or (and X, mask0), (shl (and Y, mask1), lsb)
1116  // where mask1 = (2**size - 1), mask0 = ~(mask1 << lsb)
1117  // =>
1118  // R = BSTRINS X, Y, msb, lsb (where msb = lsb + size - 1)
1119  if (N0.getOpcode() == ISD::AND &&
1120  (CN0 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) &&
1121  isShiftedMask_64(~CN0->getSExtValue(), MaskIdx0, MaskLen0) &&
1122  N1.getOpcode() == ISD::SHL && N1.getOperand(0).getOpcode() == ISD::AND &&
1123  (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
1124  (Shamt = CN1->getZExtValue()) == MaskIdx0 &&
1125  (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
1126  isShiftedMask_64(CN1->getZExtValue(), MaskIdx1, MaskLen1) &&
1127  MaskLen0 == MaskLen1 && MaskIdx1 == 0 &&
1128  (MaskIdx0 + MaskLen0 <= ValBits)) {
1129  LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 2\n");
1130  return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0),
1131  N1.getOperand(0).getOperand(0),
1132  DAG.getConstant((MaskIdx0 + MaskLen0 - 1), DL, GRLenVT),
1133  DAG.getConstant(MaskIdx0, DL, GRLenVT));
1134  }
1135 
1136  // 3rd pattern to match BSTRINS:
1137  // R = or (and X, mask0), (and Y, mask1)
1138  // where ~mask0 = (2**size - 1) << lsb, mask0 & mask1 = 0
1139  // =>
1140  // R = BSTRINS X, (shr (and Y, mask1), lsb), msb, lsb
1141  // where msb = lsb + size - 1
1142  if (N0.getOpcode() == ISD::AND && N1.getOpcode() == ISD::AND &&
1143  (CN0 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) &&
1144  isShiftedMask_64(~CN0->getSExtValue(), MaskIdx0, MaskLen0) &&
1145  (MaskIdx0 + MaskLen0 <= 64) &&
1146  (CN1 = dyn_cast<ConstantSDNode>(N1->getOperand(1))) &&
1147  (CN1->getSExtValue() & CN0->getSExtValue()) == 0) {
1148  LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 3\n");
1149  return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0),
1150  DAG.getNode(ISD::SRL, DL, N1->getValueType(0), N1,
1151  DAG.getConstant(MaskIdx0, DL, GRLenVT)),
1152  DAG.getConstant(ValBits == 32
1153  ? (MaskIdx0 + (MaskLen0 & 31) - 1)
1154  : (MaskIdx0 + MaskLen0 - 1),
1155  DL, GRLenVT),
1156  DAG.getConstant(MaskIdx0, DL, GRLenVT));
1157  }
1158 
1159  // 4th pattern to match BSTRINS:
1160  // R = or (and X, mask), (shl Y, shamt)
1161  // where mask = (2**shamt - 1)
1162  // =>
1163  // R = BSTRINS X, Y, ValBits - 1, shamt
1164  // where ValBits = 32 or 64
1165  if (N0.getOpcode() == ISD::AND && N1.getOpcode() == ISD::SHL &&
1166  (CN0 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) &&
1167  isShiftedMask_64(CN0->getZExtValue(), MaskIdx0, MaskLen0) &&
1168  MaskIdx0 == 0 && (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
1169  (Shamt = CN1->getZExtValue()) == MaskLen0 &&
1170  (MaskIdx0 + MaskLen0 <= ValBits)) {
1171  LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 4\n");
1172  return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0),
1173  N1.getOperand(0),
1174  DAG.getConstant((ValBits - 1), DL, GRLenVT),
1175  DAG.getConstant(Shamt, DL, GRLenVT));
1176  }
1177 
1178  // 5th pattern to match BSTRINS:
1179  // R = or (and X, mask), const
1180  // where ~mask = (2**size - 1) << lsb, mask & const = 0
1181  // =>
1182  // R = BSTRINS X, (const >> lsb), msb, lsb
1183  // where msb = lsb + size - 1
1184  if (N0.getOpcode() == ISD::AND &&
1185  (CN0 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) &&
1186  isShiftedMask_64(~CN0->getSExtValue(), MaskIdx0, MaskLen0) &&
1187  (CN1 = dyn_cast<ConstantSDNode>(N1)) &&
1188  (CN1->getSExtValue() & CN0->getSExtValue()) == 0) {
1189  LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 5\n");
1190  return DAG.getNode(
1191  LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0),
1192  DAG.getConstant(CN1->getSExtValue() >> MaskIdx0, DL, ValTy),
1193  DAG.getConstant((MaskIdx0 + MaskLen0 - 1), DL, GRLenVT),
1194  DAG.getConstant(MaskIdx0, DL, GRLenVT));
1195  }
1196 
1197  // 6th pattern.
1198  // a = b | ((c & mask) << shamt), where all positions in b to be overwritten
1199  // by the incoming bits are known to be zero.
1200  // =>
1201  // a = BSTRINS b, c, shamt + MaskLen - 1, shamt
1202  //
1203  // Note that the 1st pattern is a special situation of the 6th, i.e. the 6th
1204  // pattern is more common than the 1st. So we put the 1st before the 6th in
1205  // order to match as many nodes as possible.
1206  ConstantSDNode *CNMask, *CNShamt;
1207  unsigned MaskIdx, MaskLen;
1208  if (N1.getOpcode() == ISD::SHL && N1.getOperand(0).getOpcode() == ISD::AND &&
1209  (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
1210  isShiftedMask_64(CNMask->getZExtValue(), MaskIdx, MaskLen) &&
1211  MaskIdx == 0 && (CNShamt = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
1212  CNShamt->getZExtValue() + MaskLen <= ValBits) {
1213  Shamt = CNShamt->getZExtValue();
1214  APInt ShMask(ValBits, CNMask->getZExtValue() << Shamt);
1215  if (ShMask.isSubsetOf(DAG.computeKnownBits(N0).Zero)) {
1216  LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 6\n");
1217  return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0,
1218  N1.getOperand(0).getOperand(0),
1219  DAG.getConstant(Shamt + MaskLen - 1, DL, GRLenVT),
1220  DAG.getConstant(Shamt, DL, GRLenVT));
1221  }
1222  }
1223 
1224  // 7th pattern.
1225  // a = b | ((c << shamt) & shifted_mask), where all positions in b to be
1226  // overwritten by the incoming bits are known to be zero.
1227  // =>
1228  // a = BSTRINS b, c, MaskIdx + MaskLen - 1, MaskIdx
1229  //
1230  // Similarly, the 7th pattern is more common than the 2nd. So we put the 2nd
1231  // before the 7th in order to match as many nodes as possible.
1232  if (N1.getOpcode() == ISD::AND &&
1233  (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
1234  isShiftedMask_64(CNMask->getZExtValue(), MaskIdx, MaskLen) &&
1235  N1.getOperand(0).getOpcode() == ISD::SHL &&
1236  (CNShamt = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
1237  CNShamt->getZExtValue() == MaskIdx) {
1238  APInt ShMask(ValBits, CNMask->getZExtValue());
1239  if (ShMask.isSubsetOf(DAG.computeKnownBits(N0).Zero)) {
1240  LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 7\n");
1241  return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0,
1242  N1.getOperand(0).getOperand(0),
1243  DAG.getConstant(MaskIdx + MaskLen - 1, DL, GRLenVT),
1244  DAG.getConstant(MaskIdx, DL, GRLenVT));
1245  }
1246  }
1247 
1248  // (or a, b) and (or b, a) are equivalent, so swap the operands and retry.
1249  if (!SwapAndRetried) {
1250  std::swap(N0, N1);
1251  SwapAndRetried = true;
1252  goto Retry;
1253  }
1254 
1255  SwapAndRetried = false;
1256 Retry2:
1257  // 8th pattern.
1258  // a = b | (c & shifted_mask), where all positions in b to be overwritten by
1259  // the incoming bits are known to be zero.
1260  // =>
1261  // a = BSTRINS b, c >> MaskIdx, MaskIdx + MaskLen - 1, MaskIdx
1262  //
1263  // Similarly, the 8th pattern is more common than the 4th and 5th patterns. So
1264  // we put it here in order to match as many nodes as possible or generate less
1265  // instructions.
1266  if (N1.getOpcode() == ISD::AND &&
1267  (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
1268  isShiftedMask_64(CNMask->getZExtValue(), MaskIdx, MaskLen)) {
1269  APInt ShMask(ValBits, CNMask->getZExtValue());
1270  if (ShMask.isSubsetOf(DAG.computeKnownBits(N0).Zero)) {
1271  LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 8\n");
1272  return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0,
1273  DAG.getNode(ISD::SRL, DL, N1->getValueType(0),
1274  N1->getOperand(0),
1275  DAG.getConstant(MaskIdx, DL, GRLenVT)),
1276  DAG.getConstant(MaskIdx + MaskLen - 1, DL, GRLenVT),
1277  DAG.getConstant(MaskIdx, DL, GRLenVT));
1278  }
1279  }
1280  // Swap N0/N1 and retry.
1281  if (!SwapAndRetried) {
1282  std::swap(N0, N1);
1283  SwapAndRetried = true;
1284  goto Retry2;
1285  }
1286 
1287  return SDValue();
1288 }
1289 
1290 // Combine (loongarch_bitrev_w (loongarch_revb_2w X)) to loongarch_bitrev_4b.
1293  const LoongArchSubtarget &Subtarget) {
1294  if (DCI.isBeforeLegalizeOps())
1295  return SDValue();
1296 
1297  SDValue Src = N->getOperand(0);
1298  if (Src.getOpcode() != LoongArchISD::REVB_2W)
1299  return SDValue();
1300 
1301  return DAG.getNode(LoongArchISD::BITREV_4B, SDLoc(N), N->getValueType(0),
1302  Src.getOperand(0));
1303 }
1304 
1306  DAGCombinerInfo &DCI) const {
1307  SelectionDAG &DAG = DCI.DAG;
1308  switch (N->getOpcode()) {
1309  default:
1310  break;
1311  case ISD::AND:
1312  return performANDCombine(N, DAG, DCI, Subtarget);
1313  case ISD::OR:
1314  return performORCombine(N, DAG, DCI, Subtarget);
1315  case ISD::SRL:
1316  return performSRLCombine(N, DAG, DCI, Subtarget);
1318  return performBITREV_WCombine(N, DAG, DCI, Subtarget);
1319  }
1320  return SDValue();
1321 }
1322 
1325  if (!ZeroDivCheck)
1326  return MBB;
1327 
1328  // Build instructions:
1329  // MBB:
1330  // div(or mod) $dst, $dividend, $divisor
1331  // bnez $divisor, SinkMBB
1332  // BreakMBB:
1333  // break 7 // BRK_DIVZERO
1334  // SinkMBB:
1335  // fallthrough
1336  const BasicBlock *LLVM_BB = MBB->getBasicBlock();
1338  MachineFunction *MF = MBB->getParent();
1339  auto BreakMBB = MF->CreateMachineBasicBlock(LLVM_BB);
1340  auto SinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
1341  MF->insert(It, BreakMBB);
1342  MF->insert(It, SinkMBB);
1343 
1344  // Transfer the remainder of MBB and its successor edges to SinkMBB.
1345  SinkMBB->splice(SinkMBB->end(), MBB, std::next(MI.getIterator()), MBB->end());
1346  SinkMBB->transferSuccessorsAndUpdatePHIs(MBB);
1347 
1348  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
1349  DebugLoc DL = MI.getDebugLoc();
1350  MachineOperand &Divisor = MI.getOperand(2);
1351  Register DivisorReg = Divisor.getReg();
1352 
1353  // MBB:
1354  BuildMI(MBB, DL, TII.get(LoongArch::BNEZ))
1355  .addReg(DivisorReg, getKillRegState(Divisor.isKill()))
1356  .addMBB(SinkMBB);
1357  MBB->addSuccessor(BreakMBB);
1358  MBB->addSuccessor(SinkMBB);
1359 
1360  // BreakMBB:
1361  // See linux header file arch/loongarch/include/uapi/asm/break.h for the
1362  // definition of BRK_DIVZERO.
1363  BuildMI(BreakMBB, DL, TII.get(LoongArch::BREAK)).addImm(7 /*BRK_DIVZERO*/);
1364  BreakMBB->addSuccessor(SinkMBB);
1365 
1366  // Clear Divisor's kill flag.
1367  Divisor.setIsKill(false);
1368 
1369  return SinkMBB;
1370 }
1371 
1372 MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter(
1373  MachineInstr &MI, MachineBasicBlock *BB) const {
1374 
1375  switch (MI.getOpcode()) {
1376  default:
1377  llvm_unreachable("Unexpected instr type to insert");
1378  case LoongArch::DIV_W:
1379  case LoongArch::DIV_WU:
1380  case LoongArch::MOD_W:
1381  case LoongArch::MOD_WU:
1382  case LoongArch::DIV_D:
1383  case LoongArch::DIV_DU:
1384  case LoongArch::MOD_D:
1385  case LoongArch::MOD_DU:
1386  return insertDivByZeroTrap(MI, BB);
1387  break;
1388  }
1389 }
1390 
1391 const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
1392  switch ((LoongArchISD::NodeType)Opcode) {
1394  break;
1395 
1396 #define NODE_NAME_CASE(node) \
1397  case LoongArchISD::node: \
1398  return "LoongArchISD::" #node;
1399 
1400  // TODO: Add more target-dependent nodes later.
1425  }
1426 #undef NODE_NAME_CASE
1427  return nullptr;
1428 }
1429 
1430 //===----------------------------------------------------------------------===//
1431 // Calling Convention Implementation
1432 //===----------------------------------------------------------------------===//
1433 
1434 // Eight general-purpose registers a0-a7 used for passing integer arguments,
1435 // with a0-a1 reused to return values. Generally, the GPRs are used to pass
1436 // fixed-point arguments, and floating-point arguments when no FPR is available
1437 // or with soft float ABI.
1438 const MCPhysReg ArgGPRs[] = {LoongArch::R4, LoongArch::R5, LoongArch::R6,
1439  LoongArch::R7, LoongArch::R8, LoongArch::R9,
1440  LoongArch::R10, LoongArch::R11};
1441 // Eight floating-point registers fa0-fa7 used for passing floating-point
1442 // arguments, and fa0-fa1 are also used to return values.
1443 const MCPhysReg ArgFPR32s[] = {LoongArch::F0, LoongArch::F1, LoongArch::F2,
1444  LoongArch::F3, LoongArch::F4, LoongArch::F5,
1445  LoongArch::F6, LoongArch::F7};
1446 // FPR32 and FPR64 alias each other.
1448  LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, LoongArch::F3_64,
1449  LoongArch::F4_64, LoongArch::F5_64, LoongArch::F6_64, LoongArch::F7_64};
1450 
1451 // Pass a 2*GRLen argument that has been split into two GRLen values through
1452 // registers or the stack as necessary.
1453 static bool CC_LoongArchAssign2GRLen(unsigned GRLen, CCState &State,
1454  CCValAssign VA1, ISD::ArgFlagsTy ArgFlags1,
1455  unsigned ValNo2, MVT ValVT2, MVT LocVT2,
1456  ISD::ArgFlagsTy ArgFlags2) {
1457  unsigned GRLenInBytes = GRLen / 8;
1458  if (Register Reg = State.AllocateReg(ArgGPRs)) {
1459  // At least one half can be passed via register.
1460  State.addLoc(CCValAssign::getReg(VA1.getValNo(), VA1.getValVT(), Reg,
1461  VA1.getLocVT(), CCValAssign::Full));
1462  } else {
1463  // Both halves must be passed on the stack, with proper alignment.
1464  Align StackAlign =
1465  std::max(Align(GRLenInBytes), ArgFlags1.getNonZeroOrigAlign());
1466  State.addLoc(
1467  CCValAssign::getMem(VA1.getValNo(), VA1.getValVT(),
1468  State.AllocateStack(GRLenInBytes, StackAlign),
1469  VA1.getLocVT(), CCValAssign::Full));
1471  ValNo2, ValVT2, State.AllocateStack(GRLenInBytes, Align(GRLenInBytes)),
1472  LocVT2, CCValAssign::Full));
1473  return false;
1474  }
1475  if (Register Reg = State.AllocateReg(ArgGPRs)) {
1476  // The second half can also be passed via register.
1477  State.addLoc(
1478  CCValAssign::getReg(ValNo2, ValVT2, Reg, LocVT2, CCValAssign::Full));
1479  } else {
1480  // The second half is passed via the stack, without additional alignment.
1482  ValNo2, ValVT2, State.AllocateStack(GRLenInBytes, Align(GRLenInBytes)),
1483  LocVT2, CCValAssign::Full));
1484  }
1485  return false;
1486 }
1487 
1488 // Implements the LoongArch calling convention. Returns true upon failure.
1490  unsigned ValNo, MVT ValVT,
1491  CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
1492  CCState &State, bool IsFixed, bool IsRet,
1493  Type *OrigTy) {
1494  unsigned GRLen = DL.getLargestLegalIntTypeSizeInBits();
1495  assert((GRLen == 32 || GRLen == 64) && "Unspport GRLen");
1496  MVT GRLenVT = GRLen == 32 ? MVT::i32 : MVT::i64;
1497  MVT LocVT = ValVT;
1498 
1499  // Any return value split into more than two values can't be returned
1500  // directly.
1501  if (IsRet && ValNo > 1)
1502  return true;
1503 
1504  // If passing a variadic argument, or if no FPR is available.
1505  bool UseGPRForFloat = true;
1506 
1507  switch (ABI) {
1508  default:
1509  llvm_unreachable("Unexpected ABI");
1514  report_fatal_error("Unimplemented ABI");
1515  break;
1518  UseGPRForFloat = !IsFixed;
1519  break;
1520  }
1521 
1522  // FPR32 and FPR64 alias each other.
1524  UseGPRForFloat = true;
1525 
1526  if (UseGPRForFloat && ValVT == MVT::f32) {
1527  LocVT = GRLenVT;
1528  LocInfo = CCValAssign::BCvt;
1529  } else if (UseGPRForFloat && GRLen == 64 && ValVT == MVT::f64) {
1530  LocVT = MVT::i64;
1531  LocInfo = CCValAssign::BCvt;
1532  } else if (UseGPRForFloat && GRLen == 32 && ValVT == MVT::f64) {
1533  // TODO: Handle passing f64 on LA32 with D feature.
1534  report_fatal_error("Passing f64 with GPR on LA32 is undefined");
1535  }
1536 
1537  // If this is a variadic argument, the LoongArch calling convention requires
1538  // that it is assigned an 'even' or 'aligned' register if it has (2*GRLen)/8
1539  // byte alignment. An aligned register should be used regardless of whether
1540  // the original argument was split during legalisation or not. The argument
1541  // will not be passed by registers if the original type is larger than
1542  // 2*GRLen, so the register alignment rule does not apply.
1543  unsigned TwoGRLenInBytes = (2 * GRLen) / 8;
1544  if (!IsFixed && ArgFlags.getNonZeroOrigAlign() == TwoGRLenInBytes &&
1545  DL.getTypeAllocSize(OrigTy) == TwoGRLenInBytes) {
1546  unsigned RegIdx = State.getFirstUnallocated(ArgGPRs);
1547  // Skip 'odd' register if necessary.
1548  if (RegIdx != std::size(ArgGPRs) && RegIdx % 2 == 1)
1549  State.AllocateReg(ArgGPRs);
1550  }
1551 
1552  SmallVectorImpl<CCValAssign> &PendingLocs = State.getPendingLocs();
1553  SmallVectorImpl<ISD::ArgFlagsTy> &PendingArgFlags =
1554  State.getPendingArgFlags();
1555 
1556  assert(PendingLocs.size() == PendingArgFlags.size() &&
1557  "PendingLocs and PendingArgFlags out of sync");
1558 
1559  // Split arguments might be passed indirectly, so keep track of the pending
1560  // values.
1561  if (ValVT.isScalarInteger() && (ArgFlags.isSplit() || !PendingLocs.empty())) {
1562  LocVT = GRLenVT;
1563  LocInfo = CCValAssign::Indirect;
1564  PendingLocs.push_back(
1565  CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
1566  PendingArgFlags.push_back(ArgFlags);
1567  if (!ArgFlags.isSplitEnd()) {
1568  return false;
1569  }
1570  }
1571 
1572  // If the split argument only had two elements, it should be passed directly
1573  // in registers or on the stack.
1574  if (ValVT.isScalarInteger() && ArgFlags.isSplitEnd() &&
1575  PendingLocs.size() <= 2) {
1576  assert(PendingLocs.size() == 2 && "Unexpected PendingLocs.size()");
1577  // Apply the normal calling convention rules to the first half of the
1578  // split argument.
1579  CCValAssign VA = PendingLocs[0];
1580  ISD::ArgFlagsTy AF = PendingArgFlags[0];
1581  PendingLocs.clear();
1582  PendingArgFlags.clear();
1583  return CC_LoongArchAssign2GRLen(GRLen, State, VA, AF, ValNo, ValVT, LocVT,
1584  ArgFlags);
1585  }
1586 
1587  // Allocate to a register if possible, or else a stack slot.
1588  Register Reg;
1589  unsigned StoreSizeBytes = GRLen / 8;
1590  Align StackAlign = Align(GRLen / 8);
1591 
1592  if (ValVT == MVT::f32 && !UseGPRForFloat)
1593  Reg = State.AllocateReg(ArgFPR32s);
1594  else if (ValVT == MVT::f64 && !UseGPRForFloat)
1595  Reg = State.AllocateReg(ArgFPR64s);
1596  else
1597  Reg = State.AllocateReg(ArgGPRs);
1598 
1599  unsigned StackOffset =
1600  Reg ? 0 : State.AllocateStack(StoreSizeBytes, StackAlign);
1601 
1602  // If we reach this point and PendingLocs is non-empty, we must be at the
1603  // end of a split argument that must be passed indirectly.
1604  if (!PendingLocs.empty()) {
1605  assert(ArgFlags.isSplitEnd() && "Expected ArgFlags.isSplitEnd()");
1606  assert(PendingLocs.size() > 2 && "Unexpected PendingLocs.size()");
1607  for (auto &It : PendingLocs) {
1608  if (Reg)
1609  It.convertToReg(Reg);
1610  else
1611  It.convertToMem(StackOffset);
1612  State.addLoc(It);
1613  }
1614  PendingLocs.clear();
1615  PendingArgFlags.clear();
1616  return false;
1617  }
1618  assert((!UseGPRForFloat || LocVT == GRLenVT) &&
1619  "Expected an GRLenVT at this stage");
1620 
1621  if (Reg) {
1622  State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
1623  return false;
1624  }
1625 
1626  // When a floating-point value is passed on the stack, no bit-cast is needed.
1627  if (ValVT.isFloatingPoint()) {
1628  LocVT = ValVT;
1629  LocInfo = CCValAssign::Full;
1630  }
1631 
1632  State.addLoc(CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
1633  return false;
1634 }
1635 
1636 void LoongArchTargetLowering::analyzeInputArgs(
1637  MachineFunction &MF, CCState &CCInfo,
1638  const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,
1639  LoongArchCCAssignFn Fn) const {
1640  FunctionType *FType = MF.getFunction().getFunctionType();
1641  for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
1642  MVT ArgVT = Ins[i].VT;
1643  Type *ArgTy = nullptr;
1644  if (IsRet)
1645  ArgTy = FType->getReturnType();
1646  else if (Ins[i].isOrigArg())
1647  ArgTy = FType->getParamType(Ins[i].getOrigArgIndex());
1650  if (Fn(MF.getDataLayout(), ABI, i, ArgVT, CCValAssign::Full, Ins[i].Flags,
1651  CCInfo, /*IsFixed=*/true, IsRet, ArgTy)) {
1652  LLVM_DEBUG(dbgs() << "InputArg #" << i << " has unhandled type "
1653  << EVT(ArgVT).getEVTString() << '\n');
1654  llvm_unreachable("");
1655  }
1656  }
1657 }
1658 
1659 void LoongArchTargetLowering::analyzeOutputArgs(
1660  MachineFunction &MF, CCState &CCInfo,
1661  const SmallVectorImpl<ISD::OutputArg> &Outs, bool IsRet,
1662  CallLoweringInfo *CLI, LoongArchCCAssignFn Fn) const {
1663  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
1664  MVT ArgVT = Outs[i].VT;
1665  Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty : nullptr;
1668  if (Fn(MF.getDataLayout(), ABI, i, ArgVT, CCValAssign::Full, Outs[i].Flags,
1669  CCInfo, Outs[i].IsFixed, IsRet, OrigTy)) {
1670  LLVM_DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type "
1671  << EVT(ArgVT).getEVTString() << "\n");
1672  llvm_unreachable("");
1673  }
1674  }
1675 }
1676 
1677 // Convert Val to a ValVT. Should not be called for CCValAssign::Indirect
1678 // values.
1680  const CCValAssign &VA, const SDLoc &DL) {
1681  switch (VA.getLocInfo()) {
1682  default:
1683  llvm_unreachable("Unexpected CCValAssign::LocInfo");
1684  case CCValAssign::Full:
1685  case CCValAssign::Indirect:
1686  break;
1687  case CCValAssign::BCvt:
1688  if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f32)
1690  else
1691  Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);
1692  break;
1693  }
1694  return Val;
1695 }
1696 
1698  const CCValAssign &VA, const SDLoc &DL,
1699  const LoongArchTargetLowering &TLI) {
1700  MachineFunction &MF = DAG.getMachineFunction();
1701  MachineRegisterInfo &RegInfo = MF.getRegInfo();
1702  EVT LocVT = VA.getLocVT();
1703  SDValue Val;
1704  const TargetRegisterClass *RC = TLI.getRegClassFor(LocVT.getSimpleVT());
1705  Register VReg = RegInfo.createVirtualRegister(RC);
1706  RegInfo.addLiveIn(VA.getLocReg(), VReg);
1707  Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
1708 
1709  return convertLocVTToValVT(DAG, Val, VA, DL);
1710 }
1711 
1712 // The caller is responsible for loading the full value if the argument is
1713 // passed with CCValAssign::Indirect.
1715  const CCValAssign &VA, const SDLoc &DL) {
1716  MachineFunction &MF = DAG.getMachineFunction();
1717  MachineFrameInfo &MFI = MF.getFrameInfo();
1718  EVT ValVT = VA.getValVT();
1719  int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),
1720  /*IsImmutable=*/true);
1721  SDValue FIN = DAG.getFrameIndex(
1723 
1724  ISD::LoadExtType ExtType;
1725  switch (VA.getLocInfo()) {
1726  default:
1727  llvm_unreachable("Unexpected CCValAssign::LocInfo");
1728  case CCValAssign::Full:
1729  case CCValAssign::Indirect:
1730  case CCValAssign::BCvt:
1731  ExtType = ISD::NON_EXTLOAD;
1732  break;
1733  }
1734  return DAG.getExtLoad(
1735  ExtType, DL, VA.getLocVT(), Chain, FIN,
1737 }
1738 
1740  const CCValAssign &VA, const SDLoc &DL) {
1741  EVT LocVT = VA.getLocVT();
1742 
1743  switch (VA.getLocInfo()) {
1744  default:
1745  llvm_unreachable("Unexpected CCValAssign::LocInfo");
1746  case CCValAssign::Full:
1747  break;
1748  case CCValAssign::BCvt:
1749  if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f32)
1751  else
1752  Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val);
1753  break;
1754  }
1755  return Val;
1756 }
1757 
1758 // Transform physical registers into virtual registers.
1760  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
1761  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
1762  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
1763 
1764  MachineFunction &MF = DAG.getMachineFunction();
1765 
1766  switch (CallConv) {
1767  default:
1768  llvm_unreachable("Unsupported calling convention");
1769  case CallingConv::C:
1770  case CallingConv::Fast:
1771  break;
1772  }
1773 
1774  EVT PtrVT = getPointerTy(DAG.getDataLayout());
1775  MVT GRLenVT = Subtarget.getGRLenVT();
1776  unsigned GRLenInBytes = Subtarget.getGRLen() / 8;
1777  // Used with varargs to acumulate store chains.
1778  std::vector<SDValue> OutChains;
1779 
1780  // Assign locations to all of the incoming arguments.
1781  SmallVector<CCValAssign> ArgLocs;
1782  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
1783 
1784  analyzeInputArgs(MF, CCInfo, Ins, /*IsRet=*/false, CC_LoongArch);
1785 
1786  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1787  CCValAssign &VA = ArgLocs[i];
1788  SDValue ArgValue;
1789  if (VA.isRegLoc())
1790  ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, *this);
1791  else
1792  ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
1793  if (VA.getLocInfo() == CCValAssign::Indirect) {
1794  // If the original argument was split and passed by reference, we need to
1795  // load all parts of it here (using the same address).
1796  InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain, ArgValue,
1797  MachinePointerInfo()));
1798  unsigned ArgIndex = Ins[i].OrigArgIndex;
1799  unsigned ArgPartOffset = Ins[i].PartOffset;
1800  assert(ArgPartOffset == 0);
1801  while (i + 1 != e && Ins[i + 1].OrigArgIndex == ArgIndex) {
1802  CCValAssign &PartVA = ArgLocs[i + 1];
1803  unsigned PartOffset = Ins[i + 1].PartOffset - ArgPartOffset;
1804  SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL);
1805  SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, ArgValue, Offset);
1806  InVals.push_back(DAG.getLoad(PartVA.getValVT(), DL, Chain, Address,
1807  MachinePointerInfo()));
1808  ++i;
1809  }
1810  continue;
1811  }
1812  InVals.push_back(ArgValue);
1813  }
1814 
1815  if (IsVarArg) {
1817  unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
1818  const TargetRegisterClass *RC = &LoongArch::GPRRegClass;
1819  MachineFrameInfo &MFI = MF.getFrameInfo();
1820  MachineRegisterInfo &RegInfo = MF.getRegInfo();
1821  auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>();
1822 
1823  // Offset of the first variable argument from stack pointer, and size of
1824  // the vararg save area. For now, the varargs save area is either zero or
1825  // large enough to hold a0-a7.
1826  int VaArgOffset, VarArgsSaveSize;
1827 
1828  // If all registers are allocated, then all varargs must be passed on the
1829  // stack and we don't need to save any argregs.
1830  if (ArgRegs.size() == Idx) {
1831  VaArgOffset = CCInfo.getNextStackOffset();
1832  VarArgsSaveSize = 0;
1833  } else {
1834  VarArgsSaveSize = GRLenInBytes * (ArgRegs.size() - Idx);
1835  VaArgOffset = -VarArgsSaveSize;
1836  }
1837 
1838  // Record the frame index of the first variable argument
1839  // which is a value necessary to VASTART.
1840  int FI = MFI.CreateFixedObject(GRLenInBytes, VaArgOffset, true);
1841  LoongArchFI->setVarArgsFrameIndex(FI);
1842 
1843  // If saving an odd number of registers then create an extra stack slot to
1844  // ensure that the frame pointer is 2*GRLen-aligned, which in turn ensures
1845  // offsets to even-numbered registered remain 2*GRLen-aligned.
1846  if (Idx % 2) {
1847  MFI.CreateFixedObject(GRLenInBytes, VaArgOffset - (int)GRLenInBytes,
1848  true);
1849  VarArgsSaveSize += GRLenInBytes;
1850  }
1851 
1852  // Copy the integer registers that may have been used for passing varargs
1853  // to the vararg save area.
1854  for (unsigned I = Idx; I < ArgRegs.size();
1855  ++I, VaArgOffset += GRLenInBytes) {
1856  const Register Reg = RegInfo.createVirtualRegister(RC);
1857  RegInfo.addLiveIn(ArgRegs[I], Reg);
1858  SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, GRLenVT);
1859  FI = MFI.CreateFixedObject(GRLenInBytes, VaArgOffset, true);
1860  SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
1861  SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
1863  cast<StoreSDNode>(Store.getNode())
1864  ->getMemOperand()
1865  ->setValue((Value *)nullptr);
1866  OutChains.push_back(Store);
1867  }
1868  LoongArchFI->setVarArgsSaveSize(VarArgsSaveSize);
1869  }
1870 
1871  // All stores are grouped in one node to allow the matching between
1872  // the size of Ins and InVals. This only happens for vararg functions.
1873  if (!OutChains.empty()) {
1874  OutChains.push_back(Chain);
1875  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1876  }
1877 
1878  return Chain;
1879 }
1880 
1881 // Check whether the call is eligible for tail call optimization.
1882 bool LoongArchTargetLowering::isEligibleForTailCallOptimization(
1883  CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
1884  const SmallVectorImpl<CCValAssign> &ArgLocs) const {
1885 
1886  auto CalleeCC = CLI.CallConv;
1887  auto &Outs = CLI.Outs;
1888  auto &Caller = MF.getFunction();
1889  auto CallerCC = Caller.getCallingConv();
1890 
1891  // Do not tail call opt if the stack is used to pass parameters.
1892  if (CCInfo.getNextStackOffset() != 0)
1893  return false;
1894 
1895  // Do not tail call opt if any parameters need to be passed indirectly.
1896  for (auto &VA : ArgLocs)
1897  if (VA.getLocInfo() == CCValAssign::Indirect)
1898  return false;
1899 
1900  // Do not tail call opt if either caller or callee uses struct return
1901  // semantics.
1902  auto IsCallerStructRet = Caller.hasStructRetAttr();
1903  auto IsCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
1904  if (IsCallerStructRet || IsCalleeStructRet)
1905  return false;
1906 
1907  // Do not tail call opt if either the callee or caller has a byval argument.
1908  for (auto &Arg : Outs)
1909  if (Arg.Flags.isByVal())
1910  return false;
1911 
1912  // The callee has to preserve all registers the caller needs to preserve.
1913  const LoongArchRegisterInfo *TRI = Subtarget.getRegisterInfo();
1914  const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
1915  if (CalleeCC != CallerCC) {
1916  const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
1917  if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
1918  return false;
1919  }
1920  return true;
1921 }
1922 
1924  return DAG.getDataLayout().getPrefTypeAlign(
1925  VT.getTypeForEVT(*DAG.getContext()));
1926 }
1927 
1928 // Lower a call to a callseq_start + CALL + callseq_end chain, and add input
1929 // and output parameter nodes.
1930 SDValue
1932  SmallVectorImpl<SDValue> &InVals) const {
1933  SelectionDAG &DAG = CLI.DAG;
1934  SDLoc &DL = CLI.DL;
1936  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
1938  SDValue Chain = CLI.Chain;
1939  SDValue Callee = CLI.Callee;
1940  CallingConv::ID CallConv = CLI.CallConv;
1941  bool IsVarArg = CLI.IsVarArg;
1942  EVT PtrVT = getPointerTy(DAG.getDataLayout());
1943  MVT GRLenVT = Subtarget.getGRLenVT();
1944  bool &IsTailCall = CLI.IsTailCall;
1945 
1946  MachineFunction &MF = DAG.getMachineFunction();
1947 
1948  // Analyze the operands of the call, assigning locations to each operand.
1949  SmallVector<CCValAssign> ArgLocs;
1950  CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
1951 
1952  analyzeOutputArgs(MF, ArgCCInfo, Outs, /*IsRet=*/false, &CLI, CC_LoongArch);
1953 
1954  // Check if it's really possible to do a tail call.
1955  if (IsTailCall)
1956  IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs);
1957 
1958  if (IsTailCall)
1959  ++NumTailCalls;
1960  else if (CLI.CB && CLI.CB->isMustTailCall())
1961  report_fatal_error("failed to perform tail call elimination on a call "
1962  "site marked musttail");
1963 
1964  // Get a count of how many bytes are to be pushed on the stack.
1965  unsigned NumBytes = ArgCCInfo.getNextStackOffset();
1966 
1967  // Create local copies for byval args.
1968  SmallVector<SDValue> ByValArgs;
1969  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
1970  ISD::ArgFlagsTy Flags = Outs[i].Flags;
1971  if (!Flags.isByVal())
1972  continue;
1973 
1974  SDValue Arg = OutVals[i];
1975  unsigned Size = Flags.getByValSize();
1976  Align Alignment = Flags.getNonZeroByValAlign();
1977 
1978  int FI =
1979  MF.getFrameInfo().CreateStackObject(Size, Alignment, /*isSS=*/false);
1980  SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
1981  SDValue SizeNode = DAG.getConstant(Size, DL, GRLenVT);
1982 
1983  Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment,
1984  /*IsVolatile=*/false,
1985  /*AlwaysInline=*/false, /*isTailCall=*/IsTailCall,
1987  ByValArgs.push_back(FIPtr);
1988  }
1989 
1990  if (!IsTailCall)
1991  Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
1992 
1993  // Copy argument values to their designated locations.
1995  SmallVector<SDValue> MemOpChains;
1996  SDValue StackPtr;
1997  for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) {
1998  CCValAssign &VA = ArgLocs[i];
1999  SDValue ArgValue = OutVals[i];
2000  ISD::ArgFlagsTy Flags = Outs[i].Flags;
2001 
2002  // Promote the value if needed.
2003  // For now, only handle fully promoted and indirect arguments.
2004  if (VA.getLocInfo() == CCValAssign::Indirect) {
2005  // Store the argument in a stack slot and pass its address.
2006  Align StackAlign =
2007  std::max(getPrefTypeAlign(Outs[i].ArgVT, DAG),
2008  getPrefTypeAlign(ArgValue.getValueType(), DAG));
2009  TypeSize StoredSize = ArgValue.getValueType().getStoreSize();
2010  // If the original argument was split and passed by reference, we need to
2011  // store the required parts of it here (and pass just one address).
2012  unsigned ArgIndex = Outs[i].OrigArgIndex;
2013  unsigned ArgPartOffset = Outs[i].PartOffset;
2014  assert(ArgPartOffset == 0);
2015  // Calculate the total size to store. We don't have access to what we're
2016  // actually storing other than performing the loop and collecting the
2017  // info.
2019  while (i + 1 != e && Outs[i + 1].OrigArgIndex == ArgIndex) {
2020  SDValue PartValue = OutVals[i + 1];
2021  unsigned PartOffset = Outs[i + 1].PartOffset - ArgPartOffset;
2022  SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL);
2023  EVT PartVT = PartValue.getValueType();
2024 
2025  StoredSize += PartVT.getStoreSize();
2027  Parts.push_back(std::make_pair(PartValue, Offset));
2028  ++i;
2029  }
2030  SDValue SpillSlot = DAG.CreateStackTemporary(StoredSize, StackAlign);
2031  int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
2032  MemOpChains.push_back(
2033  DAG.getStore(Chain, DL, ArgValue, SpillSlot,
2035  for (const auto &Part : Parts) {
2036  SDValue PartValue = Part.first;
2037  SDValue PartOffset = Part.second;
2038  SDValue Address =
2039  DAG.getNode(ISD::ADD, DL, PtrVT, SpillSlot, PartOffset);
2040  MemOpChains.push_back(
2041  DAG.getStore(Chain, DL, PartValue, Address,
2043  }
2044  ArgValue = SpillSlot;
2045  } else {
2046  ArgValue = convertValVTToLocVT(DAG, ArgValue, VA, DL);
2047  }
2048 
2049  // Use local copy if it is a byval arg.
2050  if (Flags.isByVal())
2051  ArgValue = ByValArgs[j++];
2052 
2053  if (VA.isRegLoc()) {
2054  // Queue up the argument copies and emit them at the end.
2055  RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
2056  } else {
2057  assert(VA.isMemLoc() && "Argument not register or memory");
2058  assert(!IsTailCall && "Tail call not allowed if stack is used "
2059  "for passing parameters");
2060 
2061  // Work out the address of the stack slot.
2062  if (!StackPtr.getNode())
2063  StackPtr = DAG.getCopyFromReg(Chain, DL, LoongArch::R3, PtrVT);
2064  SDValue Address =
2065  DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
2066  DAG.getIntPtrConstant(VA.getLocMemOffset(), DL));
2067 
2068  // Emit the store.
2069  MemOpChains.push_back(
2070  DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
2071  }
2072  }
2073 
2074  // Join the stores, which are independent of one another.
2075  if (!MemOpChains.empty())
2076  Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
2077 
2078  SDValue Glue;
2079 
2080  // Build a sequence of copy-to-reg nodes, chained and glued together.
2081  for (auto &Reg : RegsToPass) {
2082  Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue);
2083  Glue = Chain.getValue(1);
2084  }
2085 
2086  // If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
2087  // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
2088  // split it and then direct call can be matched by PseudoCALL.
2089  if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
2090  const GlobalValue *GV = S->getGlobal();
2091  unsigned OpFlags =
2095  Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, OpFlags);
2096  } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2097  unsigned OpFlags = getTargetMachine().shouldAssumeDSOLocal(
2098  *MF.getFunction().getParent(), nullptr)
2101  Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags);
2102  }
2103 
2104  // The first call operand is the chain and the second is the target address.
2106  Ops.push_back(Chain);
2107  Ops.push_back(Callee);
2108 
2109  // Add argument registers to the end of the list so that they are
2110  // known live into the call.
2111  for (auto &Reg : RegsToPass)
2112  Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
2113 
2114  if (!IsTailCall) {
2115  // Add a register mask operand representing the call-preserved registers.
2116  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
2117  const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
2118  assert(Mask && "Missing call preserved mask for calling convention");
2119  Ops.push_back(DAG.getRegisterMask(Mask));
2120  }
2121 
2122  // Glue the call to the argument copies, if any.
2123  if (Glue.getNode())
2124  Ops.push_back(Glue);
2125 
2126  // Emit the call.
2127  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
2128 
2129  if (IsTailCall) {
2131  return DAG.getNode(LoongArchISD::TAIL, DL, NodeTys, Ops);
2132  }
2133 
2134  Chain = DAG.getNode(LoongArchISD::CALL, DL, NodeTys, Ops);
2135  DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
2136  Glue = Chain.getValue(1);
2137 
2138  // Mark the end of the call, which is glued to the call itself.
2139  Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, DL);
2140  Glue = Chain.getValue(1);
2141 
2142  // Assign locations to each value returned by this call.
2143  SmallVector<CCValAssign> RVLocs;
2144  CCState RetCCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
2145  analyzeInputArgs(MF, RetCCInfo, Ins, /*IsRet=*/true, CC_LoongArch);
2146 
2147  // Copy all of the result registers out of their specified physreg.
2148  for (auto &VA : RVLocs) {
2149  // Copy the value out.
2150  SDValue RetValue =
2151  DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue);
2152  // Glue the RetValue to the end of the call sequence.
2153  Chain = RetValue.getValue(1);
2154  Glue = RetValue.getValue(2);
2155 
2156  RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL);
2157 
2158  InVals.push_back(RetValue);
2159  }
2160 
2161  return Chain;
2162 }
2163 
2165  CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
2166  const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
2167  SmallVector<CCValAssign> RVLocs;
2168  CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
2169 
2170  for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
2173  if (CC_LoongArch(MF.getDataLayout(), ABI, i, Outs[i].VT, CCValAssign::Full,
2174  Outs[i].Flags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true,
2175  nullptr))
2176  return false;
2177  }
2178  return true;
2179 }
2180 
2182  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
2183  const SmallVectorImpl<ISD::OutputArg> &Outs,
2184  const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
2185  SelectionDAG &DAG) const {
2186  // Stores the assignment of the return value to a location.
2187  SmallVector<CCValAssign> RVLocs;
2188 
2189  // Info about the registers and stack slot.
2190  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
2191  *DAG.getContext());
2192 
2193  analyzeOutputArgs(DAG.getMachineFunction(), CCInfo, Outs, /*IsRet=*/true,
2194  nullptr, CC_LoongArch);
2195 
2196  SDValue Glue;
2197  SmallVector<SDValue, 4> RetOps(1, Chain);
2198 
2199  // Copy the result values into the output registers.
2200  for (unsigned i = 0, e = RVLocs.size(); i < e; ++i) {
2201  CCValAssign &VA = RVLocs[i];
2202  assert(VA.isRegLoc() && "Can only return in registers!");
2203 
2204  // Handle a 'normal' return.
2205  SDValue Val = convertValVTToLocVT(DAG, OutVals[i], VA, DL);
2206  Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);
2207 
2208  // Guarantee that all emitted copies are stuck together.
2209  Glue = Chain.getValue(1);
2210  RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
2211  }
2212 
2213  RetOps[0] = Chain; // Update chain.
2214 
2215  // Add the glue node if we have it.
2216  if (Glue.getNode())
2217  RetOps.push_back(Glue);
2218 
2219  return DAG.getNode(LoongArchISD::RET, DL, MVT::Other, RetOps);
2220 }
2221 
2222 bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
2223  bool ForCodeSize) const {
2224  // TODO: Maybe need more checks here after vector extension is supported.
2225  if (VT == MVT::f32 && !Subtarget.hasBasicF())
2226  return false;
2227  if (VT == MVT::f64 && !Subtarget.hasBasicD())
2228  return false;
2229  return (Imm.isZero() || Imm.isExactlyValue(+1.0));
2230 }
2231 
2233  return true;
2234 }
2235 
2237  return true;
2238 }
2239 
2240 bool LoongArchTargetLowering::shouldInsertFencesForAtomic(
2241  const Instruction *I) const {
2242  if (!Subtarget.is64Bit())
2243  return isa<LoadInst>(I) || isa<StoreInst>(I);
2244 
2245  if (isa<LoadInst>(I))
2246  return true;
2247 
2248  // On LA64, atomic store operations with IntegerBitWidth of 32 and 64 do not
2249  // require fences beacuse we can use amswap_db.[w/d].
2250  if (isa<StoreInst>(I)) {
2251  unsigned Size = I->getOperand(0)->getType()->getIntegerBitWidth();
2252  return (Size == 8 || Size == 16);
2253  }
2254 
2255  return false;
2256 }
2257 
2260  EVT VT) const {
2261  if (!VT.isVector())
2262  return getPointerTy(DL);
2264 }
2265 
2267  // TODO: Support vectors.
2268  return Y.getValueType().isScalarInteger() && !isa<ConstantSDNode>(Y);
2269 }
2270 
2272  const CallInst &I,
2273  MachineFunction &MF,
2274  unsigned Intrinsic) const {
2275  switch (Intrinsic) {
2276  default:
2277  return false;
2278  case Intrinsic::loongarch_masked_atomicrmw_xchg_i32:
2279  case Intrinsic::loongarch_masked_atomicrmw_add_i32:
2280  case Intrinsic::loongarch_masked_atomicrmw_sub_i32:
2281  case Intrinsic::loongarch_masked_atomicrmw_nand_i32:
2283  Info.memVT = MVT::i32;
2284  Info.ptrVal = I.getArgOperand(0);
2285  Info.offset = 0;
2286  Info.align = Align(4);
2289  return true;
2290  // TODO: Add more Intrinsics later.
2291  }
2292 }
2293 
2296  // TODO: Add more AtomicRMWInst that needs to be extended.
2297 
2298  // Since floating-point operation requires a non-trivial set of data
2299  // operations, use CmpXChg to expand.
2300  if (AI->isFloatingPointOperation())
2302 
2303  unsigned Size = AI->getType()->getPrimitiveSizeInBits();
2304  if (Size == 8 || Size == 16)
2307 }
2308 
2309 static Intrinsic::ID
2311  AtomicRMWInst::BinOp BinOp) {
2312  if (GRLen == 64) {
2313  switch (BinOp) {
2314  default:
2315  llvm_unreachable("Unexpected AtomicRMW BinOp");
2316  case AtomicRMWInst::Xchg:
2317  return Intrinsic::loongarch_masked_atomicrmw_xchg_i64;
2318  case AtomicRMWInst::Add:
2319  return Intrinsic::loongarch_masked_atomicrmw_add_i64;
2320  case AtomicRMWInst::Sub:
2321  return Intrinsic::loongarch_masked_atomicrmw_sub_i64;
2322  case AtomicRMWInst::Nand:
2323  return Intrinsic::loongarch_masked_atomicrmw_nand_i64;
2324  case AtomicRMWInst::UMax:
2325  return Intrinsic::loongarch_masked_atomicrmw_umax_i64;
2326  case AtomicRMWInst::UMin:
2327  return Intrinsic::loongarch_masked_atomicrmw_umin_i64;
2328  case AtomicRMWInst::Max:
2329  return Intrinsic::loongarch_masked_atomicrmw_max_i64;
2330  case AtomicRMWInst::Min:
2331  return Intrinsic::loongarch_masked_atomicrmw_min_i64;
2332  // TODO: support other AtomicRMWInst.
2333  }
2334  }
2335 
2336  if (GRLen == 32) {
2337  switch (BinOp) {
2338  default:
2339  llvm_unreachable("Unexpected AtomicRMW BinOp");
2340  case AtomicRMWInst::Xchg:
2341  return Intrinsic::loongarch_masked_atomicrmw_xchg_i32;
2342  case AtomicRMWInst::Add:
2343  return Intrinsic::loongarch_masked_atomicrmw_add_i32;
2344  case AtomicRMWInst::Sub:
2345  return Intrinsic::loongarch_masked_atomicrmw_sub_i32;
2346  case AtomicRMWInst::Nand:
2347  return Intrinsic::loongarch_masked_atomicrmw_nand_i32;
2348  // TODO: support other AtomicRMWInst.
2349  }
2350  }
2351 
2352  llvm_unreachable("Unexpected GRLen\n");
2353 }
2354 
2357  AtomicCmpXchgInst *CI) const {
2358  unsigned Size = CI->getCompareOperand()->getType()->getPrimitiveSizeInBits();
2359  if (Size == 8 || Size == 16)
2362 }
2363 
2365  IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr,
2366  Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const {
2367  Value *Ordering =
2368  Builder.getIntN(Subtarget.getGRLen(), static_cast<uint64_t>(Ord));
2369 
2370  // TODO: Support cmpxchg on LA32.
2371  Intrinsic::ID CmpXchgIntrID = Intrinsic::loongarch_masked_cmpxchg_i64;
2372  CmpVal = Builder.CreateSExt(CmpVal, Builder.getInt64Ty());
2373  NewVal = Builder.CreateSExt(NewVal, Builder.getInt64Ty());
2374  Mask = Builder.CreateSExt(Mask, Builder.getInt64Ty());
2375  Type *Tys[] = {AlignedAddr->getType()};
2376  Function *MaskedCmpXchg =
2377  Intrinsic::getDeclaration(CI->getModule(), CmpXchgIntrID, Tys);
2378  Value *Result = Builder.CreateCall(
2379  MaskedCmpXchg, {AlignedAddr, CmpVal, NewVal, Mask, Ordering});
2380  Result = Builder.CreateTrunc(Result, Builder.getInt32Ty());
2381  return Result;
2382 }
2383 
2385  IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr,
2386  Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const {
2387  unsigned GRLen = Subtarget.getGRLen();
2388  Value *Ordering =
2389  Builder.getIntN(GRLen, static_cast<uint64_t>(AI->getOrdering()));
2390  Type *Tys[] = {AlignedAddr->getType()};
2391  Function *LlwOpScwLoop = Intrinsic::getDeclaration(
2392  AI->getModule(),
2394 
2395  if (GRLen == 64) {
2396  Incr = Builder.CreateSExt(Incr, Builder.getInt64Ty());
2397  Mask = Builder.CreateSExt(Mask, Builder.getInt64Ty());
2398  ShiftAmt = Builder.CreateSExt(ShiftAmt, Builder.getInt64Ty());
2399  }
2400 
2401  Value *Result;
2402 
2403  // Must pass the shift amount needed to sign extend the loaded value prior
2404  // to performing a signed comparison for min/max. ShiftAmt is the number of
2405  // bits to shift the value into position. Pass GRLen-ShiftAmt-ValWidth, which
2406  // is the number of bits to left+right shift the value in order to
2407  // sign-extend.
2408  if (AI->getOperation() == AtomicRMWInst::Min ||
2409  AI->getOperation() == AtomicRMWInst::Max) {
2410  const DataLayout &DL = AI->getModule()->getDataLayout();
2411  unsigned ValWidth =
2412  DL.getTypeStoreSizeInBits(AI->getValOperand()->getType());
2413  Value *SextShamt =
2414  Builder.CreateSub(Builder.getIntN(GRLen, GRLen - ValWidth), ShiftAmt);
2415  Result = Builder.CreateCall(LlwOpScwLoop,
2416  {AlignedAddr, Incr, Mask, SextShamt, Ordering});
2417  } else {
2418  Result =
2419  Builder.CreateCall(LlwOpScwLoop, {AlignedAddr, Incr, Mask, Ordering});
2420  }
2421 
2422  if (GRLen == 64)
2423  Result = Builder.CreateTrunc(Result, Builder.getInt32Ty());
2424  return Result;
2425 }
2426 
2428  const MachineFunction &MF, EVT VT) const {
2429  VT = VT.getScalarType();
2430 
2431  if (!VT.isSimple())
2432  return false;
2433 
2434  switch (VT.getSimpleVT().SimpleTy) {
2435  case MVT::f32:
2436  case MVT::f64:
2437  return true;
2438  default:
2439  break;
2440  }
2441 
2442  return false;
2443 }
2444 
2446  const Constant *PersonalityFn) const {
2447  return LoongArch::R4;
2448 }
2449 
2451  const Constant *PersonalityFn) const {
2452  return LoongArch::R5;
2453 }
2454 
2455 //===----------------------------------------------------------------------===//
2456 // LoongArch Inline Assembly Support
2457 //===----------------------------------------------------------------------===//
2458 
2460 LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
2461  // LoongArch specific constraints in GCC: config/loongarch/constraints.md
2462  //
2463  // 'f': A floating-point register (if available).
2464  // 'k': A memory operand whose address is formed by a base register and
2465  // (optionally scaled) index register.
2466  // 'l': A signed 16-bit constant.
2467  // 'm': A memory operand whose address is formed by a base register and
2468  // offset that is suitable for use in instructions with the same
2469  // addressing mode as st.w and ld.w.
2470  // 'I': A signed 12-bit constant (for arithmetic instructions).
2471  // 'J': Integer zero.
2472  // 'K': An unsigned 12-bit constant (for logic instructions).
2473  // "ZB": An address that is held in a general-purpose register. The offset is
2474  // zero.
2475  // "ZC": A memory operand whose address is formed by a base register and
2476  // offset that is suitable for use in instructions with the same
2477  // addressing mode as ll.w and sc.w.
2478  if (Constraint.size() == 1) {
2479  switch (Constraint[0]) {
2480  default:
2481  break;
2482  case 'f':
2483  return C_RegisterClass;
2484  case 'l':
2485  case 'I':
2486  case 'J':
2487  case 'K':
2488  return C_Immediate;
2489  case 'k':
2490  return C_Memory;
2491  }
2492  }
2493 
2494  if (Constraint == "ZC" || Constraint == "ZB")
2495  return C_Memory;
2496 
2497  // 'm' is handled here.
2498  return TargetLowering::getConstraintType(Constraint);
2499 }
2500 
2501 unsigned LoongArchTargetLowering::getInlineAsmMemConstraint(
2502  StringRef ConstraintCode) const {
2503  return StringSwitch<unsigned>(ConstraintCode)
2508 }
2509 
2510 std::pair<unsigned, const TargetRegisterClass *>
2511 LoongArchTargetLowering::getRegForInlineAsmConstraint(
2512  const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
2513  // First, see if this is a constraint that directly corresponds to a LoongArch
2514  // register class.
2515  if (Constraint.size() == 1) {
2516  switch (Constraint[0]) {
2517  case 'r':
2518  // TODO: Support fixed vectors up to GRLen?
2519  if (VT.isVector())
2520  break;
2521  return std::make_pair(0U, &LoongArch::GPRRegClass);
2522  case 'f':
2523  if (Subtarget.hasBasicF() && VT == MVT::f32)
2524  return std::make_pair(0U, &LoongArch::FPR32RegClass);
2525  if (Subtarget.hasBasicD() && VT == MVT::f64)
2526  return std::make_pair(0U, &LoongArch::FPR64RegClass);
2527  break;
2528  default:
2529  break;
2530  }
2531  }
2532 
2533  // TargetLowering::getRegForInlineAsmConstraint uses the name of the TableGen
2534  // record (e.g. the "R0" in `def R0`) to choose registers for InlineAsm
2535  // constraints while the official register name is prefixed with a '$'. So we
2536  // clip the '$' from the original constraint string (e.g. {$r0} to {r0}.)
2537  // before it being parsed. And TargetLowering::getRegForInlineAsmConstraint is
2538  // case insensitive, so no need to convert the constraint to upper case here.
2539  //
2540  // For now, no need to support ABI names (e.g. `$a0`) as clang will correctly
2541  // decode the usage of register name aliases into their official names. And
2542  // AFAIK, the not yet upstreamed `rustc` for LoongArch will always use
2543  // official register names.
2544  if (Constraint.startswith("{$r") || Constraint.startswith("{$f")) {
2545  bool IsFP = Constraint[2] == 'f';
2546  std::pair<StringRef, StringRef> Temp = Constraint.split('$');
2547  std::pair<unsigned, const TargetRegisterClass *> R;
2549  TRI, join_items("", Temp.first, Temp.second), VT);
2550  // Match those names to the widest floating point register type available.
2551  if (IsFP) {
2552  unsigned RegNo = R.first;
2553  if (LoongArch::F0 <= RegNo && RegNo <= LoongArch::F31) {
2554  if (Subtarget.hasBasicD() && (VT == MVT::f64 || VT == MVT::Other)) {
2555  unsigned DReg = RegNo - LoongArch::F0 + LoongArch::F0_64;
2556  return std::make_pair(DReg, &LoongArch::FPR64RegClass);
2557  }
2558  }
2559  }
2560  return R;
2561  }
2562 
2563  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
2564 }
2565 
2566 void LoongArchTargetLowering::LowerAsmOperandForConstraint(
2567  SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops,
2568  SelectionDAG &DAG) const {
2569  // Currently only support length 1 constraints.
2570  if (Constraint.length() == 1) {
2571  switch (Constraint[0]) {
2572  case 'l':
2573  // Validate & create a 16-bit signed immediate operand.
2574  if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
2575  uint64_t CVal = C->getSExtValue();
2576  if (isInt<16>(CVal))
2577  Ops.push_back(
2578  DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT()));
2579  }
2580  return;
2581  case 'I':
2582  // Validate & create a 12-bit signed immediate operand.
2583  if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
2584  uint64_t CVal = C->getSExtValue();
2585  if (isInt<12>(CVal))
2586  Ops.push_back(
2587  DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT()));
2588  }
2589  return;
2590  case 'J':
2591  // Validate & create an integer zero operand.
2592  if (auto *C = dyn_cast<ConstantSDNode>(Op))
2593  if (C->getZExtValue() == 0)
2594  Ops.push_back(
2595  DAG.getTargetConstant(0, SDLoc(Op), Subtarget.getGRLenVT()));
2596  return;
2597  case 'K':
2598  // Validate & create a 12-bit unsigned immediate operand.
2599  if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
2600  uint64_t CVal = C->getZExtValue();
2601  if (isUInt<12>(CVal))
2602  Ops.push_back(
2603  DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT()));
2604  }
2605  return;
2606  default:
2607  break;
2608  }
2609  }
2610  TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
2611 }
2612 
2613 #define GET_REGISTER_MATCHER
2614 #include "LoongArchGenAsmMatcher.inc"
2615 
2616 Register
2618  const MachineFunction &MF) const {
2619  std::pair<StringRef, StringRef> Name = StringRef(RegName).split('$');
2620  std::string NewRegName = Name.second.str();
2621  Register Reg = MatchRegisterAltName(NewRegName);
2622  if (Reg == LoongArch::NoRegister)
2623  Reg = MatchRegisterName(NewRegName);
2624  if (Reg == LoongArch::NoRegister)
2626  Twine("Invalid register name \"" + StringRef(RegName) + "\"."));
2627  BitVector ReservedRegs = Subtarget.getRegisterInfo()->getReservedRegs(MF);
2628  if (!ReservedRegs.test(Reg))
2629  report_fatal_error(Twine("Trying to obtain non-reserved register \"" +
2630  StringRef(RegName) + "\"."));
2631  return Reg;
2632 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
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:7330
llvm::LoongArchSubtarget::getRegisterInfo
const LoongArchRegisterInfo * getRegisterInfo() const override
Definition: LoongArchSubtarget.h:74
i
i
Definition: README.txt:29
getLoongArchWOpcode
static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode)
Definition: LoongArchISelLowering.cpp:760
llvm::ISD::SETUGE
@ SETUGE
Definition: ISDOpcodes.h:1437
llvm::LoongArchTargetLowering::LowerOperation
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
Definition: LoongArchISelLowering.cpp:210
llvm::LoongArchISD::SRA_W
@ SRA_W
Definition: LoongArchISelLowering.h:37
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1582
ABI
Generic address nodes are lowered to some combination of target independent and machine specific ABI
Definition: Relocation.txt:34
llvm::ISD::STRICT_FSETCC
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
Definition: ISDOpcodes.h:475
llvm::RISCVAttrs::StackAlign
StackAlign
Definition: RISCVAttributes.h:37
performORCombine
static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
Definition: LoongArchISelLowering.cpp:1072
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:988
llvm::ISD::ArgFlagsTy::isSplit
bool isSplit() const
Definition: TargetCallingConv.h:132
llvm::LoongArchISD::CRC_W_D_W
@ CRC_W_D_W
Definition: LoongArchISelLowering.h:69
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::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::LLVMContext::emitError
void emitError(uint64_t LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
Definition: LLVMContext.cpp:271
llvm::ISD::JumpTable
@ JumpTable
Definition: ISDOpcodes.h:81
llvm::Instruction::getModule
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:69
llvm::LoongArchTargetLowering::getTargetNodeName
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
Definition: LoongArchISelLowering.cpp:1391
llvm::LoongArchABI::ABI_LP64S
@ ABI_LP64S
Definition: LoongArchBaseInfo.h:51
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1106
llvm::CCValAssign::Full
@ Full
Definition: CallingConvLower.h:34
llvm::TargetLoweringBase::Legal
@ Legal
Definition: TargetLowering.h:196
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::ISD::OR
@ OR
Definition: ISDOpcodes.h:667
llvm::MachineBasicBlock::getBasicBlock
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
Definition: MachineBasicBlock.h:209
llvm::ISD::SETGT
@ SETGT
Definition: ISDOpcodes.h:1445
llvm::ISD::BITCAST
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:886
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1481
llvm::ISD::SETNE
@ SETNE
Definition: ISDOpcodes.h:1449
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::MachineFrameInfo::setReturnAddressIsTaken
void setReturnAddressIsTaken(bool s)
Definition: MachineFrameInfo.h:378
llvm::TargetLowering::ConstraintType
ConstraintType
Definition: TargetLowering.h:4554
llvm::ISD::BR_JT
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:991
llvm::SelectionDAG::addNoMergeSiteInfo
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
Definition: SelectionDAG.h:2249
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::SelectionDAG::getCopyToReg
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:767
llvm::ISD::AssertSext
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::SDValue::getNode
SDNode * getNode() const
get the SDNode which holds the desired result
Definition: SelectionDAGNodes.h:159
llvm::LoongArchISD::SYSCALL
@ SYSCALL
Definition: LoongArchISelLowering.h:66
llvm::Function
Definition: Function.h:60
llvm::ISD::BSWAP
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:700
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:95
llvm::ISD::DYNAMIC_STACKALLOC
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:976
llvm::CCState::addLoc
void addLoc(const CCValAssign &V)
Definition: CallingConvLower.h:251
llvm::KnownBits::Zero
APInt Zero
Definition: KnownBits.h:24
llvm::LoongArchSubtarget::getGRLen
unsigned getGRLen() const
Definition: LoongArchSubtarget.h:94
llvm::TLSModel::GeneralDynamic
@ GeneralDynamic
Definition: CodeGen.h:43
llvm::MachineOperand::setIsKill
void setIsKill(bool Val=true)
Definition: MachineOperand.h:509
llvm::AtomicRMWInst::getOperation
BinOp getOperation() const
Definition: Instructions.h:801
llvm::AtomicRMWInst::BinOp
BinOp
This enumeration lists the possible modifications atomicrmw can make.
Definition: Instructions.h:727
LoongArchRegisterInfo.h
llvm::TargetLoweringBase::setMinCmpXchgSizeInBits
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
Definition: TargetLowering.h:2544
llvm::SelectionDAG::getFrameIndex
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
Definition: SelectionDAG.cpp:1739
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::LoongArchABI::ABI_ILP32D
@ ABI_ILP32D
Definition: LoongArchBaseInfo.h:50
Statistic.h
llvm::LoongArchISD::MOVGR2FR_W_LA64
@ MOVGR2FR_W_LA64
Definition: LoongArchISelLowering.h:44
llvm::MVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: MachineValueType.h:386
llvm::ISD::STACKRESTORE
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1057
llvm::SelectionDAG::getVTList
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
Definition: SelectionDAG.cpp:9378
llvm::MipsISD::Lo
@ Lo
Definition: MipsISelLowering.h:79
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::LoongArchTargetLowering::emitMaskedAtomicRMWIntrinsic
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
Definition: LoongArchISelLowering.cpp:2384
llvm::LoongArchTargetLowering::isCheapToSpeculateCtlz
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
Definition: LoongArchISelLowering.cpp:2236
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:463
llvm::ISD::FMA
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition: ISDOpcodes.h:482
llvm::ISD::FP_TO_SINT
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:819
llvm::TargetLowering::DAGCombinerInfo::DAG
SelectionDAG & DAG
Definition: TargetLowering.h:3913
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:282
llvm::CCValAssign::Indirect
@ Indirect
Definition: CallingConvLower.h:50
R4
#define R4(n)
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:237
convertValVTToLocVT
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
Definition: LoongArchISelLowering.cpp:1739
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::TargetLowering::C_Memory
@ C_Memory
Definition: TargetLowering.h:4557
llvm::LoongArchISD::BITREV_W
@ BITREV_W
Definition: LoongArchISelLowering.h:60
llvm::LoongArchSubtarget::is64Bit
bool is64Bit() const
Definition: LoongArchSubtarget.h:83
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::RTLIB::Libcall
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Definition: RuntimeLibcalls.h:30
llvm::LoongArchABI::ABI_LP64F
@ ABI_LP64F
Definition: LoongArchBaseInfo.h:52
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::LoongArchII::MO_CALL
@ MO_CALL
Definition: LoongArchBaseInfo.h:30
llvm::LoongArchISD::FIRST_NUMBER
@ FIRST_NUMBER
Definition: LoongArchISelLowering.h:27
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:8038
llvm::LoongArchABI::ABI_ILP32F
@ ABI_ILP32F
Definition: LoongArchBaseInfo.h:49
llvm::InlineAsm::Constraint_k
@ Constraint_k
Definition: InlineAsm.h:258
llvm::LoongArchTargetLowering::getRegisterByName
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
Definition: LoongArchISelLowering.cpp:2617
llvm::MachineFunction::insert
void insert(iterator MBBI, MachineBasicBlock *MBB)
Definition: MachineFunction.h:873
llvm::AArch64ISD::CALL
@ CALL
Definition: AArch64ISelLowering.h:53
LoongArchSubtarget.h
llvm::CallBase::isMustTailCall
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Definition: Instructions.cpp:300
llvm::TargetLowering::CallLoweringInfo::CB
const CallBase * CB
Definition: TargetLowering.h:4165
ZeroDivCheck
static cl::opt< bool > ZeroDivCheck("loongarch-check-zero-division", cl::Hidden, cl::desc("Trap on integer division by zero."), cl::init(false))
llvm::CCValAssign::BCvt
@ BCvt
Definition: CallingConvLower.h:44
llvm::TargetLoweringBase::setMinFunctionAlignment
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
Definition: TargetLowering.h:2506
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:9814
llvm::SPII::Store
@ Store
Definition: SparcInstrInfo.h:33
llvm::CCValAssign::getPending
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
Definition: CallingConvLower.h:125
llvm::ISD::FMAXNUM_IEEE
@ FMAXNUM_IEEE
Definition: ISDOpcodes.h:951
Results
Function Alias Analysis Results
Definition: AliasAnalysis.cpp:772
llvm::LoongArchISD::SLL_W
@ SLL_W
Definition: LoongArchISelLowering.h:36
llvm::LoongArchTargetLowering::LoongArchTargetLowering
LoongArchTargetLowering(const TargetMachine &TM, const LoongArchSubtarget &STI)
Definition: LoongArchISelLowering.cpp:41
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
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
llvm::LoongArchTargetLowering::getExceptionPointerRegister
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
Definition: LoongArchISelLowering.cpp:2445
ArgFPR64s
const MCPhysReg ArgFPR64s[]
Definition: LoongArchISelLowering.cpp:1447
llvm::BlockAddressSDNode
Definition: SelectionDAGNodes.h:2195
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
llvm::LoongArchTargetLowering::shouldExpandAtomicCmpXchgInIR
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
Definition: LoongArchISelLowering.cpp:2356
llvm::SelectionDAG::getContext
LLVMContext * getContext() const
Definition: SelectionDAG.h:479
llvm::LoongArchTargetLowering::getExceptionSelectorRegister
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
Definition: LoongArchISelLowering.cpp:2450
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::RTLIB::getUINTTOFP
Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Definition: TargetLoweringBase.cpp:452
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:265
KnownBits.h
llvm::SelectionDAG::getRegister
SDValue getRegister(unsigned Reg, EVT VT)
Definition: SelectionDAG.cpp:2121
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
llvm::MipsISD::Hi
@ Hi
Definition: MipsISelLowering.h:75
llvm::EVT::isSimple
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:129
llvm::Reloc::Model
Model
Definition: CodeGen.h:22
llvm::ISD::ROTL
@ ROTL
Definition: ISDOpcodes.h:694
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
getTargetNode
static SDValue getTargetNode(GlobalAddressSDNode *N, SDLoc DL, EVT Ty, SelectionDAG &DAG, unsigned Flags)
Definition: LoongArchISelLowering.cpp:439
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:2498
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
llvm::MachineBasicBlock::addSuccessor
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Definition: MachineBasicBlock.cpp:762
llvm::MachineOperand::isKill
bool isKill() const
Definition: MachineOperand.h:389
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
llvm::ISD::LoadExtType
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition: ISDOpcodes.h:1404
llvm::ISD::BR_CC
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1008
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:7988
R2
#define R2(n)
llvm::MVT::i1
@ i1
Definition: MachineValueType.h:43
llvm::EVT::getStoreSize
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition: ValueTypes.h:362
llvm::SDNode::getOpcode
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Definition: SelectionDAGNodes.h:644
llvm::TargetLowering::CallLoweringInfo::IsVarArg
bool IsVarArg
Definition: TargetLowering.h:4143
llvm::LoongArchTargetLowering::hasAndNot
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
Definition: LoongArchISelLowering.cpp:2266
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:667
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:2237
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:1141
llvm::CCValAssign
CCValAssign - Represent assignment of one arg/retval to a location.
Definition: CallingConvLower.h:31
llvm::ISD::CTLZ
@ CTLZ
Definition: ISDOpcodes.h:702
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
llvm::StringRef::startswith
bool startswith(StringRef Prefix) const
Definition: StringRef.h:260
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
llvm::ISD::SELECT
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:713
llvm::ISD::Constant
@ Constant
Definition: ISDOpcodes.h:76
llvm::TargetLowering::DAGCombinerInfo::isBeforeLegalizeOps
bool isBeforeLegalizeOps() const
Definition: TargetLowering.h:3919
llvm::SelectionDAG::getTargetBlockAddress
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:762
llvm::LoongArchMachineFunctionInfo
LoongArchMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private Lo...
Definition: LoongArchMachineFunctionInfo.h:25
llvm::ISD::SETGE
@ SETGE
Definition: ISDOpcodes.h:1446
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:755
llvm::SelectionDAG::getUNDEF
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
Definition: SelectionDAG.h:1023
llvm::ISD::SIGN_EXTEND_INREG
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:781
MatchRegisterAltName
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
llvm::SelectionDAG::getTargetLoweringInfo
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:475
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:34
llvm::LoongArchISD::REVB_2H
@ REVB_2H
Definition: LoongArchISelLowering.h:57
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
LoongArchISelLowering.h
false
Function Alias Analysis false
Definition: AliasAnalysis.cpp:772
llvm::MVT::f64
@ f64
Definition: MachineValueType.h:58
llvm::SelectionDAG::getConstant
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
Definition: SelectionDAG.cpp:1514
llvm::JumpTableSDNode
Definition: SelectionDAGNodes.h:1862
llvm::isShiftedMask_64
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
Definition: MathExtras.h:452
performANDCombine
static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
Definition: LoongArchISelLowering.cpp:968
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition: TargetLowering.h:3490
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
llvm::LoongArchTargetLowering::ReplaceNodeResults
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
Definition: LoongArchISelLowering.cpp:814
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::TargetLowering::DAGCombinerInfo
Definition: TargetLowering.h:3907
llvm::LoongArchTargetLowering::isCheapToSpeculateCttz
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
Definition: LoongArchISelLowering.cpp:2232
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::ISD::TRUNCATE
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:769
llvm::MVT::SimpleTy
SimpleValueType SimpleTy
Definition: MachineValueType.h:341
llvm::ISD::SRA
@ SRA
Definition: ISDOpcodes.h:692
llvm::ISD::FMINNUM_IEEE
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on two values,...
Definition: ISDOpcodes.h:950
llvm::ISD::ArgFlagsTy::isSplitEnd
bool isSplitEnd() const
Definition: TargetCallingConv.h:135
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
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:2343
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::IntegerType
Class to represent integer types.
Definition: DerivedTypes.h:40
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
llvm::Instruction
Definition: Instruction.h:42
llvm::LoongArchABI::getTargetABI
ABI getTargetABI(StringRef ABIName)
Definition: LoongArchBaseInfo.cpp:23
llvm::ISD::SINT_TO_FP
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:773
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
llvm::AtomicRMWInst::Nand
@ Nand
*p = ~(old & v)
Definition: Instructions.h:737
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::ISD::FRINT
@ FRINT
Definition: ISDOpcodes.h:926
llvm::LoongArchSubtarget::hasBasicF
bool hasBasicF() const
Definition: LoongArchSubtarget.h:84
llvm::TargetLowering::C_Immediate
@ C_Immediate
Definition: TargetLowering.h:4559
llvm::LoongArchRegisterInfo
Definition: LoongArchRegisterInfo.h:24
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::BitVector
Definition: BitVector.h:75
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
Align
uint64_t Align
Definition: ELFObjHandler.cpp:82
llvm::LoongArchISD::FTINT
@ FTINT
Definition: LoongArchISelLowering.h:47
llvm::ISD::FSINCOS
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:960
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
unpackFromRegLoc
static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL, const LoongArchTargetLowering &TLI)
Definition: LoongArchISelLowering.cpp:1697
llvm::AtomicRMWInst::Xchg
@ Xchg
*p = v
Definition: Instructions.h:729
llvm::SDValue::getConstantOperandVal
uint64_t getConstantOperandVal(unsigned i) const
Definition: SelectionDAGNodes.h:1153
llvm::EVT::changeVectorElementTypeToInteger
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition: ValueTypes.h:93
llvm::AtomicRMWInst::Add
@ Add
*p = old + v
Definition: Instructions.h:731
llvm::LoongArchTargetLowering::getTgtMemIntrinsic
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
Definition: LoongArchISelLowering.cpp:2271
llvm::EVT::getTypeForEVT
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:182
llvm::CCValAssign::isRegLoc
bool isRegLoc() const
Definition: CallingConvLower.h:143
llvm::TargetLowering::makeLibCall
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Definition: TargetLowering.cpp:144
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::ISD::SETUGT
@ SETUGT
Definition: ISDOpcodes.h:1436
NODE_NAME_CASE
#define NODE_NAME_CASE(node)
llvm::ISD::ArgFlagsTy::getNonZeroOrigAlign
Align getNonZeroOrigAlign() const
Definition: TargetCallingConv.h:160
llvm::SelectionDAG::getTargetGlobalAddress
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:715
llvm::LoongArchTargetLowering::LowerCall
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
Definition: LoongArchISelLowering.cpp:1931
llvm::MVT::isFloatingPoint
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: MachineValueType.h:360
llvm::ISD::FPOW
@ FPOW
Definition: ISDOpcodes.h:918
llvm::APInt::isSubsetOf
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
Definition: APInt.h:1227
convertLocVTToValVT
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
Definition: LoongArchISelLowering.cpp:1679
llvm::TargetRegisterInfo::regmaskSubsetEqual
bool regmaskSubsetEqual(const uint32_t *mask0, const uint32_t *mask1) const
Return true if all bits that are set in mask mask0 are also set in mask1.
Definition: TargetRegisterInfo.cpp:492
llvm::LoongArchTargetLowering::LowerReturn
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
Definition: LoongArchISelLowering.cpp:2181
llvm::ISD::BlockAddress
@ BlockAddress
Definition: ISDOpcodes.h:84
llvm::DataLayout::getPrefTypeAlign
Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
Definition: DataLayout.cpp:838
llvm::TargetLowering::CallLoweringInfo::Outs
SmallVector< ISD::OutputArg, 32 > Outs
Definition: TargetLowering.h:4166
llvm::ISD::STRICT_FSETCCS
@ STRICT_FSETCCS
Definition: ISDOpcodes.h:476
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
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:2360
llvm::AtomicOrdering
AtomicOrdering
Atomic ordering for LLVM's memory model.
Definition: AtomicOrdering.h:56
llvm::AtomicRMWInst::UMin
@ UMin
*p = old <unsigned v ? old : v
Definition: Instructions.h:749
llvm::ISD::WRITE_REGISTER
@ WRITE_REGISTER
Definition: ISDOpcodes.h:119
llvm::cl::opt< bool >
llvm::LoongArchRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: LoongArchRegisterInfo.cpp:109
llvm::LoongArchSubtarget::hasBasicD
bool hasBasicD() const
Definition: LoongArchSubtarget.h:85
llvm::APFloat
Definition: APFloat.h:716
llvm::CCValAssign::LocInfo
LocInfo
Definition: CallingConvLower.h:33
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::TargetLowering::MakeLibCallOptions
This structure is used to pass arguments to makeLibCall function.
Definition: TargetLowering.h:4304
llvm::EVT::getSizeInBits
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:340
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
llvm::AtomicRMWInst::Sub
@ Sub
*p = old - v
Definition: Instructions.h:733
getPrefTypeAlign
static Align getPrefTypeAlign(EVT VT, SelectionDAG &DAG)
Definition: LoongArchISelLowering.cpp:1923
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
uint64_t
llvm::TLSModel::LocalDynamic
@ LocalDynamic
Definition: CodeGen.h:44
RuntimeLibcalls.h
llvm::ISD::FP_TO_UINT
@ FP_TO_UINT
Definition: ISDOpcodes.h:820
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:652
llvm::TargetLowering::verifyReturnAddressArgumentIsConstant
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
Definition: TargetLowering.cpp:6653
llvm::TargetLoweringBase::TypeSoftenFloat
@ TypeSoftenFloat
Definition: TargetLowering.h:209
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
llvm::TargetLowering::CallLoweringInfo::Chain
SDValue Chain
Definition: TargetLowering.h:4139
llvm::SelectionDAG::getIntPtrConstant
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Definition: SelectionDAG.cpp:1634
llvm::LoongArchSubtarget
Definition: LoongArchSubtarget.h:32
llvm::ISD::AssertZext
@ AssertZext
Definition: ISDOpcodes.h:62
llvm::TargetLoweringBase::Promote
@ Promote
Definition: TargetLowering.h:197
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::numbers::e
constexpr double e
Definition: MathExtras.h:53
llvm::AtomicRMWInst::getOrdering
AtomicOrdering getOrdering() const
Returns the ordering constraint of this rmw instruction.
Definition: Instructions.h:843
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:793
llvm::LoongArchII::MO_CALL_PLT
@ MO_CALL_PLT
Definition: LoongArchBaseInfo.h:31
llvm::TargetLowering::CallLoweringInfo::CallConv
CallingConv::ID CallConv
Definition: TargetLowering.h:4160
llvm::LoongArchTargetLowering::LowerFormalArguments
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
Definition: LoongArchISelLowering.cpp:1759
llvm::TargetLoweringBase::setStackPointerRegisterToSaveRestore
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
Definition: TargetLowering.h:2309
llvm::SDNode::getOperand
const SDValue & getOperand(unsigned Num) const
Definition: SelectionDAGNodes.h:921
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:9072
llvm::FunctionType::getParamType
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition: DerivedTypes.h:135
llvm::AtomicRMWInst::Min
@ Min
*p = old <signed v ? old : v
Definition: Instructions.h:745
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:447
size
i< reg-> size
Definition: README.txt:166
llvm::TargetLowering::CallLoweringInfo::DL
SDLoc DL
Definition: TargetLowering.h:4164
llvm::MachineFunction::CreateMachineBasicBlock
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Definition: MachineFunction.cpp:439
llvm::CCValAssign::getMem
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
Definition: CallingConvLower.h:100
getIntrinsicForMaskedAtomicRMWBinOp
static Intrinsic::ID getIntrinsicForMaskedAtomicRMWBinOp(unsigned GRLen, AtomicRMWInst::BinOp BinOp)
Definition: LoongArchISelLowering.cpp:2310
llvm::LoongArchISD::ROTR_W
@ ROTR_W
Definition: LoongArchISelLowering.h:41
llvm::LoongArchISD::ROTL_W
@ ROTL_W
Definition: LoongArchISelLowering.h:40
llvm::TargetMachine::getTLSModel
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
Definition: TargetMachine.cpp:154
llvm::MachineFrameInfo::setHasTailCall
void setHasTailCall(bool V=true)
Definition: MachineFrameInfo.h:639
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::ISD::SETOGT
@ SETOGT
Definition: ISDOpcodes.h:1428
llvm::TargetLowering::CallLoweringInfo
This structure contains all information that is necessary for lowering calls.
Definition: TargetLowering.h:4138
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::LoongArchABI::ABI
ABI
Definition: LoongArchBaseInfo.h:47
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
llvm::LoongArchTargetLowering::getSetCCResultType
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the ValueType of the result of SETCC operations.
Definition: LoongArchISelLowering.cpp:2258
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::LoongArchTargetLowering::PerformDAGCombine
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
Definition: LoongArchISelLowering.cpp:1305
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:42
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:853
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:673
llvm::ISD::DEBUGTRAP
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
Definition: ISDOpcodes.h:1136
llvm::AtomicCmpXchgInst::getCompareOperand
Value * getCompareOperand()
Definition: Instructions.h:644
llvm::ConstantSDNode::getZExtValue
uint64_t getZExtValue() const
Definition: SelectionDAGNodes.h:1597
llvm::AtomicRMWInst::isFloatingPointOperation
bool isFloatingPointOperation() const
Definition: Instructions.h:878
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:261
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
llvm::ISD::CondCode
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1424
llvm::ISD::EH_DWARF_CFA
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
Definition: ISDOpcodes.h:129
llvm::SelectionDAG::getMachineNode
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
Definition: SelectionDAG.cpp:9816
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::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
MatchRegisterName
static unsigned MatchRegisterName(StringRef Name)
llvm::LoongArchISD::CALL
@ CALL
Definition: LoongArchISelLowering.h:30
R6
#define R6(n)
llvm::LoongArchTargetLowering
Definition: LoongArchISelLowering.h:73
llvm::LoongArchSubtarget::getGRLenVT
MVT getGRLenVT() const
Definition: LoongArchSubtarget.h:93
llvm::SelectionDAG::CreateStackTemporary
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
Definition: SelectionDAG.cpp:2342
llvm::ISD::SRA_PARTS
@ SRA_PARTS
Definition: ISDOpcodes.h:750
llvm::ISD::VASTART
@ VASTART
Definition: ISDOpcodes.h:1087
llvm::LoongArchTargetLowering::emitMaskedAtomicCmpXchgIntrinsic
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
Definition: LoongArchISelLowering.cpp:2364
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::CCState::getPendingLocs
SmallVectorImpl< CCValAssign > & getPendingLocs()
Definition: CallingConvLower.h:496
CC_LoongArch
static bool CC_LoongArch(const DataLayout &DL, LoongArchABI::ABI ABI, unsigned ValNo, MVT ValVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed, bool IsRet, Type *OrigTy)
Definition: LoongArchISelLowering.cpp:1489
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm::MachineFunction
Definition: MachineFunction.h:257
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:1000
llvm::MachineFunction::addLiveIn
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
Definition: MachineFunction.cpp:679
llvm::TargetLowering::CallLoweringInfo::Ins
SmallVector< ISD::InputArg, 32 > Ins
Definition: TargetLowering.h:4168
llvm::ISD::ConstantPool
@ ConstantPool
Definition: ISDOpcodes.h:82
llvm::ISD::GlobalTLSAddress
@ GlobalTLSAddress
Definition: ISDOpcodes.h:79
llvm::CCValAssign::getValNo
unsigned getValNo() const
Definition: CallingConvLower.h:140
llvm::TargetLowering::CallLoweringInfo::DAG
SelectionDAG & DAG
Definition: TargetLowering.h:4163
llvm::SelectionDAG::getTargetConstantPool
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=None, int Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:731
llvm::LoongArchISD::IBAR
@ IBAR
Definition: LoongArchISelLowering.h:65
customLegalizeToWOp
static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp, unsigned ExtOpc=ISD::ANY_EXTEND)
Definition: LoongArchISelLowering.cpp:786
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::EVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:154
llvm::ConstantPoolSDNode
Definition: SelectionDAGNodes.h:1883
LoongArch.h
llvm::CCState::AllocateReg
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
Definition: CallingConvLower.h:349
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::TargetLowering::LowerAsmOperandForConstraint
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Definition: TargetLowering.cpp:5171
llvm::RTLIB::getFPTOSINT
Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Definition: TargetLoweringBase.cpp:308
llvm::logicalview::LVAttributeKind::Zero
@ Zero
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::ISD::UMUL_LOHI
@ UMUL_LOHI
Definition: ISDOpcodes.h:251
llvm::LoongArchISD::DBAR
@ DBAR
Definition: LoongArchISelLowering.h:64
uint32_t
llvm::StackOffset
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
Definition: TypeSize.h:134
llvm::ISD::ArgFlagsTy
Definition: TargetCallingConv.h:27
llvm::SDValue::getOperand
const SDValue & getOperand(unsigned i) const
Definition: SelectionDAGNodes.h:1149
llvm::IRBuilderBase
Common base class shared among various IRBuilders.
Definition: IRBuilder.h:93
llvm::ilist_node_impl::getIterator
self_iterator getIterator()
Definition: ilist_node.h:82
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::ConstantSDNode::getSExtValue
int64_t getSExtValue() const
Definition: SelectionDAGNodes.h:1598
CC
auto CC
Definition: RISCVRedundantCopyElimination.cpp:79
llvm::ISD::SMUL_LOHI
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
llvm::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:5254
llvm::TargetMachine::shouldAssumeDSOLocal
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
Definition: TargetMachine.cpp:88
llvm::LoongArchTargetLowering::shouldExpandAtomicRMWInIR
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Definition: LoongArchISelLowering.cpp:2295
llvm::TargetLoweringBase::setTruncStoreAction
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
Definition: TargetLowering.h:2399
emitIntrinsicErrorMessage
static SDValue emitIntrinsicErrorMessage(SDValue Op, StringRef ErrorMsg, SelectionDAG &DAG)
Definition: LoongArchISelLowering.cpp:611
llvm::InlineAsm::Constraint_ZC
@ Constraint_ZC
Definition: InlineAsm.h:277
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::CCState::getPendingArgFlags
SmallVectorImpl< ISD::ArgFlagsTy > & getPendingArgFlags()
Definition: CallingConvLower.h:501
llvm::LoongArchISD::RET
@ RET
Definition: LoongArchISelLowering.h:31
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:715
llvm::MachineMemOperand::MOLoad
@ MOLoad
The memory access reads data.
Definition: MachineMemOperand.h:134
llvm::TargetLowering::C_RegisterClass
@ C_RegisterClass
Definition: TargetLowering.h:4556
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::ISD::XOR
@ XOR
Definition: ISDOpcodes.h:668
llvm::TargetLoweringBase::ArgListTy
std::vector< ArgListEntry > ArgListTy
Definition: TargetLowering.h:314
llvm::SelectionDAG::getTargetJumpTable
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:725
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::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::ISD::READ_REGISTER
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
Definition: ISDOpcodes.h:118
llvm::TargetLoweringBase::getTargetMachine
const TargetMachine & getTargetMachine() const
Definition: TargetLowering.h:349
llvm::TargetLowering::CallLoweringInfo::IsTailCall
bool IsTailCall
Definition: TargetLowering.h:4154
j
return j(j<< 16)
llvm::LoongArchABI::ABI_ILP32S
@ ABI_ILP32S
Definition: LoongArchBaseInfo.h:48
llvm::ISD::SETLT
@ SETLT
Definition: ISDOpcodes.h:1447
llvm::CCState::getFirstUnallocated
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
Definition: CallingConvLower.h:334
llvm::CCValAssign::isMemLoc
bool isMemLoc() const
Definition: CallingConvLower.h:144
llvm::TargetLoweringBase::IntrinsicInfo
Definition: TargetLowering.h:1048
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::BitVector::test
bool test(unsigned Idx) const
Definition: BitVector.h:454
performBITREV_WCombine
static SDValue performBITREV_WCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
Definition: LoongArchISelLowering.cpp:1291
llvm::LoongArchTargetLowering::isOffsetFoldingLegal
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
Definition: LoongArchISelLowering.cpp:201
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:2910
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:2377
llvm::GlobalAddressSDNode
Definition: SelectionDAGNodes.h:1759
llvm::Type::getIntNTy
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition: Type.cpp:243
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:623
llvm::LoongArchISD::NodeType
NodeType
Definition: LoongArchISelLowering.h:26
llvm::TargetLoweringBase::AtomicExpansionKind
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
Definition: TargetLowering.h:249
llvm::TargetLowering::MakeLibCallOptions::setTypeListBeforeSoften
MakeLibCallOptions & setTypeListBeforeSoften(ArrayRef< EVT > OpsVT, EVT RetVT, bool Value=true)
Definition: TargetLowering.h:4339
llvm::EVT::getScalarType
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition: ValueTypes.h:295
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
llvm::ISD::FCOS
@ FCOS
Definition: ISDOpcodes.h:916
llvm::ARCISD::RET
@ RET
Definition: ARCISelLowering.h:52
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:548
llvm::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
ArgFPR32s
const MCPhysReg ArgFPR32s[]
Definition: LoongArchISelLowering.cpp:1443
llvm::ISD::FSIN
@ FSIN
Definition: ISDOpcodes.h:915
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:469
ISDOpcodes.h
CC_LoongArchAssign2GRLen
static bool CC_LoongArchAssign2GRLen(unsigned GRLen, CCState &State, CCValAssign VA1, ISD::ArgFlagsTy ArgFlags1, unsigned ValNo2, MVT ValVT2, MVT LocVT2, ISD::ArgFlagsTy ArgFlags2)
Definition: LoongArchISelLowering.cpp:1453
llvm::TypeSize
Definition: TypeSize.h:435
llvm::LoongArchISD::BSTRPICK
@ BSTRPICK
Definition: LoongArchISelLowering.h:54
llvm::LoongArchISD::CTZ_W
@ CTZ_W
Definition: LoongArchISelLowering.h:51
LoongArchBaseInfo.h
unpackFromMemLoc
static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
Definition: LoongArchISelLowering.cpp:1714
llvm::CCState::AllocateStack
unsigned AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
Definition: CallingConvLower.h:423
llvm::TargetLoweringBase::Custom
@ Custom
Definition: TargetLowering.h:200
llvm::LoongArchABI::ABI_LP64D
@ ABI_LP64D
Definition: LoongArchBaseInfo.h:53
llvm::SelectionDAG::getTargetExternalSymbol
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.cpp:1889
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:48
llvm::CCState::getNextStackOffset
unsigned getNextStackOffset() const
getNextStackOffset - Return the next stack offset such that all stack slots satisfy their alignment r...
Definition: CallingConvLower.h:262
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:145
LoongArchMachineFunctionInfo.h
llvm::Function::getFunctionType
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:175
llvm::LoongArchISD::TAIL
@ TAIL
Definition: LoongArchISelLowering.h:32
llvm::TLSModel::Model
Model
Definition: CodeGen.h:42
llvm::TargetLoweringBase::AtomicExpansionKind::MaskedIntrinsic
@ MaskedIntrinsic
llvm::CSKYISD::TAIL
@ TAIL
Definition: CSKYISelLowering.h:32
llvm::EVT::getFloatingPointVT
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
Definition: ValueTypes.h:58
llvm::TargetLoweringBase::ZeroOrOneBooleanContent
@ ZeroOrOneBooleanContent
Definition: TargetLowering.h:232
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:614
llvm::LoongArchISD::SRL_W
@ SRL_W
Definition: LoongArchISelLowering.h:38
llvm::TargetLoweringBase::setLibcallName
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
Definition: TargetLowering.h:3147
llvm::ISD::VACOPY
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1082
llvm::TargetLowering::CallLoweringInfo::NoMerge
bool NoMerge
Definition: TargetLowering.h:4150
llvm::LoongArchISD::BREAK
@ BREAK
Definition: LoongArchISelLowering.h:63
llvm::MachineMemOperand::MOStore
@ MOStore
The memory access writes data.
Definition: MachineMemOperand.h:136
llvm::ISD::SRL_PARTS
@ SRL_PARTS
Definition: ISDOpcodes.h:751
llvm::ISD::UINT_TO_FP
@ UINT_TO_FP
Definition: ISDOpcodes.h:774
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:475
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
llvm::AtomicRMWInst::getValOperand
Value * getValOperand()
Definition: Instructions.h:870
llvm::TLSModel::InitialExec
@ InitialExec
Definition: CodeGen.h:45
llvm::InlineAsm::Constraint_ZB
@ Constraint_ZB
Definition: InlineAsm.h:276
llvm::M68kBeads::DReg
@ DReg
Definition: M68kBaseInfo.h:61
performSRLCombine
static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
Definition: LoongArchISelLowering.cpp:1031
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:2277
llvm::ISD::SETOGE
@ SETOGE
Definition: ISDOpcodes.h:1429
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition: MachineInstrBuilder.h:546
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:106
LoongArchMCTargetDesc.h
llvm::ISD::SHL
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:691
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
llvm::ISD::FREM
@ FREM
Definition: ISDOpcodes.h:394
llvm::MachinePointerInfo::getFixedStack
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Definition: MachineOperand.cpp:1019
llvm::CCValAssign::getReg
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
Definition: CallingConvLower.h:77
llvm::TargetLoweringBase::Expand
@ Expand
Definition: TargetLowering.h:198
llvm::CCValAssign::getValVT
MVT getValVT() const
Definition: CallingConvLower.h:141
LoongArchTargetMachine.h
llvm::CallingConv::Fast
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
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::TargetLoweringBase::setMaxAtomicSizeInBitsSupported
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Definition: TargetLowering.h:2533
llvm::ISD::SRL
@ SRL
Definition: ISDOpcodes.h:693
llvm::SelectionDAG::getRegisterMask
SDValue getRegisterMask(const uint32_t *RegMask)
Definition: SelectionDAG.cpp:2136
llvm::TargetLowering::getInlineAsmMemConstraint
virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const
Definition: TargetLowering.h:4656
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::TargetLoweringBase::setCondCodeAction
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
Definition: TargetLowering.h:2460
llvm::LoongArchISD::BSTRINS
@ BSTRINS
Definition: LoongArchISelLowering.h:53
llvm::ISD::CTTZ
@ CTTZ
Definition: ISDOpcodes.h:701
llvm::TargetLoweringBase::getRegClassFor
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
Definition: TargetLowering.h:896
llvm::MachineFunction::getDataLayout
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Definition: MachineFunction.cpp:285
insertDivByZeroTrap
static MachineBasicBlock * insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock *MBB)
Definition: LoongArchISelLowering.cpp:1323
llvm::MVT::isScalarInteger
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
Definition: MachineValueType.h:380
llvm::TargetLoweringBase::AtomicExpansionKind::None
@ None
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::TargetLowering::CallLoweringInfo::OutVals
SmallVector< SDValue, 32 > OutVals
Definition: TargetLowering.h:4167
RegName
#define RegName(no)
llvm::SDValue::getOpcode
unsigned getOpcode() const
Definition: SelectionDAGNodes.h:1137
llvm::StringSwitch::Default
R Default(T Value)
Definition: StringSwitch.h:183
llvm::RTLIB::getSINTTOFP
Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Definition: TargetLoweringBase.cpp:406
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:669
llvm::Module::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:399
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:45
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::TargetLowering::CallLoweringInfo::Callee
SDValue Callee
Definition: TargetLowering.h:4161
llvm::DataLayout::getPointerSizeInBits
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
Definition: DataLayout.h:412
llvm::MVT::i16
@ i16
Definition: MachineValueType.h:47
llvm::ISD::INTRINSIC_W_CHAIN
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition: ISDOpcodes.h:192
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1474
llvm::SelectionDAG::getMachineFunction
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:466
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::LoongArchRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: LoongArchRegisterInfo.cpp:81
llvm::ISD::VAARG
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1077
llvm::SelectionDAG::getExternalSymbol
SDValue getExternalSymbol(const char *Sym, EVT VT)
Definition: SelectionDAG.cpp:1872
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineFrameInfo::setFrameAddressIsTaken
void setFrameAddressIsTaken(bool T)
Definition: MachineFrameInfo.h:372
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
ArgGPRs
const MCPhysReg ArgGPRs[]
Definition: LoongArchISelLowering.cpp:1438
llvm::cl::desc
Definition: CommandLine.h:413
llvm::LoongArchISD::REVB_2W
@ REVB_2W
Definition: LoongArchISelLowering.h:58
llvm::AtomicRMWInst::UMax
@ UMax
*p = old >unsigned v ? old : v
Definition: Instructions.h:747
llvm::LoongArchISD::BITREV_4B
@ BITREV_4B
Definition: LoongArchISelLowering.h:59
llvm::TargetLoweringBase::AtomicExpansionKind::CmpXChg
@ CmpXChg
llvm::ISD::STACKSAVE
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1053
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:8005
llvm::MVT::f32
@ f32
Definition: MachineValueType.h:57
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692
llvm::FunctionType::getReturnType
Type * getReturnType() const
Definition: DerivedTypes.h:124
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::ISD::ROTR
@ ROTR
Definition: ISDOpcodes.h:695
llvm::AtomicCmpXchgInst
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:510
Debug.h
llvm::LoongArchTargetLowering::isFMAFasterThanFMulAndFAdd
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
Definition: LoongArchISelLowering.cpp:2427
llvm::TargetRegisterInfo::getCallPreservedMask
virtual const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const
Return a mask of call-preserved registers for the given calling convention on the current function.
Definition: TargetRegisterInfo.h:483
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:307
llvm::LoongArchISD::MOVFR2GR_S_LA64
@ MOVFR2GR_S_LA64
Definition: LoongArchISelLowering.h:45
llvm::TargetLowering::getConstraintType
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
Definition: TargetLowering.cpp:5109
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:356
llvm::ISD::CTPOP
@ CTPOP
Definition: ISDOpcodes.h:703
llvm::SelectionDAG::getSetCC
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
Definition: SelectionDAG.h:1133
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:7752
llvm::TargetLoweringBase::getTypeAction
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
Definition: TargetLowering.h:989
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103
llvm::Type::getPrimitiveSizeInBits
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition: Type.cpp:164
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:288
llvm::MVT::getIntegerVT
static MVT getIntegerVT(unsigned BitWidth)
Definition: MachineValueType.h:1240
llvm::TLSModel::LocalExec
@ LocalExec
Definition: CodeGen.h:46
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:39
llvm::LoongArchTargetLowering::CanLowerReturn
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
Definition: LoongArchISelLowering.cpp:2164
llvm::AtomicRMWInst::Max
@ Max
*p = old >signed v ? old : v
Definition: Instructions.h:743
llvm::LLT
Definition: LowLevelTypeImpl.h:39
llvm::LoongArchISD::CLZ_W
@ CLZ_W
Definition: LoongArchISelLowering.h:50