28#define DEBUG_TYPE "gi-combiner"
39 LLT DstTy =
MRI.getType(Dst);
71 std::optional<ValueAndVReg> MaybeIndex =
73 std::optional<APInt> IndexC = std::nullopt;
76 IndexC = MaybeIndex->Value;
110 std::optional<ValueAndVReg> MaybeIndex =
112 std::optional<APInt> IndexC = std::nullopt;
117 IndexC = MaybeIndex->Value;
128 std::optional<ValueAndVReg> MaybeInsertIndex =
131 if (MaybeInsertIndex && MaybeInsertIndex->Value != *IndexC) {
136 B.buildExtractVectorElement(Dst, Insert->getVectorReg(), Index);
166 if (!
MRI.hasOneNonDBGUse(Build->
getReg(0)) ||
226 if (!
MRI.hasOneNonDBGUse(Build->
getReg(0)) ||
234 std::optional<ValueAndVReg> MaybeIndex =
249 LLT DstTy =
MRI.getType(Dst);
257 B.buildTrunc(Dst, Build->
getSourceReg(MaybeIndex->Value.getZExtValue()));
298 unsigned Offset = Index.getZExtValue();
299 int SrcIdx = Mask[
Offset];
304 assert(Src1Type.
isVector() &&
"expected to extract from a vector");
309 LLT DstTy =
MRI.getType(Dst);
324 if (SrcIdx < (
int)LHSWidth) {
333 LLT NewVectorTy =
MRI.getType(NewVector);
337 {TargetOpcode::G_EXTRACT_VECTOR_ELT, {DstTy, NewVectorTy, IdxTy}}) ||
343 auto Idx =
B.buildConstant(IdxTy, SrcIdx);
344 B.buildExtractVectorElement(Dst, NewVector, Idx);
354 LLT DstTy =
MRI.getType(Dst);
355 Register Index = Insert->getIndexReg();
360 std::optional<ValueAndVReg> MaybeIndex =
363 if (MaybeIndex && MaybeIndex->Value.uge(DstTy.
getNumElements()) &&
373 GVScale *LHSVScale, *RHSVScale;
377 if (!
MRI.hasOneNonDBGUse(LHSVScale->
getReg(0)) ||
378 !
MRI.hasOneNonDBGUse(RHSVScale->
getReg(0)))
382 B.buildVScale(Dst, LHSVScale->
getSrc() + RHSVScale->
getSrc());
400 if (!
MRI.hasOneNonDBGUse(LHSVScale->
getReg(0)))
404 B.buildVScale(Dst, LHSVScale->
getSrc() * *MaybeRHS);
420 LLT DstTy =
MRI.getType(Dst);
422 if (!
MRI.hasOneNonDBGUse(RHSVScale->
getReg(0)) ||
427 auto VScale =
B.buildVScale(DstTy, -RHSVScale->
getSrc());
428 B.buildAdd(Dst, SubLHS, VScale, Flags);
446 LLT DstTy =
MRI.getType(Dst);
448 if (!
MRI.hasOneNonDBGUse(LHSVScale->
getReg(0)) ||
453 B.buildVScale(Dst, LHSVScale->
getSrc().
shl(*MaybeRHS));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This contains common combine transformations that may be used in a combine pass,or by the target else...
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Interface for Targets to specify which operations they can successfully select and how the others sho...
Implement a low-level type suitable for MachineInstr level instruction selection.
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
This file describes how to lower LLVM code to machine code.
Class for arbitrary precision integers.
APInt shl(unsigned shiftAmt) const
Left-shift function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM_ABI bool matchExtractVectorElementWithBuildVectorTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine extract vector element with a build vector trunc on the vector register.
LLVM_ABI const TargetLowering & getTargetLowering() const
LLVM_ABI bool matchExtractVectorElementWithDifferentIndices(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine extract vector element with a insert vector element on the vector register and different indi...
LLVM_ABI bool matchMulOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchAddOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchShlOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchExtractVectorElementWithShuffleVector(const MachineInstr &MI, const MachineInstr &MI2, BuildFnTy &MatchInfo) const
Combine extract vector element with a shuffle vector on the vector register.
LLVM_ABI bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const
MachineRegisterInfo & MRI
LLVM_ABI bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const
LLVM_ABI bool matchInsertVectorElementOOB(MachineInstr &MI) const
Combine insert vector element OOB.
LLVM_ABI bool matchSubOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchExtractVectorElement(MachineInstr &MI) const
Combine extract vector element.
LLVM_ABI bool matchExtractVectorElementWithBuildVector(const MachineInstr &MI, const MachineInstr &MI2, BuildFnTy &MatchInfo) const
Combine extract vector element with a build vector on the vector register.
Represents a G_BUILD_VECTOR_TRUNC.
Represents a G_BUILD_VECTOR.
Represents an insert vector element.
Register getSourceReg(unsigned I) const
Returns the I'th source register.
unsigned getNumSources() const
Returns the number of source registers.
Represents a G_SHUFFLE_VECTOR.
Register getSrc2Reg() const
Register getSrc1Reg() const
ArrayRef< int > getMask() const
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
Helper class to build MachineInstr.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
operand_type_match m_Reg()
MIFlagsRef m_MIFlags(uint32_t &Flags)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ADD, true > m_GAdd(const LHS &L, const RHS &R)
GInstrBind< GVScale > m_GVScale(GVScale *&Inst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_MUL, true > m_GMul(const LHS &L, const RHS &R)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI MachineInstr * getOpcodeDef(unsigned Opcode, Register Reg, const MachineRegisterInfo &MRI)
See if Reg is defined by an single def instruction that is Opcode.
LLVM_ABI std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
std::function< void(MachineIRBuilder &)> BuildFnTy
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
LLVM_ABI const APInt & getIConstantFromReg(Register VReg, const MachineRegisterInfo &MRI)
VReg is defined by a G_CONSTANT, return the corresponding value.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...