[llvm] GlobalISel: Migrate misc. CombinerHelper def checks to MIPatternMatch (PR #216671)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 17 02:44:43 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/216671
Replace getVRegDef + cast/opcode-check idioms across CombinerHelper
with mi_match, adding named instruction binders and operand-form matchers
as needed.
Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
>From 5696ae15d825614264a85dd119e7df128a67c962 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sun, 16 Aug 2026 21:49:54 +0200
Subject: [PATCH] GlobalISel: Migrate misc. CombinerHelper def checks to
MIPatternMatch
Replace getVRegDef + cast/opcode-check idioms across CombinerHelper
with mi_match, adding named instruction binders and operand-form matchers
as needed.
Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
---
.../llvm/CodeGen/GlobalISel/MIPatternMatch.h | 54 ++-
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 365 ++++++++++--------
.../GlobalISel/CombinerHelperCasts.cpp | 10 +-
.../GlobalISel/CombinerHelperVectorOps.cpp | 42 +-
4 files changed, 285 insertions(+), 186 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index e6c6f69d3e0a1..a4312d48ae5cf 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -480,13 +480,12 @@ struct ImplicitDefMatch {
inline ImplicitDefMatch m_GImplicitDef() { return ImplicitDefMatch(); }
-/// Matches a G_CONSTANT and binds the defining instruction. Unlike m_ICst, this
-/// returns the instruction (not the value) and does not look through vector
-/// splats.
-template <typename Class> struct GConstantMatch {
+/// Binds the defining instruction of \p Reg if it is a \p Class. Prefer the
+/// named helpers below so the opcode is spelled out at the call site.
+template <typename Class> struct GInstrBind {
Class *&Inst;
- GConstantMatch(Class *&Inst) : Inst(Inst) {}
+ GInstrBind(Class *&Inst) : Inst(Inst) {}
bool match(const MachineRegisterInfo &MRI, Register Reg) {
MachineInstr *TmpMI;
if (mi_match(Reg, MRI, m_MInstr(TmpMI))) {
@@ -499,8 +498,43 @@ template <typename Class> struct GConstantMatch {
}
};
-inline GConstantMatch<GConstant> m_GConstant(GConstant *&Inst) { return Inst; }
-inline GConstantMatch<const GConstant> m_GConstant(const GConstant *&Inst) {
+/// Match a literal G_CONSTANT instruction (no look-through of splats or
+/// copies).
+inline GInstrBind<GConstant> m_GConstant(GConstant *&Inst) { return Inst; }
+inline GInstrBind<const GConstant> m_GConstant(const GConstant *&Inst) {
+ return Inst;
+}
+
+/// Match a literal G_CONSTANT or G_FCONSTANT, binding its raw bits to \p Bits
+/// (the integer value, or the float reinterpreted as an integer).
+struct GConstantBitsMatch {
+ APInt &Bits;
+ bool match(const MachineRegisterInfo &MRI, Register Reg) {
+ MachineInstr *MI = MRI.getVRegDef(Reg);
+ if (MI->getOpcode() == TargetOpcode::G_CONSTANT) {
+ Bits = MI->getOperand(1).getCImm()->getValue();
+ return true;
+ }
+ if (MI->getOpcode() == TargetOpcode::G_FCONSTANT) {
+ Bits = MI->getOperand(1).getFPImm()->getValueAPF().bitcastToAPInt();
+ return true;
+ }
+ return false;
+ }
+};
+
+inline GConstantBitsMatch m_GConstantOrFConstantBits(APInt &Bits) {
+ return {Bits};
+}
+
+/// Instruction binders for ops with no operand-form matcher (constant-immediate
+/// or variadic-source ops).
+inline GInstrBind<GUnmerge> m_GUnmerge(GUnmerge *&Inst) { return Inst; }
+inline GInstrBind<GVScale> m_GVScale(GVScale *&Inst) { return Inst; }
+inline GInstrBind<GBuildVector> m_GBuildVector(GBuildVector *&Inst) {
+ return Inst;
+}
+inline GInstrBind<GConcatVectors> m_GConcatVectors(GConcatVectors *&Inst) {
return Inst;
}
@@ -624,6 +658,12 @@ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB> m_GSub(const LHS &L,
return BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB>(L, R);
}
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB>
+m_GSub(const LHS &L, const RHS &R, MIFlagsRef Flags) {
+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB>(L, R, Flags);
+}
+
template <typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, TargetOpcode::G_MUL, true>
m_GMul(const LHS &L, const RHS &R) {
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index b8f5f840d5cff..92e3e8e4c1d5b 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -261,7 +261,9 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
if (!MRI.hasOneNonDBGUse(OrigOp))
return false;
- MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp);
+ MachineInstr *OrigDef;
+ if (!mi_match(OrigOp, MRI, m_MInstr(OrigDef)))
+ return false;
// Even if only a single operand of the PHI is not guaranteed non-poison,
// moving freeze() backwards across a PHI can cause optimization issues for
// other users of that operand.
@@ -338,8 +340,9 @@ bool CombinerHelper::matchCombineConcatVectors(
// Then collect their operands in Ops.
for (const MachineOperand &MO : MI.uses()) {
Register Reg = MO.getReg();
- MachineInstr *Def = MRI.getVRegDef(Reg);
- assert(Def && "Operand not defined");
+ MachineInstr *Def;
+ if (!mi_match(Reg, MRI, m_MInstr(Def)))
+ return false;
if (!MRI.hasOneNonDBGUse(Reg))
return false;
switch (Def->getOpcode()) {
@@ -414,10 +417,10 @@ bool CombinerHelper::matchCombineBuildVectorOfBitcast(
GUnmerge *Unmerge = getOpcodeDef<GUnmerge>(BV.getSourceReg(0), MRI);
if (!Unmerge || Unmerge->getReg(0) != BV.getSourceReg(0))
return false;
- MachineInstr *BC = MRI.getVRegDef(Unmerge->getSourceReg());
- if (BC->getOpcode() != TargetOpcode::G_BITCAST)
+ Register BCSrc;
+ if (!mi_match(Unmerge->getSourceReg(), MRI, m_GBitcast(m_Reg(BCSrc))))
return false;
- LLT InputTy = MRI.getType(BC->getOperand(1).getReg());
+ LLT InputTy = MRI.getType(BCSrc);
unsigned Factor = Unmerge->getNumDefs();
if (!InputTy.isScalar() || BV.getNumSources() % Factor != 0)
return false;
@@ -431,8 +434,7 @@ bool CombinerHelper::matchCombineBuildVectorOfBitcast(
for (unsigned Idx = 0; Idx < BV.getNumSources(); Idx += Factor) {
GUnmerge *Unmerge = getOpcodeDef<GUnmerge>(BV.getSourceReg(Idx), MRI);
if (!all_of(iota_range<unsigned>(0, Factor, false), [&](unsigned J) {
- MachineInstr *Src = MRI.getVRegDef(BV.getSourceReg(Idx + J));
- if (Src->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
+ if (mi_match(BV.getSourceReg(Idx + J), MRI, m_GImplicitDef()))
return true;
return Unmerge && BV.getSourceReg(Idx + J) == Unmerge->getReg(J);
}))
@@ -440,11 +442,12 @@ bool CombinerHelper::matchCombineBuildVectorOfBitcast(
if (!Unmerge)
Ops.push_back(0);
else {
- MachineInstr *BC = MRI.getVRegDef(Unmerge->getSourceReg());
- if (BC->getOpcode() != TargetOpcode::G_BITCAST ||
- MRI.getType(BC->getOperand(1).getReg()) != InputTy)
+ Register BCSrc;
+ if (!mi_match(
+ Unmerge->getSourceReg(), MRI,
+ m_GBitcast(m_all_of(m_Reg(BCSrc), m_SpecificType(InputTy)))))
return false;
- Ops.push_back(BC->getOperand(1).getReg());
+ Ops.push_back(BCSrc);
}
}
@@ -502,11 +505,9 @@ void CombinerHelper::applyCombineShuffleToBuildVector(MachineInstr &MI) const {
bool CombinerHelper::matchCombineShuffleConcat(
MachineInstr &MI, SmallVector<Register> &Ops) const {
ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
- auto ConcatMI1 =
- dyn_cast<GConcatVectors>(MRI.getVRegDef(MI.getOperand(1).getReg()));
- auto ConcatMI2 =
- dyn_cast<GConcatVectors>(MRI.getVRegDef(MI.getOperand(2).getReg()));
- if (!ConcatMI1 || !ConcatMI2)
+ GConcatVectors *ConcatMI1, *ConcatMI2;
+ if (!mi_match(MI.getOperand(1).getReg(), MRI, m_GConcatVectors(ConcatMI1)) ||
+ !mi_match(MI.getOperand(2).getReg(), MRI, m_GConcatVectors(ConcatMI2)))
return false;
// Check that the sources of the Concat instructions have the same type
@@ -1285,7 +1286,9 @@ bool CombinerHelper::findPostIndexCandidate(GLoadStore &LdSt, Register &Addr,
return false;
MachineInstr *StoredValDef = getDefIgnoringCopies(LdSt.getReg(0), MRI);
- auto *PtrDef = MRI.getVRegDef(Ptr);
+ MachineInstr *PtrDef;
+ if (!mi_match(Ptr, MRI, m_MInstr(PtrDef)))
+ return false;
unsigned NumUsesChecked = 0;
for (auto &Use : MRI.use_nodbg_instructions(Ptr)) {
@@ -1310,7 +1313,9 @@ bool CombinerHelper::findPostIndexCandidate(GLoadStore &LdSt, Register &Addr,
continue;
// Make sure the offset calculation is before the potentially indexed op.
- MachineInstr *OffsetDef = MRI.getVRegDef(Offset);
+ MachineInstr *OffsetDef;
+ if (!mi_match(Offset, MRI, m_MInstr(OffsetDef)))
+ continue;
RematOffset = false;
if (!dominates(*OffsetDef, LdSt)) {
// If the offset however is just a G_CONSTANT, we can always just
@@ -1540,7 +1545,7 @@ bool CombinerHelper::matchCombineIndexedLoadStore(
void CombinerHelper::applyCombineIndexedLoadStore(
MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo) const {
- MachineInstr &AddrDef = *MRI.getUniqueVRegDef(MatchInfo.Addr);
+ MachineInstr &AddrDef = *MRI.getVRegDef(MatchInfo.Addr);
unsigned Opcode = MI.getOpcode();
bool IsStore = Opcode == TargetOpcode::G_STORE;
unsigned NewOpcode = getIndexedOpc(Opcode);
@@ -1946,8 +1951,8 @@ bool CombinerHelper::matchShiftImmedChain(MachineInstr &MI,
if (!MaybeImmVal)
return false;
- MachineInstr *Shl2Def = MRI.getUniqueVRegDef(Shl2);
- if (Shl2Def->getOpcode() != Opcode)
+ MachineInstr *Shl2Def;
+ if (!mi_match(Shl2, MRI, m_MInstr(Shl2Def)) || Shl2Def->getOpcode() != Opcode)
return false;
Register Base = Shl2Def->getOperand(1).getReg();
@@ -2027,7 +2032,9 @@ bool CombinerHelper::matchShiftOfShiftedLogic(
if (!MRI.hasOneNonDBGUse(LogicDest))
return false;
- MachineInstr *LogicMI = MRI.getUniqueVRegDef(LogicDest);
+ MachineInstr *LogicMI;
+ if (!mi_match(LogicDest, MRI, m_MInstr(LogicMI)))
+ return false;
unsigned LogicOpcode = LogicMI->getOpcode();
if (LogicOpcode != TargetOpcode::G_AND && LogicOpcode != TargetOpcode::G_OR &&
LogicOpcode != TargetOpcode::G_XOR)
@@ -2059,9 +2066,12 @@ bool CombinerHelper::matchShiftOfShiftedLogic(
// Logic ops are commutative, so check each operand for a match.
Register LogicMIReg1 = LogicMI->getOperand(1).getReg();
- MachineInstr *LogicMIOp1 = MRI.getUniqueVRegDef(LogicMIReg1);
+ MachineInstr *LogicMIOp1;
Register LogicMIReg2 = LogicMI->getOperand(2).getReg();
- MachineInstr *LogicMIOp2 = MRI.getUniqueVRegDef(LogicMIReg2);
+ MachineInstr *LogicMIOp2;
+ if (!mi_match(LogicMIReg1, MRI, m_MInstr(LogicMIOp1)) ||
+ !mi_match(LogicMIReg2, MRI, m_MInstr(LogicMIOp2)))
+ return false;
uint64_t C0Val;
if (matchFirstShift(LogicMIOp1, C0Val)) {
@@ -2136,9 +2146,11 @@ bool CombinerHelper::matchCommuteShift(MachineInstr &MI,
if (!getTargetLowering().isDesirableToCommuteWithShift(MI, !isPreLegalize()))
return false;
+ MachineInstr *SrcDef;
if (!mi_match(SrcReg, MRI,
m_OneNonDBGUse(m_any_of(m_GAdd(m_Reg(X), m_Reg(C1)),
- m_GOr(m_Reg(X), m_Reg(C1))))))
+ m_GOr(m_Reg(X), m_Reg(C1))))) ||
+ !mi_match(SrcReg, MRI, m_MInstr(SrcDef)))
return false;
APInt C1Val, C2Val;
@@ -2146,14 +2158,12 @@ bool CombinerHelper::matchCommuteShift(MachineInstr &MI,
!mi_match(ShiftReg, MRI, m_ICstOrSplat(C2Val)))
return false;
- auto *SrcDef = MRI.getVRegDef(SrcReg);
- assert((SrcDef->getOpcode() == TargetOpcode::G_ADD ||
- SrcDef->getOpcode() == TargetOpcode::G_OR) && "Unexpected op");
+ unsigned SrcOpc = SrcDef->getOpcode();
LLT SrcTy = MRI.getType(SrcReg);
MatchInfo = [=](MachineIRBuilder &B) {
auto S1 = B.buildShl(SrcTy, X, ShiftReg);
auto S2 = B.buildShl(SrcTy, C1, ShiftReg);
- B.buildInstr(SrcDef->getOpcode(), {DstReg}, {S1, S2});
+ B.buildInstr(SrcOpc, {DstReg}, {S1, S2});
};
return true;
}
@@ -2412,15 +2422,10 @@ bool CombinerHelper::matchCombineUnmergeConstant(
MachineInstr &MI, SmallVectorImpl<APInt> &Csts) const {
unsigned SrcIdx = MI.getNumOperands() - 1;
Register SrcReg = MI.getOperand(SrcIdx).getReg();
- MachineInstr *SrcInstr = MRI.getVRegDef(SrcReg);
- if (SrcInstr->getOpcode() != TargetOpcode::G_CONSTANT &&
- SrcInstr->getOpcode() != TargetOpcode::G_FCONSTANT)
- return false;
// Break down the big constant in smaller ones.
- const MachineOperand &CstVal = SrcInstr->getOperand(1);
- APInt Val = SrcInstr->getOpcode() == TargetOpcode::G_CONSTANT
- ? CstVal.getCImm()->getValue()
- : CstVal.getFPImm()->getValueAPF().bitcastToAPInt();
+ APInt Val;
+ if (!mi_match(SrcReg, MRI, m_GConstantOrFConstantBits(Val)))
+ return false;
LLT Dst0Ty = MRI.getType(MI.getOperand(0).getReg());
unsigned ShiftAmt = Dst0Ty.getSizeInBits();
@@ -2518,12 +2523,9 @@ void CombinerHelper::applyCombineUnmergeZExtToZExt(MachineInstr &MI) const {
Register Dst0Reg = MI.getOperand(0).getReg();
- MachineInstr *ZExtInstr =
- MRI.getVRegDef(MI.getOperand(MI.getNumDefs()).getReg());
- assert(ZExtInstr && ZExtInstr->getOpcode() == TargetOpcode::G_ZEXT &&
- "Expecting a G_ZEXT");
-
- Register ZExtSrcReg = ZExtInstr->getOperand(1).getReg();
+ GZext *ZExtInstr =
+ cast<GZext>(MRI.getVRegDef(MI.getOperand(MI.getNumDefs()).getReg()));
+ Register ZExtSrcReg = ZExtInstr->getSrcReg();
LLT Dst0Ty = MRI.getType(Dst0Reg);
LLT ZExtSrcTy = MRI.getType(ZExtSrcReg);
@@ -3282,8 +3284,8 @@ bool CombinerHelper::matchBinopWithNegInner(Register MInner, Register Other,
BuildFnTy &MatchInfo) const {
/// Helper function for matchBinopWithNeg: tries to match one commuted form
/// of `a bitwiseop (~b +/- c)` -> `a bitwiseop ~(b -/+ c)`.
- MachineInstr *InnerDef = MRI.getVRegDef(MInner);
- if (!InnerDef)
+ MachineInstr *InnerDef;
+ if (!mi_match(MInner, MRI, m_MInstr(InnerDef)))
return false;
unsigned InnerOpc = InnerDef->getOpcode();
@@ -3750,49 +3752,41 @@ bool CombinerHelper::matchUseVectorTruncate(MachineInstr &MI,
// Check the G_BUILD_VECTOR sources
unsigned I;
- MachineInstr *UnmergeMI = nullptr;
+ GUnmerge *UnmergeMI = nullptr;
// Check all source TRUNCs come from the same UNMERGE instruction
// and that the element order matches (BUILD_VECTOR position I
// corresponds to UNMERGE result I)
for (I = 0; I < NumOperands; ++I) {
- auto SrcMI = MRI.getVRegDef(BuildMI->getSourceReg(I));
- auto SrcMIOpc = SrcMI->getOpcode();
-
// Check if the G_TRUNC instructions all come from the same MI
- if (SrcMIOpc == TargetOpcode::G_TRUNC) {
- Register TruncSrcReg = SrcMI->getOperand(1).getReg();
- if (!UnmergeMI) {
- UnmergeMI = MRI.getVRegDef(TruncSrcReg);
- if (UnmergeMI->getOpcode() != TargetOpcode::G_UNMERGE_VALUES)
- return false;
- } else {
- auto UnmergeSrcMI = MRI.getVRegDef(TruncSrcReg);
- if (UnmergeMI != UnmergeSrcMI)
- return false;
- }
- // Verify element ordering: BUILD_VECTOR position I must use
- // UNMERGE result I, otherwise the fold would lose element reordering
- if (UnmergeMI->getOperand(I).getReg() != TruncSrcReg)
+ Register TruncSrcReg;
+ if (!mi_match(BuildMI->getSourceReg(I), MRI, m_GTrunc(m_Reg(TruncSrcReg))))
+ break;
+
+ if (!UnmergeMI) {
+ if (!mi_match(TruncSrcReg, MRI, m_GUnmerge(UnmergeMI)))
return false;
} else {
- break;
+ MachineInstr *UnmergeSrcMI;
+ if (!mi_match(TruncSrcReg, MRI, m_MInstr(UnmergeSrcMI)) ||
+ UnmergeMI != UnmergeSrcMI)
+ return false;
}
+ // Element order must match: position I must use UNMERGE result I.
+ if (UnmergeMI->getOperand(I).getReg() != TruncSrcReg)
+ return false;
}
if (I < 2)
return false;
// Check the remaining source elements are only G_IMPLICIT_DEF
for (; I < NumOperands; ++I) {
- auto SrcMI = MRI.getVRegDef(BuildMI->getSourceReg(I));
- auto SrcMIOpc = SrcMI->getOpcode();
-
- if (SrcMIOpc != TargetOpcode::G_IMPLICIT_DEF)
+ if (!mi_match(BuildMI->getSourceReg(I), MRI, m_GImplicitDef()))
return false;
}
// Check the size of unmerge source
- MatchInfo = cast<GUnmerge>(UnmergeMI)->getSourceReg();
+ MatchInfo = UnmergeMI->getSourceReg();
LLT UnmergeSrcTy = MRI.getType(MatchInfo);
if (!DstTy.getElementCount().isKnownMultipleOf(UnmergeSrcTy.getNumElements()))
return false;
@@ -3872,7 +3866,9 @@ bool CombinerHelper::matchNotCmp(
Register Reg = RegsToNegate[I];
if (!MRI.hasOneNonDBGUse(Reg))
return false;
- MachineInstr *Def = MRI.getVRegDef(Reg);
+ MachineInstr *Def;
+ if (!mi_match(Reg, MRI, m_MInstr(Def)))
+ return false;
switch (Def->getOpcode()) {
default:
// Don't match if the tree contains anything other than ANDs, ORs and
@@ -3907,11 +3903,10 @@ bool CombinerHelper::matchNotCmp(
// the constant in the xor.
int64_t Cst;
if (Ty.isVector()) {
- MachineInstr *CstDef = MRI.getVRegDef(CstReg);
- auto MaybeCst = getIConstantSplatSExtVal(*CstDef, MRI);
- if (!MaybeCst)
+ int64_t SplatCst;
+ if (!mi_match(CstReg, MRI, m_ICstOrSplat(SplatCst)))
return false;
- if (!isConstValidTrue(TLI, Ty.getScalarSizeInBits(), *MaybeCst, true, IsFP))
+ if (!isConstValidTrue(TLI, Ty.getScalarSizeInBits(), SplatCst, true, IsFP))
return false;
} else {
if (!mi_match(CstReg, MRI, m_ICst(Cst)))
@@ -4014,7 +4009,9 @@ bool CombinerHelper::matchPtrAddZero(MachineInstr &MI) const {
}
assert(Ty.isVector() && "Expecting a vector type");
- const MachineInstr *VecMI = MRI.getVRegDef(PtrAdd.getBaseReg());
+ const MachineInstr *VecMI;
+ if (!mi_match(PtrAdd.getBaseReg(), MRI, m_MInstr(VecMI)))
+ return false;
return isBuildVectorAllZeros(*VecMI, MRI);
}
@@ -4045,22 +4042,25 @@ bool CombinerHelper::matchFoldBinOpIntoSelect(MachineInstr &MI,
Register OtherOperandReg = RHS;
SelectOpNo = 1;
- MachineInstr *Select = MRI.getVRegDef(LHS);
+ Register SelectTrue, SelectFalse;
// Don't do this unless the old select is going away. We want to eliminate the
// binary operator, not replace a binop with a select.
- if (Select->getOpcode() != TargetOpcode::G_SELECT ||
+ if (!mi_match(LHS, MRI,
+ m_GISelect(m_Reg(), m_Reg(SelectTrue), m_Reg(SelectFalse))) ||
!MRI.hasOneNonDBGUse(LHS)) {
OtherOperandReg = LHS;
SelectOpNo = 2;
- Select = MRI.getVRegDef(RHS);
- if (Select->getOpcode() != TargetOpcode::G_SELECT ||
+ if (!mi_match(RHS, MRI,
+ m_GISelect(m_Reg(), m_Reg(SelectTrue), m_Reg(SelectFalse))) ||
!MRI.hasOneNonDBGUse(RHS))
return false;
}
- MachineInstr *SelectLHS = MRI.getVRegDef(Select->getOperand(2).getReg());
- MachineInstr *SelectRHS = MRI.getVRegDef(Select->getOperand(3).getReg());
+ MachineInstr *SelectLHS, *SelectRHS;
+ if (!mi_match(SelectTrue, MRI, m_MInstr(SelectLHS)) ||
+ !mi_match(SelectFalse, MRI, m_MInstr(SelectRHS)))
+ return false;
if (!isConstantOrConstantVector(*SelectLHS, MRI,
/*AllowFP*/ true,
@@ -4085,7 +4085,10 @@ bool CombinerHelper::matchFoldBinOpIntoSelect(MachineInstr &MI,
if (CanFoldNonConst)
return true;
- return isConstantOrConstantVector(*MRI.getVRegDef(OtherOperandReg), MRI,
+ MachineInstr *OtherOperandDef;
+ if (!mi_match(OtherOperandReg, MRI, m_MInstr(OtherOperandDef)))
+ return false;
+ return isConstantOrConstantVector(*OtherOperandDef, MRI,
/*AllowFP*/ true,
/*AllowOpaqueConstants*/ false);
}
@@ -4097,11 +4100,12 @@ void CombinerHelper::applyFoldBinOpIntoSelect(
Register Dst = MI.getOperand(0).getReg();
Register LHS = MI.getOperand(1).getReg();
Register RHS = MI.getOperand(2).getReg();
- MachineInstr *Select = MRI.getVRegDef(MI.getOperand(SelectOperand).getReg());
+ GSelect *Select =
+ cast<GSelect>(MRI.getVRegDef(MI.getOperand(SelectOperand).getReg()));
- Register SelectCond = Select->getOperand(1).getReg();
- Register SelectTrue = Select->getOperand(2).getReg();
- Register SelectFalse = Select->getOperand(3).getReg();
+ Register SelectCond = Select->getCondReg();
+ Register SelectTrue = Select->getTrueReg();
+ Register SelectFalse = Select->getFalseReg();
LLT Ty = MRI.getType(Dst);
unsigned BinOpcode = MI.getOpcode();
@@ -4542,7 +4546,9 @@ void CombinerHelper::applyExtendThroughPhis(MachineInstr &MI,
SmallDenseMap<MachineInstr *, MachineInstr *, 8> OldToNewSrcMap;
for (unsigned I = 0; I < PHI.getNumIncomingValues(); ++I) {
auto SrcReg = PHI.getIncomingValue(I);
- auto *SrcMI = MRI.getVRegDef(SrcReg);
+ MachineInstr *SrcMI;
+ if (!mi_match(SrcReg, MRI, m_MInstr(SrcMI)))
+ continue;
if (!SrcMIs.insert(SrcMI))
continue;
@@ -4592,10 +4598,13 @@ bool CombinerHelper::matchExtractVecEltBuildVec(MachineInstr &MI,
// Check if we have a build_vector or build_vector_trunc with an optional
// trunc in front.
- MachineInstr *SrcVecMI = MRI.getVRegDef(SrcVec);
- if (SrcVecMI->getOpcode() == TargetOpcode::G_TRUNC) {
- SrcVecMI = MRI.getVRegDef(SrcVecMI->getOperand(1).getReg());
- }
+ MachineInstr *SrcVecMI;
+ Register TruncSrc;
+ if (mi_match(SrcVec, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
+ if (!mi_match(TruncSrc, MRI, m_MInstr(SrcVecMI)))
+ return false;
+ } else if (!mi_match(SrcVec, MRI, m_MInstr(SrcVecMI)))
+ return false;
if (SrcVecMI->getOpcode() != TargetOpcode::G_BUILD_VECTOR &&
SrcVecMI->getOpcode() != TargetOpcode::G_BUILD_VECTOR_TRUNC)
@@ -5322,8 +5331,10 @@ bool CombinerHelper::matchReassocPtrAdd(MachineInstr &MI,
// 3) Move a constant from the LHS of an inner op to the RHS of the outer.
// G_PTR_ADD (G_PTR_ADD X, C), Y) -> G_PTR_ADD (G_PTR_ADD(X, Y), C)
// iif (G_PTR_ADD X, C) has one use.
- MachineInstr *LHS = MRI.getVRegDef(PtrAdd.getBaseReg());
- MachineInstr *RHS = MRI.getVRegDef(PtrAdd.getOffsetReg());
+ MachineInstr *LHS, *RHS;
+ if (!mi_match(PtrAdd.getBaseReg(), MRI, m_MInstr(LHS)) ||
+ !mi_match(PtrAdd.getOffsetReg(), MRI, m_MInstr(RHS)))
+ return false;
// Try to match example 2.
if (matchReassocFoldConstantsInSubTree(PtrAdd, LHS, RHS, MatchInfo))
@@ -5343,9 +5354,8 @@ bool CombinerHelper::tryReassocBinOp(unsigned Opc, Register DstReg,
Register OpLHS, Register OpRHS,
BuildFnTy &MatchInfo) const {
LLT OpRHSTy = MRI.getType(OpRHS);
- MachineInstr *OpLHSDef = MRI.getVRegDef(OpLHS);
-
- if (OpLHSDef->getOpcode() != Opc)
+ MachineInstr *OpLHSDef;
+ if (!mi_match(OpLHS, MRI, m_MInstr(OpLHSDef)) || OpLHSDef->getOpcode() != Opc)
return false;
Register OpLHSLHS = OpLHSDef->getOperand(1).getReg();
@@ -5875,8 +5885,9 @@ bool CombinerHelper::matchUDivOrURemByConst(MachineInstr &MI) const {
MRI, RHS, [](const Constant *C) { return C && !C->isNullValue(); });
}
- auto *RHSDef = MRI.getVRegDef(RHS);
- if (!isConstantOrConstantVector(*RHSDef, MRI))
+ MachineInstr *RHSDef;
+ if (!mi_match(RHS, MRI, m_MInstr(RHSDef)) ||
+ !isConstantOrConstantVector(*RHSDef, MRI))
return false;
// Don't do this if the types are not going to be legal.
@@ -5933,8 +5944,9 @@ bool CombinerHelper::matchSDivOrSRemByConst(MachineInstr &MI) const {
MRI, RHS, [](const Constant *C) { return C && !C->isNullValue(); });
}
- auto *RHSDef = MRI.getVRegDef(RHS);
- if (!isConstantOrConstantVector(*RHSDef, MRI))
+ MachineInstr *RHSDef;
+ if (!mi_match(RHS, MRI, m_MInstr(RHSDef)) ||
+ !isConstantOrConstantVector(*RHSDef, MRI))
return false;
// Don't do this if the types are not going to be legal.
@@ -6494,8 +6506,12 @@ bool CombinerHelper::matchCombineFAddFMulToFMadOrFMA(
Register Op1 = MI.getOperand(1).getReg();
Register Op2 = MI.getOperand(2).getReg();
- DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
- DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+ MachineInstr *Op1Def, *Op2Def;
+ if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+ !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+ return false;
+ DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+ DefinitionAndSourceRegister RHS = {Op2Def, Op2};
unsigned PreferredFusedOpcode =
HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
@@ -6548,8 +6564,12 @@ bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMA(
const auto &TLI = *MI.getMF()->getSubtarget().getTargetLowering();
Register Op1 = MI.getOperand(1).getReg();
Register Op2 = MI.getOperand(2).getReg();
- DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
- DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+ MachineInstr *Op1Def, *Op2Def;
+ if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+ !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+ return false;
+ DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+ DefinitionAndSourceRegister RHS = {Op2Def, Op2};
LLT DstType = MRI.getType(MI.getOperand(0).getReg());
unsigned PreferredFusedOpcode =
@@ -6609,8 +6629,12 @@ bool CombinerHelper::matchCombineFAddFMAFMulToFMadOrFMA(
Register Op1 = MI.getOperand(1).getReg();
Register Op2 = MI.getOperand(2).getReg();
- DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
- DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+ MachineInstr *Op1Def, *Op2Def;
+ if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+ !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+ return false;
+ DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+ DefinitionAndSourceRegister RHS = {Op2Def, Op2};
LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
unsigned PreferredFusedOpcode =
@@ -6646,7 +6670,9 @@ bool CombinerHelper::matchCombineFAddFMAFMulToFMadOrFMA(
}
if (FMA) {
- MachineInstr *FMulMI = MRI.getVRegDef(FMA->getOperand(3).getReg());
+ MachineInstr *FMulMI;
+ if (!mi_match(FMA->getOperand(3).getReg(), MRI, m_MInstr(FMulMI)))
+ return false;
Register X = FMA->getOperand(1).getReg();
Register Y = FMA->getOperand(2).getReg();
Register U = FMulMI->getOperand(1).getReg();
@@ -6682,8 +6708,12 @@ bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMAAggressive(
LLT DstType = MRI.getType(MI.getOperand(0).getReg());
Register Op1 = MI.getOperand(1).getReg();
Register Op2 = MI.getOperand(2).getReg();
- DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
- DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+ MachineInstr *Op1Def, *Op2Def;
+ if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+ !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+ return false;
+ DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+ DefinitionAndSourceRegister RHS = {Op2Def, Op2};
unsigned PreferredFusedOpcode =
HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
@@ -6736,7 +6766,9 @@ bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMAAggressive(
// interesting for all targets, especially GPUs.
if (mi_match(LHS.Reg, MRI, m_GFPExt(m_MInstr(FMAMI))) &&
FMAMI->getOpcode() == PreferredFusedOpcode) {
- MachineInstr *FMulMI = MRI.getVRegDef(FMAMI->getOperand(3).getReg());
+ MachineInstr *FMulMI;
+ if (!mi_match(FMAMI->getOperand(3).getReg(), MRI, m_MInstr(FMulMI)))
+ return false;
if (isContractableFMul(*FMulMI, AllowFusionGlobally) &&
TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
MRI.getType(FMAMI->getOperand(0).getReg()))) {
@@ -6782,7 +6814,9 @@ bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMAAggressive(
// interesting for all targets, especially GPUs.
if (mi_match(RHS.Reg, MRI, m_GFPExt(m_MInstr(FMAMI))) &&
FMAMI->getOpcode() == PreferredFusedOpcode) {
- MachineInstr *FMulMI = MRI.getVRegDef(FMAMI->getOperand(3).getReg());
+ MachineInstr *FMulMI;
+ if (!mi_match(FMAMI->getOperand(3).getReg(), MRI, m_MInstr(FMulMI)))
+ return false;
if (isContractableFMul(*FMulMI, AllowFusionGlobally) &&
TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
MRI.getType(FMAMI->getOperand(0).getReg()))) {
@@ -6815,8 +6849,12 @@ bool CombinerHelper::matchCombineFSubFMulToFMadOrFMA(
Register Op1 = MI.getOperand(1).getReg();
Register Op2 = MI.getOperand(2).getReg();
- DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
- DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+ MachineInstr *Op1Def, *Op2Def;
+ if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+ !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+ return false;
+ DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+ DefinitionAndSourceRegister RHS = {Op2Def, Op2};
LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
// If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)),
@@ -7450,17 +7488,20 @@ bool CombinerHelper::matchCommuteConstantToRHS(MachineInstr &MI) const {
}
Register LHS = MI.getOperand(LHSOpndIdx).getReg();
Register RHS = MI.getOperand(RHSOpndIdx).getReg();
+ MachineInstr *LHSDef, *RHSDef;
+ if (!mi_match(LHS, MRI, m_MInstr(LHSDef)) ||
+ !mi_match(RHS, MRI, m_MInstr(RHSDef)))
+ return false;
+
if (!getIConstantVRegVal(LHS, MRI)) {
// Skip commuting if LHS is not a constant. But, LHS may be a
// G_CONSTANT_FOLD_BARRIER. If so we commute as long as we don't already
// have a constant on the RHS.
- if (MRI.getVRegDef(LHS)->getOpcode() !=
- TargetOpcode::G_CONSTANT_FOLD_BARRIER)
+ if (LHSDef->getOpcode() != TargetOpcode::G_CONSTANT_FOLD_BARRIER)
return false;
}
// Commute as long as RHS is not a constant or G_CONSTANT_FOLD_BARRIER.
- return MRI.getVRegDef(RHS)->getOpcode() !=
- TargetOpcode::G_CONSTANT_FOLD_BARRIER &&
+ return RHSDef->getOpcode() != TargetOpcode::G_CONSTANT_FOLD_BARRIER &&
!getIConstantVRegVal(RHS, MRI);
}
@@ -7826,30 +7867,31 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
bool CombinerHelper::matchSelectIMinMax(const MachineOperand &MO,
BuildFnTy &MatchInfo) const {
- GSelect *Select = cast<GSelect>(MRI.getVRegDef(MO.getReg()));
- GICmp *Cmp = cast<GICmp>(MRI.getVRegDef(Select->getCondReg()));
+ Register DstReg = MO.getReg();
+ Register CondReg, True, False;
+ if (!mi_match(DstReg, MRI,
+ m_GISelect(m_Reg(CondReg), m_Reg(True), m_Reg(False))))
+ return false;
- Register DstReg = Select->getReg(0);
- Register True = Select->getTrueReg();
- Register False = Select->getFalseReg();
- LLT DstTy = MRI.getType(DstReg);
+ CmpInst::Predicate Pred;
+ Register CmpLHS, CmpRHS;
+ if (!mi_match(CondReg, MRI,
+ m_GICmp(m_Pred(Pred), m_Reg(CmpLHS), m_Reg(CmpRHS))))
+ return false;
+ LLT DstTy = MRI.getType(DstReg);
if (DstTy.isPointerOrPointerVector())
return false;
// We want to fold the icmp and replace the select.
- if (!MRI.hasOneNonDBGUse(Cmp->getReg(0)))
+ if (!MRI.hasOneNonDBGUse(CondReg))
return false;
- CmpInst::Predicate Pred = Cmp->getCond();
// We need a larger or smaller predicate for
// canonicalization.
if (CmpInst::isEquality(Pred))
return false;
- Register CmpLHS = Cmp->getLHSReg();
- Register CmpRHS = Cmp->getRHSReg();
-
// We can swap CmpLHS and CmpRHS for higher hitrate.
if (True == CmpRHS && False == CmpLHS) {
std::swap(CmpLHS, CmpRHS);
@@ -7911,7 +7953,9 @@ bool CombinerHelper::matchSimplifyNegMinMax(MachineInstr &MI,
m_GSMax(m_Reg(X), NegPattern),
m_GUMin(m_Reg(X), NegPattern),
m_GUMax(m_Reg(X), NegPattern)))))) {
- MachineInstr *MinMaxMI = MRI.getVRegDef(MI.getOperand(2).getReg());
+ MachineInstr *MinMaxMI;
+ if (!mi_match(MI.getOperand(2).getReg(), MRI, m_MInstr(MinMaxMI)))
+ return false;
unsigned NewOpc = getInverseGMinMaxOpcode(MinMaxMI->getOpcode());
if (isLegal({NewOpc, {DestTy}})) {
MatchInfo = [=](MachineIRBuilder &B) {
@@ -8427,20 +8471,22 @@ bool CombinerHelper::matchFoldAPlusC1MinusC2(const MachineInstr &MI,
BuildFnTy &MatchInfo) const {
// fold (A+C1)-C2 -> A+(C1-C2)
const GSub *Sub = cast<GSub>(&MI);
- GAdd *Add = cast<GAdd>(MRI.getVRegDef(Sub->getLHSReg()));
+ Register A, C1Reg;
+ if (!mi_match(Sub->getLHSReg(), MRI, m_GAdd(m_Reg(A), m_Reg(C1Reg))))
+ return false;
- if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+ if (!MRI.hasOneNonDBGUse(Sub->getLHSReg()))
return false;
APInt C2 = getIConstantFromReg(Sub->getRHSReg(), MRI);
- APInt C1 = getIConstantFromReg(Add->getRHSReg(), MRI);
+ APInt C1 = getIConstantFromReg(C1Reg, MRI);
Register Dst = Sub->getReg(0);
LLT DstTy = MRI.getType(Dst);
MatchInfo = [=](MachineIRBuilder &B) {
auto Const = B.buildConstant(DstTy, C1 - C2);
- B.buildAdd(Dst, Add->getLHSReg(), Const);
+ B.buildAdd(Dst, A, Const);
};
return true;
@@ -8450,20 +8496,22 @@ bool CombinerHelper::matchFoldC2MinusAPlusC1(const MachineInstr &MI,
BuildFnTy &MatchInfo) const {
// fold C2-(A+C1) -> (C2-C1)-A
const GSub *Sub = cast<GSub>(&MI);
- GAdd *Add = cast<GAdd>(MRI.getVRegDef(Sub->getRHSReg()));
+ Register A, C1Reg;
+ if (!mi_match(Sub->getRHSReg(), MRI, m_GAdd(m_Reg(A), m_Reg(C1Reg))))
+ return false;
- if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+ if (!MRI.hasOneNonDBGUse(Sub->getRHSReg()))
return false;
APInt C2 = getIConstantFromReg(Sub->getLHSReg(), MRI);
- APInt C1 = getIConstantFromReg(Add->getRHSReg(), MRI);
+ APInt C1 = getIConstantFromReg(C1Reg, MRI);
Register Dst = Sub->getReg(0);
LLT DstTy = MRI.getType(Dst);
MatchInfo = [=](MachineIRBuilder &B) {
auto Const = B.buildConstant(DstTy, C2 - C1);
- B.buildSub(Dst, Const, Add->getLHSReg());
+ B.buildSub(Dst, Const, A);
};
return true;
@@ -8473,20 +8521,22 @@ bool CombinerHelper::matchFoldAMinusC1MinusC2(const MachineInstr &MI,
BuildFnTy &MatchInfo) const {
// fold (A-C1)-C2 -> A-(C1+C2)
const GSub *Sub1 = cast<GSub>(&MI);
- GSub *Sub2 = cast<GSub>(MRI.getVRegDef(Sub1->getLHSReg()));
+ Register A, C1Reg;
+ if (!mi_match(Sub1->getLHSReg(), MRI, m_GSub(m_Reg(A), m_Reg(C1Reg))))
+ return false;
- if (!MRI.hasOneNonDBGUse(Sub2->getReg(0)))
+ if (!MRI.hasOneNonDBGUse(Sub1->getLHSReg()))
return false;
APInt C2 = getIConstantFromReg(Sub1->getRHSReg(), MRI);
- APInt C1 = getIConstantFromReg(Sub2->getRHSReg(), MRI);
+ APInt C1 = getIConstantFromReg(C1Reg, MRI);
Register Dst = Sub1->getReg(0);
LLT DstTy = MRI.getType(Dst);
MatchInfo = [=](MachineIRBuilder &B) {
auto Const = B.buildConstant(DstTy, C1 + C2);
- B.buildSub(Dst, Sub2->getLHSReg(), Const);
+ B.buildSub(Dst, A, Const);
};
return true;
@@ -8496,20 +8546,22 @@ bool CombinerHelper::matchFoldC1Minus2MinusC2(const MachineInstr &MI,
BuildFnTy &MatchInfo) const {
// fold (C1-A)-C2 -> (C1-C2)-A
const GSub *Sub1 = cast<GSub>(&MI);
- GSub *Sub2 = cast<GSub>(MRI.getVRegDef(Sub1->getLHSReg()));
+ Register C1Reg, A;
+ if (!mi_match(Sub1->getLHSReg(), MRI, m_GSub(m_Reg(C1Reg), m_Reg(A))))
+ return false;
- if (!MRI.hasOneNonDBGUse(Sub2->getReg(0)))
+ if (!MRI.hasOneNonDBGUse(Sub1->getLHSReg()))
return false;
APInt C2 = getIConstantFromReg(Sub1->getRHSReg(), MRI);
- APInt C1 = getIConstantFromReg(Sub2->getLHSReg(), MRI);
+ APInt C1 = getIConstantFromReg(C1Reg, MRI);
Register Dst = Sub1->getReg(0);
LLT DstTy = MRI.getType(Dst);
MatchInfo = [=](MachineIRBuilder &B) {
auto Const = B.buildConstant(DstTy, C1 - C2);
- B.buildSub(Dst, Const, Sub2->getRHSReg());
+ B.buildSub(Dst, Const, A);
};
return true;
@@ -8519,20 +8571,22 @@ bool CombinerHelper::matchFoldAMinusC1PlusC2(const MachineInstr &MI,
BuildFnTy &MatchInfo) const {
// fold ((A-C1)+C2) -> (A+(C2-C1))
const GAdd *Add = cast<GAdd>(&MI);
- GSub *Sub = cast<GSub>(MRI.getVRegDef(Add->getLHSReg()));
+ Register A, C1Reg;
+ if (!mi_match(Add->getLHSReg(), MRI, m_GSub(m_Reg(A), m_Reg(C1Reg))))
+ return false;
- if (!MRI.hasOneNonDBGUse(Sub->getReg(0)))
+ if (!MRI.hasOneNonDBGUse(Add->getLHSReg()))
return false;
APInt C2 = getIConstantFromReg(Add->getRHSReg(), MRI);
- APInt C1 = getIConstantFromReg(Sub->getRHSReg(), MRI);
+ APInt C1 = getIConstantFromReg(C1Reg, MRI);
Register Dst = Add->getReg(0);
LLT DstTy = MRI.getType(Dst);
MatchInfo = [=](MachineIRBuilder &B) {
auto Const = B.buildConstant(DstTy, C2 - C1);
- B.buildAdd(Dst, Sub->getLHSReg(), Const);
+ B.buildAdd(Dst, A, Const);
};
return true;
@@ -8545,8 +8599,6 @@ bool CombinerHelper::matchUnmergeValuesAnyExtBuildVector(
if (!MRI.hasOneNonDBGUse(Unmerge->getSourceReg()))
return false;
- const MachineInstr *Source = MRI.getVRegDef(Unmerge->getSourceReg());
-
LLT DstTy = MRI.getType(Unmerge->getReg(0));
// $bv:_(<8 x s8>) = G_BUILD_VECTOR ....
@@ -8570,13 +8622,12 @@ bool CombinerHelper::matchUnmergeValuesAnyExtBuildVector(
if (!DstTy.isFixedVector())
return false;
- const GAnyExt *Any = dyn_cast<GAnyExt>(Source);
- if (!Any)
+ Register AnySrcReg;
+ if (!mi_match(Unmerge->getSourceReg(), MRI, m_GAnyExt(m_Reg(AnySrcReg))))
return false;
- const MachineInstr *NextSource = MRI.getVRegDef(Any->getSrcReg());
-
- if (const GBuildVector *BV = dyn_cast<GBuildVector>(NextSource)) {
+ GBuildVector *BV;
+ if (mi_match(AnySrcReg, MRI, m_GBuildVector(BV))) {
// G_UNMERGE_VALUES G_ANYEXT G_BUILD_VECTOR
if (!MRI.hasOneNonDBGUse(BV->getReg(0)))
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
index 5e67029e68b56..a310cb8174f43 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
@@ -13,6 +13,7 @@
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/LowLevelTypeUtils.h"
@@ -24,6 +25,7 @@
#define DEBUG_TYPE "gi-combiner"
using namespace llvm;
+using namespace MIPatternMatch;
bool CombinerHelper::matchSextOfTrunc(const MachineOperand &MO,
BuildFnTy &MatchInfo) const {
@@ -116,10 +118,10 @@ bool CombinerHelper::matchZextOfTrunc(const MachineOperand &MO,
bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
BuildFnTy &MatchInfo) const {
- GZext *Zext = cast<GZext>(MRI.getVRegDef(MO.getReg()));
-
- Register Dst = Zext->getReg(0);
- Register Src = Zext->getSrcReg();
+ Register Dst = MO.getReg();
+ Register Src;
+ if (!mi_match(Dst, MRI, m_GZExt(m_Reg(Src))))
+ return false;
LLT DstTy = MRI.getType(Dst);
LLT SrcTy = MRI.getType(Src);
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
index 229076bbdeaa5..f657c6b49cbb4 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
@@ -364,11 +364,10 @@ bool CombinerHelper::matchInsertVectorElementOOB(MachineInstr &MI,
bool CombinerHelper::matchAddOfVScale(const MachineOperand &MO,
BuildFnTy &MatchInfo) const {
- GAdd *Add = cast<GAdd>(MRI.getVRegDef(MO.getReg()));
- GVScale *LHSVScale = cast<GVScale>(MRI.getVRegDef(Add->getLHSReg()));
- GVScale *RHSVScale = cast<GVScale>(MRI.getVRegDef(Add->getRHSReg()));
-
- Register Dst = Add->getReg(0);
+ Register Dst = MO.getReg();
+ GVScale *LHSVScale, *RHSVScale;
+ if (!mi_match(Dst, MRI, m_GAdd(m_GVScale(LHSVScale), m_GVScale(RHSVScale))))
+ return false;
if (!MRI.hasOneNonDBGUse(LHSVScale->getReg(0)) ||
!MRI.hasOneNonDBGUse(RHSVScale->getReg(0)))
@@ -383,15 +382,16 @@ bool CombinerHelper::matchAddOfVScale(const MachineOperand &MO,
bool CombinerHelper::matchMulOfVScale(const MachineOperand &MO,
BuildFnTy &MatchInfo) const {
- GMul *Mul = cast<GMul>(MRI.getVRegDef(MO.getReg()));
- GVScale *LHSVScale = cast<GVScale>(MRI.getVRegDef(Mul->getLHSReg()));
+ Register Dst = MO.getReg();
+ GVScale *LHSVScale;
+ Register RHSReg;
+ if (!mi_match(Dst, MRI, m_GMul(m_GVScale(LHSVScale), m_Reg(RHSReg))))
+ return false;
- std::optional<APInt> MaybeRHS = getIConstantVRegVal(Mul->getRHSReg(), MRI);
+ std::optional<APInt> MaybeRHS = getIConstantVRegVal(RHSReg, MRI);
if (!MaybeRHS)
return false;
- Register Dst = MO.getReg();
-
if (!MRI.hasOneNonDBGUse(LHSVScale->getReg(0)))
return false;
@@ -404,10 +404,14 @@ bool CombinerHelper::matchMulOfVScale(const MachineOperand &MO,
bool CombinerHelper::matchSubOfVScale(const MachineOperand &MO,
BuildFnTy &MatchInfo) const {
- GSub *Sub = cast<GSub>(MRI.getVRegDef(MO.getReg()));
- GVScale *RHSVScale = cast<GVScale>(MRI.getVRegDef(Sub->getRHSReg()));
-
Register Dst = MO.getReg();
+ Register SubLHS;
+ GVScale *RHSVScale;
+ uint32_t Flags;
+ if (!mi_match(Dst, MRI,
+ m_GSub(m_Reg(SubLHS), m_GVScale(RHSVScale), m_MIFlags(Flags))))
+ return false;
+
LLT DstTy = MRI.getType(Dst);
if (!MRI.hasOneNonDBGUse(RHSVScale->getReg(0)) ||
@@ -416,7 +420,7 @@ bool CombinerHelper::matchSubOfVScale(const MachineOperand &MO,
MatchInfo = [=](MachineIRBuilder &B) {
auto VScale = B.buildVScale(DstTy, -RHSVScale->getSrc());
- B.buildAdd(Dst, Sub->getLHSReg(), VScale, Sub->getFlags());
+ B.buildAdd(Dst, SubLHS, VScale, Flags);
};
return true;
@@ -424,14 +428,16 @@ bool CombinerHelper::matchSubOfVScale(const MachineOperand &MO,
bool CombinerHelper::matchShlOfVScale(const MachineOperand &MO,
BuildFnTy &MatchInfo) const {
- GShl *Shl = cast<GShl>(MRI.getVRegDef(MO.getReg()));
- GVScale *LHSVScale = cast<GVScale>(MRI.getVRegDef(Shl->getSrcReg()));
+ Register Dst = MO.getReg();
+ GVScale *LHSVScale;
+ Register ShiftReg;
+ if (!mi_match(Dst, MRI, m_GShl(m_GVScale(LHSVScale), m_Reg(ShiftReg))))
+ return false;
- std::optional<APInt> MaybeRHS = getIConstantVRegVal(Shl->getShiftReg(), MRI);
+ std::optional<APInt> MaybeRHS = getIConstantVRegVal(ShiftReg, MRI);
if (!MaybeRHS)
return false;
- Register Dst = MO.getReg();
LLT DstTy = MRI.getType(Dst);
if (!MRI.hasOneNonDBGUse(LHSVScale->getReg(0)) ||
More information about the llvm-commits
mailing list