25#define DEBUG_TYPE "gi-combiner"
38 LLT DstTy =
MRI.getType(Dst);
39 LLT SrcTy =
MRI.getType(Src);
45 unsigned TruncWidth =
MRI.getType(Trunc->
getReg(0)).getScalarSizeInBits();
51 {TargetOpcode::G_SEXT_INREG, {DstTy, SrcTy}, {}, {TruncWidth}}))
55 B.buildSExtInReg(Dst, Src, TruncWidth);
92 LLT DstTy =
MRI.getType(Dst);
93 LLT SrcTy =
MRI.getType(Src);
126 LLT DstTy =
MRI.getType(Dst);
127 LLT SrcTy =
MRI.getType(Src);
146 if (!
MRI.hasOneNonDBGUse(Ext->
getReg(0)))
151 LLT DstTy =
MRI.getType(Dst);
152 LLT SrcTy =
MRI.getType(Src);
154 if (SrcTy == DstTy) {
188bool CombinerHelper::isCastFree(
unsigned Opcode,
LLT ToTy,
LLT FromTy)
const {
193 case TargetOpcode::G_ANYEXT:
194 case TargetOpcode::G_ZEXT:
196 case TargetOpcode::G_TRUNC:
209 if (!
MRI.hasOneNonDBGUse(
Select->getReg(0)))
213 LLT DstTy =
MRI.getType(Dst);
217 LLT SrcTy =
MRI.getType(TrueReg);
223 if (!isCastFree(Cast->
getOpcode(), DstTy, SrcTy))
227 auto True =
B.buildInstr(Cast->
getOpcode(), {DstTy}, {TrueReg});
228 auto False =
B.buildInstr(Cast->
getOpcode(), {DstTy}, {FalseReg});
229 B.buildSelect(Dst,
Cond, True, False);
243 LLT DstTy =
MRI.getType(Dst);
244 LLT SrcTy =
MRI.getType(Src);
246 if (!
MRI.hasOneNonDBGUse(Second->
getReg(0)))
252 if (Second->
getOpcode() == TargetOpcode::G_ZEXT) {
261 B.buildInstr(Second->
getOpcode(), {Dst}, {Src});
268 if (
First->getOpcode() == TargetOpcode::G_ANYEXT &&
270 if (Second->
getOpcode() == TargetOpcode::G_ZEXT) {
283 if (Second->
getOpcode() == TargetOpcode::G_ANYEXT &&
285 if (
First->getOpcode() == TargetOpcode::G_ZEXT) {
310 LLT DstTy =
MRI.getType(Dst);
314 LLT InputElemTy =
MRI.getType(BV->
getReg(0)).getElementType();
319 {TargetOpcode::G_BUILD_VECTOR, {DstTy, ElemTy}}) ||
321 !isCastFree(Cast->
getOpcode(), ElemTy, InputElemTy))
327 for (
unsigned I = 0;
I < Elements; ++
I) {
329 B.buildInstr(Cast->
getOpcode(), {ElemTy}, {BV->getSourceReg(I)});
333 B.buildBuildVector(Dst, Casts);
345 if (!
MRI.hasOneNonDBGUse(BinOp->
getReg(0)))
349 LLT DstTy =
MRI.getType(Dst);
356 auto LHS =
B.buildTrunc(DstTy, BinOp->
getLHSReg());
357 auto RHS =
B.buildTrunc(DstTy, BinOp->
getRHSReg());
358 B.buildInstr(BinOp->
getOpcode(), {Dst}, {LHS, RHS});
365 APInt &MatchInfo)
const {
376 case TargetOpcode::G_TRUNC: {
389 Other.getOpcode() == TargetOpcode::G_SEXT_INREG);
392 unsigned OtherWidth =
Other.getOperand(2).getImm();
398 if (RootWidth >= OtherWidth) {
406 MRI.replaceRegWith(Dst, OtherDst);
407 Observer.finishedChangingAllUsesOfReg();
413 B.buildSExtInReg(Dst, Src, RootWidth);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
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...
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.
const SmallVectorImpl< MachineOperand > & Cond
Class for arbitrary precision integers.
LLVM_ABI bool matchZextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine zext of trunc.
LLVM_ABI bool matchNonNegZext(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine zext nneg to sext.
LLVM_ABI const TargetLowering & getTargetLowering() const
LLVM_ABI bool matchSextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine sext of trunc.
LLVM_ABI bool matchTruncateOfExt(const MachineInstr &Root, const MachineInstr &ExtMI, BuildFnTy &MatchInfo) const
Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
LLVM_ABI bool matchExtOfExt(const MachineInstr &FirstMI, const MachineInstr &SecondMI, BuildFnTy &MatchInfo) const
LLVM_ABI LLVMContext & getContext() const
LLVM_ABI bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const
MachineRegisterInfo & MRI
LLVM_ABI bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const
LLVM_ABI bool matchNarrowBinop(const MachineInstr &TruncMI, const MachineInstr &BinopMI, BuildFnTy &MatchInfo) const
trunc (binop X, C) --> binop (trunc X, trunc C).
GISelChangeObserver & Observer
LLVM_ABI bool matchRedundantSextInReg(MachineInstr &Root, MachineInstr &Other, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchCastOfBuildVector(const MachineInstr &CastMI, const MachineInstr &BVMI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchCastOfInteger(const MachineInstr &CastMI, APInt &MatchInfo) const
LLVM_ABI bool matchCastOfSelect(const MachineInstr &Cast, const MachineInstr &SelectMI, BuildFnTy &MatchInfo) const
Represents a binary operation, i.e, x = y op z.
Register getLHSReg() const
Register getRHSReg() const
Represents a G_BUILD_VECTOR.
Register getSrcReg() const
Represents an integer-like extending operation.
Represents an integer-like extending or truncating operation.
unsigned getNumSources() const
Returns the number of source registers.
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
constexpr unsigned getScalarSizeInBits() const
LLT getScalarType() const
This is an important class for using LLVM in a threaded context.
Helper class to build MachineInstr.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
operand_type_match m_Reg()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
This is an optimization pass for GlobalISel generic memory operations.
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.
LLVM_ABI bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)
Check if DstReg can be replaced with SrcReg depending on the register constraints.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.