[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVInstrInfo.h
blob7e1d3f31180650dad56a6323ea41b983d90a04ea
1 //===-- RISCVInstrInfo.h - RISC-V Instruction Information -------*- C++ -*-===//
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 contains the RISC-V implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
14 #define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
16 #include "RISCVRegisterInfo.h"
17 #include "llvm/CodeGen/TargetInstrInfo.h"
18 #include "llvm/IR/DiagnosticInfo.h"
20 #define GET_INSTRINFO_HEADER
21 #define GET_INSTRINFO_OPERAND_ENUM
22 #include "RISCVGenInstrInfo.inc"
24 namespace llvm {
26 class RISCVSubtarget;
28 static const MachineMemOperand::Flags MONontemporalBit0 =
29 MachineMemOperand::MOTargetFlag1;
30 static const MachineMemOperand::Flags MONontemporalBit1 =
31 MachineMemOperand::MOTargetFlag2;
33 namespace RISCVCC {
35 enum CondCode {
36 COND_EQ,
37 COND_NE,
38 COND_LT,
39 COND_GE,
40 COND_LTU,
41 COND_GEU,
42 COND_INVALID
45 CondCode getOppositeBranchCondition(CondCode);
46 unsigned getBrCond(CondCode CC);
48 } // end of namespace RISCVCC
50 class RISCVInstrInfo : public RISCVGenInstrInfo {
52 public:
53 explicit RISCVInstrInfo(RISCVSubtarget &STI);
55 MCInst getNop() const override;
56 const MCInstrDesc &getBrCond(RISCVCC::CondCode CC) const;
58 unsigned isLoadFromStackSlot(const MachineInstr &MI,
59 int &FrameIndex) const override;
60 unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex,
61 unsigned &MemBytes) const override;
62 unsigned isStoreToStackSlot(const MachineInstr &MI,
63 int &FrameIndex) const override;
64 unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex,
65 unsigned &MemBytes) const override;
67 void copyPhysRegVector(MachineBasicBlock &MBB,
68 MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
69 MCRegister DstReg, MCRegister SrcReg, bool KillSrc,
70 unsigned Opc, unsigned NF = 1) const;
71 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
72 const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg,
73 bool KillSrc) const override;
75 void storeRegToStackSlot(MachineBasicBlock &MBB,
76 MachineBasicBlock::iterator MBBI, Register SrcReg,
77 bool IsKill, int FrameIndex,
78 const TargetRegisterClass *RC,
79 const TargetRegisterInfo *TRI,
80 Register VReg) const override;
82 void loadRegFromStackSlot(MachineBasicBlock &MBB,
83 MachineBasicBlock::iterator MBBI, Register DstReg,
84 int FrameIndex, const TargetRegisterClass *RC,
85 const TargetRegisterInfo *TRI,
86 Register VReg) const override;
88 using TargetInstrInfo::foldMemoryOperandImpl;
89 MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
90 ArrayRef<unsigned> Ops,
91 MachineBasicBlock::iterator InsertPt,
92 int FrameIndex,
93 LiveIntervals *LIS = nullptr,
94 VirtRegMap *VRM = nullptr) const override;
96 // Materializes the given integer Val into DstReg.
97 void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
98 const DebugLoc &DL, Register DstReg, uint64_t Val,
99 MachineInstr::MIFlag Flag = MachineInstr::NoFlags,
100 bool DstRenamable = false, bool DstIsDead = false) const;
102 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
104 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
105 MachineBasicBlock *&FBB,
106 SmallVectorImpl<MachineOperand> &Cond,
107 bool AllowModify) const override;
109 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
110 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
111 const DebugLoc &dl,
112 int *BytesAdded = nullptr) const override;
114 void insertIndirectBranch(MachineBasicBlock &MBB,
115 MachineBasicBlock &NewDestBB,
116 MachineBasicBlock &RestoreBB, const DebugLoc &DL,
117 int64_t BrOffset, RegScavenger *RS) const override;
119 unsigned removeBranch(MachineBasicBlock &MBB,
120 int *BytesRemoved = nullptr) const override;
122 bool
123 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
125 bool optimizeCondBranch(MachineInstr &MI) const override;
127 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
129 bool isBranchOffsetInRange(unsigned BranchOpc,
130 int64_t BrOffset) const override;
132 bool analyzeSelect(const MachineInstr &MI,
133 SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
134 unsigned &FalseOp, bool &Optimizable) const override;
136 MachineInstr *optimizeSelect(MachineInstr &MI,
137 SmallPtrSetImpl<MachineInstr *> &SeenMIs,
138 bool) const override;
140 bool isAsCheapAsAMove(const MachineInstr &MI) const override;
142 std::optional<DestSourcePair>
143 isCopyInstrImpl(const MachineInstr &MI) const override;
145 bool verifyInstruction(const MachineInstr &MI,
146 StringRef &ErrInfo) const override;
148 bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg,
149 const MachineInstr &AddrI,
150 ExtAddrMode &AM) const override;
152 MachineInstr *emitLdStWithAddr(MachineInstr &MemI,
153 const ExtAddrMode &AM) const override;
155 bool getMemOperandsWithOffsetWidth(
156 const MachineInstr &MI, SmallVectorImpl<const MachineOperand *> &BaseOps,
157 int64_t &Offset, bool &OffsetIsScalable, unsigned &Width,
158 const TargetRegisterInfo *TRI) const override;
160 bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,
161 int64_t Offset1, bool OffsetIsScalable1,
162 ArrayRef<const MachineOperand *> BaseOps2,
163 int64_t Offset2, bool OffsetIsScalable2,
164 unsigned ClusterSize,
165 unsigned NumBytes) const override;
167 bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,
168 const MachineOperand *&BaseOp,
169 int64_t &Offset, unsigned &Width,
170 const TargetRegisterInfo *TRI) const;
172 bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
173 const MachineInstr &MIb) const override;
176 std::pair<unsigned, unsigned>
177 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
179 ArrayRef<std::pair<unsigned, const char *>>
180 getSerializableDirectMachineOperandTargetFlags() const override;
182 // Return true if the function can safely be outlined from.
183 bool isFunctionSafeToOutlineFrom(MachineFunction &MF,
184 bool OutlineFromLinkOnceODRs) const override;
186 // Return true if MBB is safe to outline from, and return any target-specific
187 // information in Flags.
188 bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
189 unsigned &Flags) const override;
191 bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
193 // Calculate target-specific information for a set of outlining candidates.
194 std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(
195 std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
197 // Return if/how a given MachineInstr should be outlined.
198 virtual outliner::InstrType
199 getOutliningTypeImpl(MachineBasicBlock::iterator &MBBI,
200 unsigned Flags) const override;
202 // Insert a custom frame for outlined functions.
203 void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
204 const outliner::OutlinedFunction &OF) const override;
206 // Insert a call to an outlined function into a given basic block.
207 MachineBasicBlock::iterator
208 insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
209 MachineBasicBlock::iterator &It, MachineFunction &MF,
210 outliner::Candidate &C) const override;
212 std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,
213 Register Reg) const override;
215 bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,
216 unsigned &SrcOpIdx2) const override;
217 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
218 unsigned OpIdx1,
219 unsigned OpIdx2) const override;
221 MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,
222 LiveIntervals *LIS) const override;
224 // MIR printer helper function to annotate Operands with a comment.
225 std::string
226 createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op,
227 unsigned OpIdx,
228 const TargetRegisterInfo *TRI) const override;
230 void getVLENFactoredAmount(
231 MachineFunction &MF, MachineBasicBlock &MBB,
232 MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg,
233 int64_t Amount, MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;
235 bool useMachineCombiner() const override { return true; }
237 MachineTraceStrategy getMachineCombinerTraceStrategy() const override;
239 bool
240 getMachineCombinerPatterns(MachineInstr &Root,
241 SmallVectorImpl<MachineCombinerPattern> &Patterns,
242 bool DoRegPressureReduce) const override;
244 void
245 finalizeInsInstrs(MachineInstr &Root, MachineCombinerPattern &P,
246 SmallVectorImpl<MachineInstr *> &InsInstrs) const override;
248 void genAlternativeCodeSequence(
249 MachineInstr &Root, MachineCombinerPattern Pattern,
250 SmallVectorImpl<MachineInstr *> &InsInstrs,
251 SmallVectorImpl<MachineInstr *> &DelInstrs,
252 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override;
254 bool hasReassociableSibling(const MachineInstr &Inst,
255 bool &Commuted) const override;
257 bool isAssociativeAndCommutative(const MachineInstr &Inst,
258 bool Invert) const override;
260 std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;
262 ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>
263 getSerializableMachineMemOperandTargetFlags() const override;
265 protected:
266 const RISCVSubtarget &STI;
268 private:
269 unsigned getInstBundleLength(const MachineInstr &MI) const;
272 namespace RISCV {
274 // Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
275 bool isSEXT_W(const MachineInstr &MI);
276 bool isZEXT_W(const MachineInstr &MI);
277 bool isZEXT_B(const MachineInstr &MI);
279 // Returns true if the given MI is an RVV instruction opcode for which we may
280 // expect to see a FrameIndex operand.
281 bool isRVVSpill(const MachineInstr &MI);
283 std::optional<std::pair<unsigned, unsigned>>
284 isRVVSpillForZvlsseg(unsigned Opcode);
286 bool isFaultFirstLoad(const MachineInstr &MI);
288 // Implemented in RISCVGenInstrInfo.inc
289 int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
291 // Return true if both input instructions have equal rounding mode. If at least
292 // one of the instructions does not have rounding mode, false will be returned.
293 bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);
295 // If \p Opcode is a .vx vector instruction, returns the lower number of bits
296 // that are used from the scalar .x operand for a given \p Log2SEW. Otherwise
297 // returns null.
298 std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode,
299 unsigned Log2SEW);
301 // Returns the MC opcode of RVV pseudo instruction.
302 unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode);
304 // Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
305 static constexpr int64_t VLMaxSentinel = -1LL;
307 // Mask assignments for floating-point
308 static constexpr unsigned FPMASK_Negative_Infinity = 0x001;
309 static constexpr unsigned FPMASK_Negative_Normal = 0x002;
310 static constexpr unsigned FPMASK_Negative_Subnormal = 0x004;
311 static constexpr unsigned FPMASK_Negative_Zero = 0x008;
312 static constexpr unsigned FPMASK_Positive_Zero = 0x010;
313 static constexpr unsigned FPMASK_Positive_Subnormal = 0x020;
314 static constexpr unsigned FPMASK_Positive_Normal = 0x040;
315 static constexpr unsigned FPMASK_Positive_Infinity = 0x080;
316 static constexpr unsigned FPMASK_Signaling_NaN = 0x100;
317 static constexpr unsigned FPMASK_Quiet_NaN = 0x200;
318 } // namespace RISCV
320 namespace RISCVVPseudosTable {
322 struct PseudoInfo {
323 uint16_t Pseudo;
324 uint16_t BaseInstr;
327 #define GET_RISCVVPseudosTable_DECL
328 #include "RISCVGenSearchableTables.inc"
330 } // end namespace RISCVVPseudosTable
332 } // end namespace llvm
333 #endif