LLVM  16.0.0git
LoongArchISelDAGToDAG.cpp
Go to the documentation of this file.
1 //=- LoongArchISelDAGToDAG.cpp - A dag to dag inst selector for LoongArch -===//
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 an instruction selector for the LoongArch target.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "LoongArchISelDAGToDAG.h"
14 #include "LoongArchISelLowering.h"
17 #include "llvm/Support/KnownBits.h"
18 
19 using namespace llvm;
20 
21 #define DEBUG_TYPE "loongarch-isel"
22 
24  // If we have a custom node, we have already selected.
25  if (Node->isMachineOpcode()) {
26  LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
27  Node->setNodeId(-1);
28  return;
29  }
30 
31  // Instruction Selection not handled by the auto-generated tablegen selection
32  // should be handled here.
33  unsigned Opcode = Node->getOpcode();
34  MVT GRLenVT = Subtarget->getGRLenVT();
35  SDLoc DL(Node);
36  MVT VT = Node->getSimpleValueType(0);
37 
38  switch (Opcode) {
39  default:
40  break;
41  case ISD::Constant: {
42  int64_t Imm = cast<ConstantSDNode>(Node)->getSExtValue();
43  if (Imm == 0 && VT == GRLenVT) {
45  LoongArch::R0, GRLenVT);
46  ReplaceNode(Node, New.getNode());
47  return;
48  }
49  SDNode *Result = nullptr;
50  SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, GRLenVT);
51  // The instructions in the sequence are handled here.
53  SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, GRLenVT);
54  if (Inst.Opc == LoongArch::LU12I_W)
55  Result = CurDAG->getMachineNode(LoongArch::LU12I_W, DL, GRLenVT, SDImm);
56  else
57  Result = CurDAG->getMachineNode(Inst.Opc, DL, GRLenVT, SrcReg, SDImm);
58  SrcReg = SDValue(Result, 0);
59  }
60 
61  ReplaceNode(Node, Result);
62  return;
63  }
64  case ISD::FrameIndex: {
65  SDValue Imm = CurDAG->getTargetConstant(0, DL, GRLenVT);
66  int FI = cast<FrameIndexSDNode>(Node)->getIndex();
67  SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
68  unsigned ADDIOp =
69  Subtarget->is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
70  ReplaceNode(Node, CurDAG->getMachineNode(ADDIOp, DL, VT, TFI, Imm));
71  return;
72  }
73  // TODO: Add selection nodes needed later.
74  }
75 
76  // Select the default instruction.
77  SelectCode(Node);
78 }
79 
81  const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
82  switch (ConstraintID) {
83  default:
84  llvm_unreachable("unexpected asm memory constraint");
85  // Reg+Reg addressing.
87  OutOps.push_back(Op.getOperand(0));
88  OutOps.push_back(Op.getOperand(1));
89  return false;
90  // Reg+simm12 addressing.
92  SDValue Base = Op;
93  SDValue Offset =
94  CurDAG->getTargetConstant(0, SDLoc(Op), Subtarget->getGRLenVT());
96  ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op.getOperand(1));
97  if (isIntN(12, CN->getSExtValue())) {
98  Base = Op.getOperand(0);
99  Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Op),
100  Op.getValueType());
101  }
102  }
103  OutOps.push_back(Base);
104  OutOps.push_back(Offset);
105  return false;
106  }
108  OutOps.push_back(Op);
109  // No offset.
110  return false;
111  // Reg+(simm14<<2) addressing.
113  SDValue Base = Op;
114  SDValue Offset =
115  CurDAG->getTargetConstant(0, SDLoc(Op), Subtarget->getGRLenVT());
117  ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op.getOperand(1));
118  if (isIntN(16, CN->getSExtValue()) &&
119  isAligned(Align(4ULL), CN->getZExtValue())) {
120  Base = Op.getOperand(0);
121  Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Op),
122  Op.getValueType());
123  }
124  }
125  OutOps.push_back(Base);
126  OutOps.push_back(Offset);
127  return false;
128  }
129  }
130  return true;
131 }
132 
134  // If this is FrameIndex, select it directly. Otherwise just let it get
135  // selected to a register independently.
136  if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr))
137  Base =
138  CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getGRLenVT());
139  else
140  Base = Addr;
141  return true;
142 }
143 
145  // If this is FrameIndex, don't select it.
146  if (isa<FrameIndexSDNode>(Addr))
147  return false;
148  Base = Addr;
149  return true;
150 }
151 
153  SDValue &ShAmt) {
154  // Shift instructions on LoongArch only read the lower 5 or 6 bits of the
155  // shift amount. If there is an AND on the shift amount, we can bypass it if
156  // it doesn't affect any of those bits.
157  if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) {
158  const APInt &AndMask = N->getConstantOperandAPInt(1);
159 
160  // Since the max shift amount is a power of 2 we can subtract 1 to make a
161  // mask that covers the bits needed to represent all shift amounts.
162  assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!");
163  APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1);
164 
165  if (ShMask.isSubsetOf(AndMask)) {
166  ShAmt = N.getOperand(0);
167  return true;
168  }
169 
170  // SimplifyDemandedBits may have optimized the mask so try restoring any
171  // bits that are known zero.
172  KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0));
173  if (ShMask.isSubsetOf(AndMask | Known.Zero)) {
174  ShAmt = N.getOperand(0);
175  return true;
176  }
177  } else if (N.getOpcode() == LoongArchISD::BSTRPICK) {
178  // Similar to the above AND, if there is a BSTRPICK on the shift amount, we
179  // can bypass it.
180  assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!");
181  assert(isa<ConstantSDNode>(N.getOperand(1)) && "Illegal msb operand!");
182  assert(isa<ConstantSDNode>(N.getOperand(2)) && "Illegal lsb operand!");
183  uint64_t msb = N.getConstantOperandVal(1), lsb = N.getConstantOperandVal(2);
184  if (lsb == 0 && Log2_32(ShiftWidth) <= msb + 1) {
185  ShAmt = N.getOperand(0);
186  return true;
187  }
188  } else if (N.getOpcode() == ISD::SUB &&
189  isa<ConstantSDNode>(N.getOperand(0))) {
190  uint64_t Imm = N.getConstantOperandVal(0);
191  // If we are shifting by N-X where N == 0 mod Size, then just shift by -X to
192  // generate a NEG instead of a SUB of a constant.
193  if (Imm != 0 && Imm % ShiftWidth == 0) {
194  SDLoc DL(N);
195  EVT VT = N.getValueType();
196  SDValue Zero =
197  CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, LoongArch::R0, VT);
198  unsigned NegOpc = VT == MVT::i64 ? LoongArch::SUB_D : LoongArch::SUB_W;
199  MachineSDNode *Neg =
200  CurDAG->getMachineNode(NegOpc, DL, VT, Zero, N.getOperand(1));
201  ShAmt = SDValue(Neg, 0);
202  return true;
203  }
204  }
205 
206  ShAmt = N;
207  return true;
208 }
209 
211  if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
212  cast<VTSDNode>(N.getOperand(1))->getVT() == MVT::i32) {
213  Val = N.getOperand(0);
214  return true;
215  }
216  if (N.getOpcode() == LoongArchISD::BSTRPICK &&
217  N.getConstantOperandVal(1) < UINT64_C(0X1F) &&
218  N.getConstantOperandVal(2) == UINT64_C(0)) {
219  Val = N;
220  return true;
221  }
222  MVT VT = N.getSimpleValueType();
223  if (CurDAG->ComputeNumSignBits(N) > (VT.getSizeInBits() - 32)) {
224  Val = N;
225  return true;
226  }
227 
228  return false;
229 }
230 
232  if (N.getOpcode() == ISD::AND) {
233  auto *C = dyn_cast<ConstantSDNode>(N.getOperand(1));
234  if (C && C->getZExtValue() == UINT64_C(0xFFFFFFFF)) {
235  Val = N.getOperand(0);
236  return true;
237  }
238  }
239  MVT VT = N.getSimpleValueType();
241  if (CurDAG->MaskedValueIsZero(N, Mask)) {
242  Val = N;
243  return true;
244  }
245 
246  return false;
247 }
248 
249 // This pass converts a legalized DAG into a LoongArch-specific DAG, ready
250 // for instruction scheduling.
252  return new LoongArchDAGToDAGISel(TM);
253 }
llvm::ISD::SUB
@ SUB
Definition: ISDOpcodes.h:240
llvm::LoongArchDAGToDAGISel::SelectInlineAsmMemoryOperand
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
Definition: LoongArchISelDAGToDAG.cpp:80
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1582
llvm::isAligned
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition: Alignment.h:146
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::LoongArchMatInt::Inst
Definition: LoongArchMatInt.h:17
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1106
llvm::KnownBits::Zero
APInt Zero
Definition: KnownBits.h:24
llvm::MachineSDNode
An SDNode that represents everything that will be needed to construct a MachineInstr.
Definition: SelectionDAGNodes.h:2897
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:463
llvm::LoongArchSubtarget::is64Bit
bool is64Bit() const
Definition: LoongArchSubtarget.h:83
llvm::APInt::getBitWidth
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1431
llvm::InlineAsm::Constraint_k
@ Constraint_k
Definition: InlineAsm.h:258
llvm::SelectionDAG::isBaseWithConstantOffset
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
Definition: SelectionDAG.cpp:4709
llvm::isPowerOf2_32
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:458
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
KnownBits.h
llvm::SelectionDAG::getRegister
SDValue getRegister(unsigned Reg, EVT VT)
Definition: SelectionDAG.cpp:2121
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
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::SelectionDAG::getTargetFrameIndex
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:720
llvm::ISD::Constant
@ Constant
Definition: ISDOpcodes.h:76
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
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:34
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
LoongArchISelLowering.h
llvm::SelectionDAG::MaskedValueIsZero
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
Definition: SelectionDAG.cpp:2532
llvm::SelectionDAGISel::ReplaceNode
void ReplaceNode(SDNode *F, SDNode *T)
Replace all uses of F with T, then remove F from the DAG.
Definition: SelectionDAGISel.h:231
llvm::Log2_32
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:547
llvm::LoongArchDAGToDAGISel::SelectBaseAddr
bool SelectBaseAddr(SDValue Addr, SDValue &Base)
Definition: LoongArchISelDAGToDAG.cpp:133
llvm::APInt::getHighBitsSet
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition: APInt.h:279
llvm::ISD::AND
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:666
llvm::LoongArchDAGToDAGISel
Definition: LoongArchISelDAGToDAG.h:23
Align
uint64_t Align
Definition: ELFObjHandler.cpp:82
llvm::isIntN
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:427
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
llvm::InlineAsm::Constraint_m
@ Constraint_m
Definition: InlineAsm.h:259
uint64_t
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
llvm::LoongArchMatInt::generateInstSeq
InstSeq generateInstSeq(int64_t Val)
Definition: LoongArchMatInt.cpp:15
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:793
llvm::LoongArchDAGToDAGISel::selectShiftMask
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt)
Definition: LoongArchISelDAGToDAG.cpp:152
llvm::LoongArchTargetMachine
Definition: LoongArchTargetMachine.h:22
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MVT::getSizeInBits
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
Definition: MachineValueType.h:919
llvm::ConstantSDNode::getZExtValue
uint64_t getZExtValue() const
Definition: SelectionDAGNodes.h:1597
llvm::SelectionDAGISel::CurDAG
SelectionDAG * CurDAG
Definition: SelectionDAGISel.h:49
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::MVT
Machine Value Type.
Definition: MachineValueType.h:31
LoongArchISelDAGToDAG.h
llvm::LoongArchSubtarget::getGRLenVT
MVT getGRLenVT() const
Definition: LoongArchSubtarget.h:93
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm::MVT::i64
@ i64
Definition: MachineValueType.h:49
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::ConstantSDNode::getSExtValue
int64_t getSExtValue() const
Definition: SelectionDAGNodes.h:1598
llvm::InlineAsm::Constraint_ZC
@ Constraint_ZC
Definition: InlineAsm.h:277
llvm::LoongArchDAGToDAGISel::selectZExti32
bool selectZExti32(SDValue N, SDValue &Val)
Definition: LoongArchISelDAGToDAG.cpp:231
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
llvm::LoongArchDAGToDAGISel::Select
void Select(SDNode *Node) override
Main hook for targets to transform nodes into machine nodes.
Definition: LoongArchISelDAGToDAG.cpp:23
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::KnownBits
Definition: KnownBits.h:23
LoongArchMatInt.h
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:548
llvm::LoongArchISD::BSTRPICK
@ BSTRPICK
Definition: LoongArchISelLowering.h:54
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:48
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:145
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
llvm::InlineAsm::Constraint_ZB
@ Constraint_ZB
Definition: InlineAsm.h:276
LoongArchMCTargetDesc.h
llvm::LoongArchDAGToDAGISel::selectNonFIBaseAddr
bool selectNonFIBaseAddr(SDValue Addr, SDValue &Base)
Definition: LoongArchISelDAGToDAG.cpp:144
N
#define N
llvm::LoongArchDAGToDAGISel::selectSExti32
bool selectSExti32(SDValue N, SDValue &Val)
Definition: LoongArchISelDAGToDAG.cpp:210
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:669
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::SelectionDAG::ComputeNumSignBits
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
Definition: SelectionDAG.cpp:3935
llvm::createLoongArchISelDag
FunctionPass * createLoongArchISelDag(LoongArchTargetMachine &TM)
Definition: LoongArchISelDAGToDAG.cpp:251
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58