There is no case where those functions return false. It's always return true.
Even if they were to return false, it's not really something we should rely on I think.
With the current combiner implementation, it would just make `tryCombineAll` return false without retrying anymore rules.
I also believe that if an applyer were to return false, it would mean that the match function is not good enough. Asserting on failure in an apply function is a better idea, IMO.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D153619
bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx);
/// Replace an instruction with a G_FCONSTANT with value \p C.
- bool replaceInstWithFConstant(MachineInstr &MI, double C);
+ void replaceInstWithFConstant(MachineInstr &MI, double C);
/// Replace an instruction with a G_CONSTANT with value \p C.
- bool replaceInstWithConstant(MachineInstr &MI, int64_t C);
+ void replaceInstWithConstant(MachineInstr &MI, int64_t C);
/// Replace an instruction with a G_CONSTANT with value \p C.
- bool replaceInstWithConstant(MachineInstr &MI, APInt C);
+ void replaceInstWithConstant(MachineInstr &MI, APInt C);
/// Replace an instruction with a G_IMPLICIT_DEF.
- bool replaceInstWithUndef(MachineInstr &MI);
+ void replaceInstWithUndef(MachineInstr &MI);
/// Delete \p MI and replace all of its uses with its \p OpIdx-th operand.
- bool replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx);
+ void replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx);
/// Delete \p MI and replace all of its uses with \p Replacement.
- bool replaceSingleDefInstWithReg(MachineInstr &MI, Register Replacement);
+ void replaceSingleDefInstWithReg(MachineInstr &MI, Register Replacement);
/// Return true if \p MOP1 and \p MOP2 are register operands are defined by
/// equivalent instructions.
bool matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI, unsigned OpIdx);
/// Erase \p MI
- bool eraseInst(MachineInstr &MI);
+ void eraseInst(MachineInstr &MI);
/// Return true if MI is a G_ADD which can be simplified to a G_SUB.
bool matchSimplifyAddToSub(MachineInstr &MI,
/// binop (select cond, K0, K1), K2 ->
/// select cond, (binop K0, K2), (binop K1, K2)
bool matchFoldBinOpIntoSelect(MachineInstr &MI, unsigned &SelectOpNo);
- bool applyFoldBinOpIntoSelect(MachineInstr &MI, const unsigned &SelectOpNo);
+ void applyFoldBinOpIntoSelect(MachineInstr &MI, const unsigned &SelectOpNo);
bool matchCombineInsertVecElts(MachineInstr &MI,
SmallVectorImpl<Register> &MatchInfo);
Helper.getBuilder().setInstrAndDebugLoc(*${root});
Helper.getBuilder().buildZExtInReg(${dst}, ${src}, ${imm}.getImm());
${root}->eraseFromParent();
- return true;
}])
>;
(defs root:$root),
(match (wip_match_opcode G_SELECT):$root,
[{ return Helper.matchSelectSameVal(*${root}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
>;
// Fold (undef ? x : y) -> y
(defs root:$root),
(match (wip_match_opcode G_SELECT):$root,
[{ return Helper.matchUndefSelectCmp(*${root}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
>;
// Fold (true ? x : y) -> x
(defs root:$root, select_constant_cmp_matchdata:$matchinfo),
(match (wip_match_opcode G_SELECT):$root,
[{ return Helper.matchConstantSelectCmp(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
>;
def select_to_logical : GICombineRule<
(match (wip_match_opcode G_SUB, G_ADD, G_OR, G_XOR, G_SHL, G_ASHR, G_LSHR,
G_PTR_ADD, G_ROTL, G_ROTR):$root,
[{ return Helper.matchConstantOp(${root}->getOperand(2), 0); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
// Fold x op 1 -> x
(defs root:$root),
(match (wip_match_opcode G_MUL):$root,
[{ return Helper.matchConstantOp(${root}->getOperand(2), 1); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
// Fold (x op x) - > x
(defs root:$root),
(match (wip_match_opcode G_AND, G_OR):$root,
[{ return Helper.matchBinOpSameVal(*${root}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
// Fold (0 op x) - > 0
(defs root:$root),
(match (wip_match_opcode G_SDIV, G_UDIV, G_SREM, G_UREM):$root,
[{ return Helper.matchOperandIsZero(*${root}, 1); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
def urem_pow2_to_mask : GICombineRule<
G_FMUL, G_FADD, G_FSUB, G_FDIV, G_FREM,
G_FMINNUM, G_FMAXNUM, G_FMINIMUM, G_FMAXIMUM):$root,
[{ return Helper.matchFoldBinOpIntoSelect(*${root}, ${select_op_no}); }]),
- (apply [{ return Helper.applyFoldBinOpIntoSelect(*${root}, ${select_op_no}); }])
+ (apply [{ Helper.applyFoldBinOpIntoSelect(*${root}, ${select_op_no}); }])
>;
// Transform d = [su]div(x, y) and r = [su]rem(x, y) - > d, r = [su]divrem(x, y)
(defs root:$root),
(match (wip_match_opcode G_MUL):$root,
[{ return Helper.matchOperandIsZero(*${root}, 2); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
>;
// Erase stores of undef values.
(defs root:$root),
(match (wip_match_opcode G_STORE):$root,
[{ return Helper.matchUndefStore(*${root}); }]),
- (apply [{ return Helper.eraseInst(*${root}); }])
+ (apply [{ Helper.eraseInst(*${root}); }])
>;
def simplify_add_to_sub_matchinfo: GIDefMatchData<"std::tuple<Register, Register>">;
(defs root:$root, register_matchinfo:$matchinfo),
(match (wip_match_opcode G_AND):$root,
[{ return Helper.matchRedundantAnd(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+ (apply [{ Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
>;
// Fold (x | y) -> x or (x | y) -> y when (x | y) is known to equal x or equal y.
(defs root:$root, register_matchinfo:$matchinfo),
(match (wip_match_opcode G_OR):$root,
[{ return Helper.matchRedundantOr(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+ (apply [{ Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
>;
// If the input is already sign extended, just drop the extension.
(defs root:$root),
(match (wip_match_opcode G_SEXT_INREG):$root,
[{ return Helper.matchRedundantSExtInReg(*${root}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
// Fold (anyext (trunc x)) -> x if the source type is same as
(defs root:$root, register_matchinfo:$matchinfo),
(match (wip_match_opcode G_ANYEXT):$root,
[{ return Helper.matchCombineAnyExtTrunc(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+ (apply [{ Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
>;
// Fold (zext (trunc x)) -> x if the source type is same as the destination type
(defs root:$root, zext_trunc_fold_matchinfo:$matchinfo),
(match (wip_match_opcode G_ZEXT):$root,
[{ return Helper.matchCombineZextTrunc(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+ (apply [{ Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
>;
// Fold ([asz]ext ([asz]ext x)) -> ([asz]ext x).
(match (G_FNEG $t, $src),
(G_FNEG $dst, $t):$mi,
[{ ${matchinfo} = ${src}.getReg(); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${mi}, ${matchinfo}); }])
+ (apply [{ Helper.replaceSingleDefInstWithReg(*${mi}, ${matchinfo}); }])
>;
// Fold (unmerge(merge x, y, z)) -> z, y, z.
(defs root:$root, register_matchinfo:$matchinfo),
(match (wip_match_opcode G_ADD):$root,
[{ return Helper.matchAddSubSameReg(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root},
+ (apply [{ Helper.replaceSingleDefInstWithReg(*${root},
${matchinfo}); }])>;
def buildvector_identity_fold : GICombineRule<
return true;
}
-bool CombinerHelper::eraseInst(MachineInstr &MI) {
- MI.eraseFromParent();
- return true;
-}
+void CombinerHelper::eraseInst(MachineInstr &MI) { MI.eraseFromParent(); }
bool CombinerHelper::matchEqualDefs(const MachineOperand &MOP1,
const MachineOperand &MOP2) {
MaybeCst->getSExtValue() == C;
}
-bool CombinerHelper::replaceSingleDefInstWithOperand(MachineInstr &MI,
+void CombinerHelper::replaceSingleDefInstWithOperand(MachineInstr &MI,
unsigned OpIdx) {
assert(MI.getNumExplicitDefs() == 1 && "Expected one explicit def?");
Register OldReg = MI.getOperand(0).getReg();
assert(canReplaceReg(OldReg, Replacement, MRI) && "Cannot replace register?");
MI.eraseFromParent();
replaceRegWith(MRI, OldReg, Replacement);
- return true;
}
-bool CombinerHelper::replaceSingleDefInstWithReg(MachineInstr &MI,
+void CombinerHelper::replaceSingleDefInstWithReg(MachineInstr &MI,
Register Replacement) {
assert(MI.getNumExplicitDefs() == 1 && "Expected one explicit def?");
Register OldReg = MI.getOperand(0).getReg();
assert(canReplaceReg(OldReg, Replacement, MRI) && "Cannot replace register?");
MI.eraseFromParent();
replaceRegWith(MRI, OldReg, Replacement);
- return true;
}
bool CombinerHelper::matchSelectSameVal(MachineInstr &MI) {
return isKnownToBeAPowerOfTwo(MO.getReg(), MRI, KB);
}
-bool CombinerHelper::replaceInstWithFConstant(MachineInstr &MI, double C) {
+void CombinerHelper::replaceInstWithFConstant(MachineInstr &MI, double C) {
assert(MI.getNumDefs() == 1 && "Expected only one def?");
Builder.setInstr(MI);
Builder.buildFConstant(MI.getOperand(0), C);
MI.eraseFromParent();
- return true;
}
-bool CombinerHelper::replaceInstWithConstant(MachineInstr &MI, int64_t C) {
+void CombinerHelper::replaceInstWithConstant(MachineInstr &MI, int64_t C) {
assert(MI.getNumDefs() == 1 && "Expected only one def?");
Builder.setInstr(MI);
Builder.buildConstant(MI.getOperand(0), C);
MI.eraseFromParent();
- return true;
}
-bool CombinerHelper::replaceInstWithConstant(MachineInstr &MI, APInt C) {
+void CombinerHelper::replaceInstWithConstant(MachineInstr &MI, APInt C) {
assert(MI.getNumDefs() == 1 && "Expected only one def?");
Builder.setInstr(MI);
Builder.buildConstant(MI.getOperand(0), C);
MI.eraseFromParent();
- return true;
}
-bool CombinerHelper::replaceInstWithUndef(MachineInstr &MI) {
+void CombinerHelper::replaceInstWithUndef(MachineInstr &MI) {
assert(MI.getNumDefs() == 1 && "Expected only one def?");
Builder.setInstr(MI);
Builder.buildUndef(MI.getOperand(0));
MI.eraseFromParent();
- return true;
}
bool CombinerHelper::matchSimplifyAddToSub(
/// \p SelectOperand is the operand in binary operator \p MI that is the select
/// to fold.
-bool CombinerHelper::applyFoldBinOpIntoSelect(MachineInstr &MI,
+void CombinerHelper::applyFoldBinOpIntoSelect(MachineInstr &MI,
const unsigned &SelectOperand) {
Builder.setInstrAndDebugLoc(MI);
Builder.buildSelect(Dst, SelectCond, FoldTrue, FoldFalse, MI.getFlags());
MI.eraseFromParent();
-
- return true;
}
std::optional<SmallVector<Register, 8>>
(defs root:$root, fold_global_offset_matchdata:$matchinfo),
(match (wip_match_opcode G_GLOBAL_VALUE):$root,
[{ return matchFoldGlobalOffset(*${root}, MRI, ${matchinfo}); }]),
- (apply [{ return applyFoldGlobalOffset(*${root}, MRI, B, Observer, ${matchinfo});}])
+ (apply [{ applyFoldGlobalOffset(*${root}, MRI, B, Observer, ${matchinfo});}])
>;
def AArch64PreLegalizerCombinerHelper: GICombinerHelper<
(defs root:$root, shuf_to_ins_matchdata:$matchinfo),
(match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
[{ return matchINS(*${root}, MRI, ${matchinfo}); }]),
- (apply [{ return applyINS(*${root}, MRI, B, ${matchinfo}); }])
+ (apply [{ applyINS(*${root}, MRI, B, ${matchinfo}); }])
>;
def vashr_vlshr_imm_matchdata : GIDefMatchData<"int64_t">;
(defs root:$root),
(match (wip_match_opcode G_BUILD_VECTOR):$root,
[{ return matchBuildVectorToDup(*${root}, MRI); }]),
- (apply [{ return applyBuildVectorToDup(*${root}, MRI, B); }])
+ (apply [{ applyBuildVectorToDup(*${root}, MRI, B); }])
>;
def build_vector_lowering : GICombineGroup<[build_vector_to_dup]>;
return false;
}
-bool applyExtractVecEltPairwiseAdd(
+void applyExtractVecEltPairwiseAdd(
MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
std::tuple<unsigned, LLT, Register> &MatchInfo) {
unsigned Opc = std::get<0>(MatchInfo);
auto Elt1 = B.buildExtractVectorElement(Ty, Src, B.buildConstant(s64, 1));
B.buildInstr(Opc, {MI.getOperand(0).getReg()}, {Elt0, Elt1});
MI.eraseFromParent();
- return true;
}
static bool isSignExtended(Register R, MachineRegisterInfo &MRI) {
return true;
}
-bool applyAArch64MulConstCombine(
+void applyAArch64MulConstCombine(
MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
std::function<void(MachineIRBuilder &B, Register DstReg)> &ApplyFn) {
B.setInstrAndDebugLoc(MI);
ApplyFn(B, MI.getOperand(0).getReg());
MI.eraseFromParent();
- return true;
}
/// Try to fold a G_MERGE_VALUES of 2 s32 sources, where the second source
/// Replace a G_SHUFFLE_VECTOR instruction with a pseudo.
/// \p Opc is the opcode to use. \p MI is the G_SHUFFLE_VECTOR.
-static bool applyShuffleVectorPseudo(MachineInstr &MI,
+static void applyShuffleVectorPseudo(MachineInstr &MI,
ShuffleVectorPseudo &MatchInfo) {
MachineIRBuilder MIRBuilder(MI);
MIRBuilder.buildInstr(MatchInfo.Opc, {MatchInfo.Dst}, MatchInfo.SrcOps);
MI.eraseFromParent();
- return true;
}
/// Replace a G_SHUFFLE_VECTOR instruction with G_EXT.
/// Special-cased because the constant operand must be emitted as a G_CONSTANT
/// for the imported tablegen patterns to work.
-static bool applyEXT(MachineInstr &MI, ShuffleVectorPseudo &MatchInfo) {
+static void applyEXT(MachineInstr &MI, ShuffleVectorPseudo &MatchInfo) {
MachineIRBuilder MIRBuilder(MI);
// Tablegen patterns expect an i32 G_CONSTANT as the final op.
auto Cst =
MIRBuilder.buildInstr(MatchInfo.Opc, {MatchInfo.Dst},
{MatchInfo.SrcOps[0], MatchInfo.SrcOps[1], Cst});
MI.eraseFromParent();
- return true;
}
/// Match a G_SHUFFLE_VECTOR with a mask which corresponds to a
return true;
}
-static bool applyINS(MachineInstr &MI, MachineRegisterInfo &MRI,
+static void applyINS(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &Builder,
std::tuple<Register, int, Register, int> &MatchInfo) {
Builder.setInstrAndDebugLoc(MI);
auto DstCst = Builder.buildConstant(LLT::scalar(64), DstLane);
Builder.buildInsertVectorElement(Dst, DstVec, Extract, DstCst);
MI.eraseFromParent();
- return true;
}
/// isVShiftRImm - Check if this is a valid vector for the immediate
return isVShiftRImm(MI.getOperand(2).getReg(), MRI, Ty, Imm);
}
-static bool applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
+static void applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
int64_t &Imm) {
unsigned Opc = MI.getOpcode();
assert(Opc == TargetOpcode::G_ASHR || Opc == TargetOpcode::G_LSHR);
auto ImmDef = MIB.buildConstant(LLT::scalar(32), Imm);
MIB.buildInstr(NewOpc, {MI.getOperand(0)}, {MI.getOperand(1), ImmDef});
MI.eraseFromParent();
- return true;
}
/// Determine if it is possible to modify the \p RHS and predicate \p P of a
return false;
}
-bool applyAdjustICmpImmAndPred(
+void applyAdjustICmpImmAndPred(
MachineInstr &MI, std::pair<uint64_t, CmpInst::Predicate> &MatchInfo,
MachineIRBuilder &MIB, GISelChangeObserver &Observer) {
MIB.setInstrAndDebugLoc(MI);
RHS.setReg(Cst->getOperand(0).getReg());
MI.getOperand(1).setPredicate(MatchInfo.second);
Observer.changedInstr(MI);
- return true;
}
bool matchDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
return true;
}
-bool applyDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
+void applyDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &B, std::pair<unsigned, int> &MatchInfo) {
assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
Register Src1Reg = MI.getOperand(1).getReg();
}
B.buildInstr(MatchInfo.first, {MI.getOperand(0).getReg()}, {DupSrc, Lane});
MI.eraseFromParent();
- return true;
}
static bool matchBuildVectorToDup(MachineInstr &MI, MachineRegisterInfo &MRI) {
return (Cst != 0 && Cst != -1);
}
-static bool applyBuildVectorToDup(MachineInstr &MI, MachineRegisterInfo &MRI,
+static void applyBuildVectorToDup(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &B) {
B.setInstrAndDebugLoc(MI);
B.buildInstr(AArch64::G_DUP, {MI.getOperand(0).getReg()},
{MI.getOperand(1).getReg()});
MI.eraseFromParent();
- return true;
}
/// \returns how many instructions would be saved by folding a G_ICMP's shift
getCmpOperandFoldingProfit(TheRHS, MRI));
}
-static bool applySwapICmpOperands(MachineInstr &MI,
- GISelChangeObserver &Observer) {
+static void applySwapICmpOperands(MachineInstr &MI,
+ GISelChangeObserver &Observer) {
auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
Register LHS = MI.getOperand(2).getReg();
Register RHS = MI.getOperand(3).getReg();
MI.getOperand(2).setReg(RHS);
MI.getOperand(3).setReg(LHS);
Observer.changedInstr(MI);
- return true;
}
/// \returns a function which builds a vector floating point compare instruction
return MRI.getType(SrcReg).getSizeInBits() <= 64;
}
-static bool applyFormTruncstore(MachineInstr &MI, MachineRegisterInfo &MRI,
+static void applyFormTruncstore(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &B,
GISelChangeObserver &Observer,
Register &SrcReg) {
Observer.changingInstr(MI);
MI.getOperand(0).setReg(SrcReg);
Observer.changedInstr(MI);
- return true;
}
// Lower vector G_SEXT_INREG back to shifts for selection. We allowed them to
return true;
}
-static bool applyICmpRedundantTrunc(MachineInstr &MI, MachineRegisterInfo &MRI,
+static void applyICmpRedundantTrunc(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &Builder,
GISelChangeObserver &Observer,
Register &WideReg) {
MI.getOperand(2).setReg(WideReg);
MI.getOperand(3).setReg(WideZero.getReg(0));
Observer.changedInstr(MI);
- return true;
}
/// \returns true if it is possible to fold a constant into a G_GLOBAL_VALUE.
return true;
}
-static bool applyFoldGlobalOffset(MachineInstr &MI, MachineRegisterInfo &MRI,
+static void applyFoldGlobalOffset(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &B,
GISelChangeObserver &Observer,
std::pair<uint64_t, uint64_t> &MatchInfo) {
B.buildPtrAdd(
Dst, NewGVDst,
B.buildConstant(LLT::scalar(64), -static_cast<int64_t>(MinOffset)));
- return true;
}
static bool tryToSimplifyUADDO(MachineInstr &MI, MachineIRBuilder &B,