22#define DEBUG_TYPE "loongarch-isel"
23#define PASS_NAME "LoongArch DAG->DAG Pattern Instruction Selection"
37 if (
Node->isMachineOpcode()) {
38 LLVM_DEBUG(dbgs() <<
"== "; Node->dump(CurDAG); dbgs() <<
"\n");
45 unsigned Opcode =
Node->getOpcode();
46 MVT GRLenVT = Subtarget->getGRLenVT();
48 MVT VT =
Node->getSimpleValueType(0);
55 if (Imm == 0 && VT == GRLenVT) {
56 SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL,
57 LoongArch::R0, GRLenVT);
58 ReplaceNode(
Node, New.getNode());
62 SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, GRLenVT);
65 SDValue SDImm = CurDAG->getSignedTargetConstant(Inst.Imm,
DL, GRLenVT);
67 case LoongArch::LU12I_W:
68 Result = CurDAG->getMachineNode(Inst.Opc,
DL, GRLenVT, SDImm);
70 case LoongArch::ADDI_W:
72 case LoongArch::LU32I_D:
73 case LoongArch::LU52I_D:
74 Result = CurDAG->getMachineNode(Inst.Opc,
DL, GRLenVT, SrcReg, SDImm);
76 case LoongArch::BSTRINS_D:
77 Result = CurDAG->getMachineNode(
78 Inst.Opc,
DL, GRLenVT,
80 CurDAG->getSignedTargetConstant(Inst.Imm >> 32, DL, GRLenVT),
81 CurDAG->getTargetConstant(Inst.Imm & 0xFF, DL, GRLenVT)});
89 ReplaceNode(
Node, Result);
93 SDValue Imm = CurDAG->getTargetConstant(0,
DL, GRLenVT);
95 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
97 Subtarget->is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
98 ReplaceNode(
Node, CurDAG->getMachineNode(ADDIOp,
DL, VT, TFI, Imm));
104 CurDAG->RemoveDeadNode(
Node);
113 APInt SplatValue, SplatUndef;
114 unsigned SplatBitSize;
121 if (!Subtarget->hasExtLSX() || (!Is128Vec && !Is256Vec))
127 switch (SplatBitSize) {
131 Op = Is256Vec ? LoongArch::PseudoXVREPLI_B : LoongArch::PseudoVREPLI_B;
134 Op = Is256Vec ? LoongArch::PseudoXVREPLI_H : LoongArch::PseudoVREPLI_H;
137 Op = Is256Vec ? LoongArch::PseudoXVREPLI_W : LoongArch::PseudoVREPLI_W;
140 Op = Is256Vec ? LoongArch::PseudoXVREPLI_D : LoongArch::PseudoVREPLI_D;
149 SDValue Imm = CurDAG->getTargetConstant(Val,
DL, EleType);
150 Res = CurDAG->getMachineNode(
Op,
DL, ResTy, Imm);
151 ReplaceNode(
Node, Res);
164 std::vector<SDValue> &OutOps) {
167 CurDAG->getTargetConstant(0,
SDLoc(
Op), Subtarget->getGRLenVT());
168 switch (ConstraintID) {
178 if (
CurDAG->isBaseWithConstantOffset(
Op)) {
192 if (
CurDAG->isBaseWithConstantOffset(
Op)) {
203 OutOps.push_back(
Base);
213 CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getGRLenVT());
233 Base =
CurDAG->getRegister(LoongArch::R0, VT);
252 if (
CurDAG->isBaseWithConstantOffset(Addr)) {
274 const APInt &AndMask =
N->getConstantOperandAPInt(1);
282 ShAmt =
N.getOperand(0);
290 ShAmt =
N.getOperand(0);
299 uint64_t msb =
N.getConstantOperandVal(1), lsb =
N.getConstantOperandVal(2);
300 if (lsb == 0 &&
Log2_32(ShiftWidth) <= msb + 1) {
301 ShAmt =
N.getOperand(0);
306 uint64_t Imm =
N.getConstantOperandVal(0);
309 if (Imm != 0 && Imm % ShiftWidth == 0) {
311 EVT VT =
N.getValueType();
313 CurDAG->getCopyFromReg(
CurDAG->getEntryNode(),
DL, LoongArch::R0, VT);
314 unsigned NegOpc = VT == MVT::i64 ? LoongArch::SUB_D : LoongArch::SUB_W;
316 CurDAG->getMachineNode(NegOpc,
DL, VT, Zero,
N.getOperand(1));
329 Val =
N.getOperand(0);
333 N.getConstantOperandVal(1) < UINT64_C(0X1F) &&
334 N.getConstantOperandVal(2) == UINT64_C(0)) {
338 MVT VT =
N.getSimpleValueType();
350 if (
C &&
C->getZExtValue() == UINT64_C(0xFFFFFFFF)) {
351 Val =
N.getOperand(0);
355 MVT VT =
N.getSimpleValueType();
357 if (
CurDAG->MaskedValueIsZero(
N, Mask)) {
366 unsigned MinSizeInBits)
const {
367 if (!Subtarget->hasExtLSX())
375 APInt SplatValue, SplatUndef;
376 unsigned SplatBitSize;
379 if (!
Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
380 MinSizeInBits,
false))
388template <
unsigned ImmBitSize,
bool IsSigned>
391 EVT EltTy =
N->getValueType(0).getVectorElementType();
393 if (
N->getOpcode() == ISD::BITCAST)
394 N =
N->getOperand(0);
399 SplatVal =
CurDAG->getSignedTargetConstant(
403 if (!IsSigned && ImmValue.
isIntN(ImmBitSize)) {
405 Subtarget->getGRLenVT());
416 EVT EltTy =
N->getValueType(0).getVectorElementType();
418 if (
N->getOpcode() == ISD::BITCAST)
419 N =
N->getOperand(0);
423 int32_t
Log2 = (~ImmValue).exactLogBase2();
437 EVT EltTy =
N->getValueType(0).getVectorElementType();
439 if (
N->getOpcode() == ISD::BITCAST)
440 N =
N->getOperand(0);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
int32_t exactLogBase2() const
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
int64_t getSExtValue() const
Get sign extended value.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
uint64_t getZExtValue() const
int64_t getSExtValue() const
FunctionPass class - This class is used to implement most global optimizations.
LoongArchDAGToDAGISelLegacy(LoongArchTargetMachine &TM, CodeGenOptLevel OptLevel)
bool selectNonFIBaseAddr(SDValue Addr, SDValue &Base)
bool selectSExti32(SDValue N, SDValue &Val)
bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
bool selectVSplatUimmPow2(SDValue N, SDValue &SplatImm) const
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt)
bool selectZExti32(SDValue N, SDValue &Val)
bool SelectAddrRegImm12(SDValue Addr, SDValue &Base, SDValue &Offset)
bool SelectAddrConstant(SDValue Addr, SDValue &Base, SDValue &Offset)
bool selectVSplat(SDNode *N, APInt &Imm, unsigned MinSizeInBits) const
bool selectVSplatImm(SDValue N, SDValue &SplatVal)
bool selectVSplatUimmInvPow2(SDValue N, SDValue &SplatImm) const
bool SelectBaseAddr(SDValue Addr, SDValue &Base)
bool is128BitVector() const
Return true if this is a 128-bit vector type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
An SDNode that represents everything that will be needed to construct a MachineInstr.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
const SDValue & getOperand(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
SelectionDAGISelLegacy(char &ID, std::unique_ptr< SelectionDAGISel > S)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
InstSeq generateInstSeq(int64_t Val)
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
CodeGenOptLevel
Code generation optimization level.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
FunctionPass * createLoongArchISelDag(LoongArchTargetMachine &TM, CodeGenOptLevel OptLevel)
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
unsigned Log2(Align A)
Returns the log2 of the alignment.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
EVT getVectorElementType() const
Given a vector type, return the type of each element.