21#define DEBUG_TYPE "loongarch-isel"
22#define PASS_NAME "LoongArch DAG->DAG Pattern Instruction Selection"
30 if (Node->isMachineOpcode()) {
38 unsigned Opcode = Node->getOpcode();
39 MVT GRLenVT = Subtarget->getGRLenVT();
41 MVT VT = Node->getSimpleValueType(0);
47 int64_t Imm = cast<ConstantSDNode>(Node)->getSExtValue();
48 if (Imm == 0 && VT == GRLenVT) {
49 SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL,
50 LoongArch::R0, GRLenVT);
51 ReplaceNode(Node, New.getNode());
55 SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, GRLenVT);
58 SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm,
DL, GRLenVT);
59 if (Inst.Opc == LoongArch::LU12I_W)
60 Result = CurDAG->getMachineNode(LoongArch::LU12I_W,
DL, GRLenVT, SDImm);
62 Result = CurDAG->getMachineNode(Inst.Opc,
DL, GRLenVT, SrcReg, SDImm);
66 ReplaceNode(Node, Result);
70 SDValue Imm = CurDAG->getTargetConstant(0,
DL, GRLenVT);
71 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
72 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
74 Subtarget->is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
75 ReplaceNode(Node, CurDAG->getMachineNode(ADDIOp,
DL, VT, TFI, Imm));
86 const SDValue &Op,
unsigned ConstraintID, std::vector<SDValue> &OutOps) {
90 switch (ConstraintID) {
95 Base = Op.getOperand(0);
103 Base = Op.getOperand(0);
118 Base = Op.getOperand(0);
125 OutOps.push_back(
Base);
133 if (
auto *FIN = dyn_cast<FrameIndexSDNode>(
Addr))
145 MVT VT =
Addr.getSimpleValueType();
147 if (!isa<ConstantSDNode>(
Addr))
152 int64_t CVal = cast<ConstantSDNode>(
Addr)->getSExtValue();
153 if (!isInt<12>(CVal))
162 if (isa<FrameIndexSDNode>(
Addr))
173 if (
N.getOpcode() ==
ISD::AND && isa<ConstantSDNode>(
N.getOperand(1))) {
174 const APInt &AndMask =
N->getConstantOperandAPInt(1);
182 ShAmt =
N.getOperand(0);
190 ShAmt =
N.getOperand(0);
197 assert(isa<ConstantSDNode>(
N.getOperand(1)) &&
"Illegal msb operand!");
198 assert(isa<ConstantSDNode>(
N.getOperand(2)) &&
"Illegal lsb operand!");
199 uint64_t msb =
N.getConstantOperandVal(1), lsb =
N.getConstantOperandVal(2);
200 if (lsb == 0 &&
Log2_32(ShiftWidth) <= msb + 1) {
201 ShAmt =
N.getOperand(0);
205 isa<ConstantSDNode>(
N.getOperand(0))) {
206 uint64_t Imm =
N.getConstantOperandVal(0);
209 if (Imm != 0 && Imm % ShiftWidth == 0) {
211 EVT VT =
N.getValueType();
214 unsigned NegOpc = VT ==
MVT::i64 ? LoongArch::SUB_D : LoongArch::SUB_W;
228 cast<VTSDNode>(
N.getOperand(1))->getVT() ==
MVT::i32) {
229 Val =
N.getOperand(0);
233 N.getConstantOperandVal(1) < UINT64_C(0X1F) &&
234 N.getConstantOperandVal(2) == UINT64_C(0)) {
238 MVT VT =
N.getSimpleValueType();
249 auto *
C = dyn_cast<ConstantSDNode>(
N.getOperand(1));
250 if (
C &&
C->getZExtValue() == UINT64_C(0xFFFFFFFF)) {
251 Val =
N.getOperand(0);
255 MVT VT =
N.getSimpleValueType();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu AMDGPU Register Bank Select
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
unsigned getBitWidth() const
Return the number of bits in the APInt.
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.
uint64_t getZExtValue() const
int64_t getSExtValue() const
FunctionPass class - This class is used to implement most global optimizations.
bool selectNonFIBaseAddr(SDValue Addr, SDValue &Base)
bool selectSExti32(SDValue N, SDValue &Val)
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt)
bool selectZExti32(SDValue N, SDValue &Val)
bool SelectAddrConstant(SDValue Addr, SDValue &Base, SDValue &Offset)
bool SelectBaseAddr(SDValue Addr, SDValue &Base)
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
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.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
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),...
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
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.
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
#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.
InstSeq generateInstSeq(int64_t Val)
This is an optimization pass for GlobalISel generic memory operations.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
FunctionPass * createLoongArchISelDag(LoongArchTargetMachine &TM)
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
This struct is a compact representation of a valid (non-zero power of two) alignment.