[DAG] SDPatternMatch - rename m_Opc -> m_SpecificOpc (#190215)
Match naming convention for other m_Specific* matchers, and frees up the m_Opc() matcher for future use in #84940 to allow us to capture the opcode of a unknown binop Moving to m_SpecificOpc does mess up the formatting in a few places, I've tried to refactor to use the m_Value(SDValue, ....) matcher where I can to retrieve some whitespace
This commit is contained in:
parent
68b6a27771
commit
6832709dc0
@ -28,8 +28,8 @@ namespace llvm {
|
||||
namespace SDPatternMatch {
|
||||
|
||||
/// MatchContext can repurpose existing patterns to behave differently under
|
||||
/// a certain context. For instance, `m_Opc(ISD::ADD)` matches plain ADD nodes
|
||||
/// in normal circumstances, but matches VP_ADD nodes under a custom
|
||||
/// a certain context. For instance, `m_SpecificOpc(ISD::ADD)` matches plain ADD
|
||||
/// nodes in normal circumstances, but matches VP_ADD nodes under a custom
|
||||
/// VPMatchContext. This design is meant to facilitate code / pattern reusing.
|
||||
class BasicMatchContext {
|
||||
const SelectionDAG *DAG;
|
||||
@ -223,7 +223,9 @@ template <typename... Preds> auto m_NoneOf(const Preds &...preds) {
|
||||
return m_Unless(m_AnyOf(preds...));
|
||||
}
|
||||
|
||||
inline Opcode_match m_Opc(unsigned Opcode) { return Opcode_match(Opcode); }
|
||||
inline Opcode_match m_SpecificOpc(unsigned Opcode) {
|
||||
return Opcode_match(Opcode);
|
||||
}
|
||||
|
||||
inline auto m_Undef() {
|
||||
return m_AnyOf(Opcode_match(ISD::UNDEF), Opcode_match(ISD::POISON));
|
||||
@ -496,7 +498,8 @@ struct Operands_match<OpIdx, OpndPred, OpndPreds...>
|
||||
|
||||
template <typename... OpndPreds>
|
||||
auto m_Node(unsigned Opcode, const OpndPreds &...preds) {
|
||||
return m_AllOf(m_Opc(Opcode), Operands_match<0, OpndPreds...>(preds...));
|
||||
return m_AllOf(m_SpecificOpc(Opcode),
|
||||
Operands_match<0, OpndPreds...>(preds...));
|
||||
}
|
||||
|
||||
/// Provide number of operands that are not chain or glue, as well as the first
|
||||
@ -546,7 +549,7 @@ struct TernaryOpc_match {
|
||||
|
||||
template <typename MatchContext>
|
||||
bool match(const MatchContext &Ctx, SDValue N) {
|
||||
if (sd_context_match(N, Ctx, m_Opc(Opcode))) {
|
||||
if (sd_context_match(N, Ctx, m_SpecificOpc(Opcode))) {
|
||||
EffectiveOperands<ExcludeChain> EO(N, Ctx);
|
||||
assert(EO.Size == 3);
|
||||
return ((Op0.match(Ctx, N->getOperand(EO.FirstIndex)) &&
|
||||
@ -648,7 +651,7 @@ struct BinaryOpc_match {
|
||||
|
||||
template <typename MatchContext>
|
||||
bool match(const MatchContext &Ctx, SDValue N) {
|
||||
if (sd_context_match(N, Ctx, m_Opc(Opcode))) {
|
||||
if (sd_context_match(N, Ctx, m_SpecificOpc(Opcode))) {
|
||||
EffectiveOperands<ExcludeChain> EO(N, Ctx);
|
||||
assert(EO.Size == 2);
|
||||
if (!((LHS.match(Ctx, N->getOperand(EO.FirstIndex)) &&
|
||||
@ -723,15 +726,15 @@ struct MaxMin_match {
|
||||
(Commutable && LHS.match(Ctx, R) && RHS.match(Ctx, L));
|
||||
};
|
||||
|
||||
if (sd_context_match(N, Ctx, m_Opc(ISD::SELECT)) ||
|
||||
sd_context_match(N, Ctx, m_Opc(ISD::VSELECT))) {
|
||||
if (sd_context_match(N, Ctx, m_SpecificOpc(ISD::SELECT)) ||
|
||||
sd_context_match(N, Ctx, m_SpecificOpc(ISD::VSELECT))) {
|
||||
EffectiveOperands<ExcludeChain> EO_SELECT(N, Ctx);
|
||||
assert(EO_SELECT.Size == 3);
|
||||
SDValue Cond = N->getOperand(EO_SELECT.FirstIndex);
|
||||
SDValue TrueValue = N->getOperand(EO_SELECT.FirstIndex + 1);
|
||||
SDValue FalseValue = N->getOperand(EO_SELECT.FirstIndex + 2);
|
||||
|
||||
if (sd_context_match(Cond, Ctx, m_Opc(ISD::SETCC))) {
|
||||
if (sd_context_match(Cond, Ctx, m_SpecificOpc(ISD::SETCC))) {
|
||||
EffectiveOperands<ExcludeChain> EO_SETCC(Cond, Ctx);
|
||||
assert(EO_SETCC.Size == 3);
|
||||
SDValue L = Cond->getOperand(EO_SETCC.FirstIndex);
|
||||
@ -742,7 +745,7 @@ struct MaxMin_match {
|
||||
}
|
||||
}
|
||||
|
||||
if (sd_context_match(N, Ctx, m_Opc(ISD::SELECT_CC))) {
|
||||
if (sd_context_match(N, Ctx, m_SpecificOpc(ISD::SELECT_CC))) {
|
||||
EffectiveOperands<ExcludeChain> EO_SELECT(N, Ctx);
|
||||
assert(EO_SELECT.Size == 5);
|
||||
SDValue L = N->getOperand(EO_SELECT.FirstIndex);
|
||||
@ -1025,7 +1028,7 @@ template <typename Opnd_P, bool ExcludeChain = false> struct UnaryOpc_match {
|
||||
|
||||
template <typename MatchContext>
|
||||
bool match(const MatchContext &Ctx, SDValue N) {
|
||||
if (sd_context_match(N, Ctx, m_Opc(Opcode))) {
|
||||
if (sd_context_match(N, Ctx, m_SpecificOpc(Opcode))) {
|
||||
EffectiveOperands<ExcludeChain> EO(N, Ctx);
|
||||
assert(EO.Size == 1);
|
||||
if (!Opnd.match(Ctx, N->getOperand(EO.FirstIndex)))
|
||||
|
||||
@ -4935,7 +4935,7 @@ template <class MatchContextClass> SDValue DAGCombiner::visitMUL(SDNode *N) {
|
||||
}
|
||||
|
||||
// fold (mul (add x, c1), c2) -> (add (mul x, c2), c1*c2)
|
||||
if (sd_context_match(N0, Matcher, m_Opc(ISD::ADD)) &&
|
||||
if (sd_context_match(N0, Matcher, m_SpecificOpc(ISD::ADD)) &&
|
||||
isConstantOrConstantVector(N1) &&
|
||||
isConstantOrConstantVector(N0.getOperand(1)) &&
|
||||
isMulAddWithConstProfitable(N, N0, N1))
|
||||
@ -11561,15 +11561,17 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
|
||||
// fold (srl (logic_op x, (shl (zext y), c1)), c1)
|
||||
// -> (logic_op (srl x, c1), (zext y))
|
||||
// c1 <= leadingzeros(zext(y))
|
||||
// TODO: Replace c1 with valuetracking?
|
||||
SDValue X, ZExtY;
|
||||
if (N1C && sd_match(N0, m_OneUse(m_BitwiseLogic(
|
||||
m_Value(X),
|
||||
m_OneUse(m_Shl(m_AllOf(m_Value(ZExtY),
|
||||
m_Opc(ISD::ZERO_EXTEND)),
|
||||
m_Specific(N1))))))) {
|
||||
if (sd_match(
|
||||
N0,
|
||||
m_OneUse(m_BitwiseLogic(
|
||||
m_Value(X),
|
||||
m_OneUse(m_Shl(m_Value(ZExtY, m_SpecificOpc(ISD::ZERO_EXTEND)),
|
||||
m_Specific(N1))))))) {
|
||||
unsigned NumLeadingZeros = ZExtY.getScalarValueSizeInBits() -
|
||||
ZExtY.getOperand(0).getScalarValueSizeInBits();
|
||||
if (N1C->getZExtValue() <= NumLeadingZeros)
|
||||
if (N1C && N1C->getZExtValue() <= NumLeadingZeros)
|
||||
return DAG.getNode(N0.getOpcode(), SDLoc(N0), VT,
|
||||
DAG.getNode(ISD::SRL, SDLoc(N0), VT, X, N1), ZExtY);
|
||||
}
|
||||
|
||||
@ -17077,7 +17077,7 @@ static SDValue combineNarrowableShiftedLoad(SDNode *N, SelectionDAG &DAG) {
|
||||
APInt MaskVal, ShiftVal;
|
||||
// (and (shl (load ...), ShiftAmt), Mask)
|
||||
if (!sd_match(
|
||||
N, m_And(m_OneUse(m_Shl(m_AllOf(m_Opc(ISD::LOAD), m_Value(LoadNode)),
|
||||
N, m_And(m_OneUse(m_Shl(m_Value(LoadNode, m_SpecificOpc(ISD::LOAD)),
|
||||
m_ConstInt(ShiftVal))),
|
||||
m_ConstInt(MaskVal)))) {
|
||||
return SDValue();
|
||||
|
||||
@ -58877,11 +58877,12 @@ static SDValue matchPMADDWD(SelectionDAG &DAG, SDNode *N,
|
||||
return SDValue();
|
||||
|
||||
SDValue Op0, Op1, Accum;
|
||||
if (!sd_match(N, m_Add(m_AllOf(m_Opc(ISD::BUILD_VECTOR), m_Value(Op0)),
|
||||
m_AllOf(m_Opc(ISD::BUILD_VECTOR), m_Value(Op1)))) &&
|
||||
!sd_match(N, m_Add(m_AllOf(m_Opc(ISD::BUILD_VECTOR), m_Value(Op0)),
|
||||
m_Add(m_Value(Accum), m_AllOf(m_Opc(ISD::BUILD_VECTOR),
|
||||
m_Value(Op1))))))
|
||||
if (!sd_match(N, m_Add(m_Value(Op0, m_SpecificOpc(ISD::BUILD_VECTOR)),
|
||||
m_Value(Op1, m_SpecificOpc(ISD::BUILD_VECTOR)))) &&
|
||||
!sd_match(N,
|
||||
m_Add(m_Value(Op0, m_SpecificOpc(ISD::BUILD_VECTOR)),
|
||||
m_Add(m_Value(Accum),
|
||||
m_Value(Op1, m_SpecificOpc(ISD::BUILD_VECTOR))))))
|
||||
return SDValue();
|
||||
|
||||
// Check if one of Op0,Op1 is of the form:
|
||||
|
||||
@ -320,8 +320,8 @@ TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {
|
||||
EXPECT_TRUE(sd_match(Add, m_c_BinOp(ISD::ADD, m_Value(), m_Value())));
|
||||
EXPECT_TRUE(sd_match(Add, m_Add(m_Value(), m_Value())));
|
||||
EXPECT_TRUE(sd_match(Add, m_AddLike(m_Value(), m_Value())));
|
||||
EXPECT_TRUE(sd_match(
|
||||
Mul, m_Mul(m_OneUse(m_Opc(ISD::SUB)), m_NUses<2>(m_Specific(Add)))));
|
||||
EXPECT_TRUE(sd_match(Mul, m_Mul(m_OneUse(m_SpecificOpc(ISD::SUB)),
|
||||
m_NUses<2>(m_Specific(Add)))));
|
||||
EXPECT_TRUE(
|
||||
sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_SpecificVT(Float32VT),
|
||||
m_SpecificVT(Float32VT))));
|
||||
@ -467,21 +467,25 @@ TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {
|
||||
|
||||
SDValue BindVal;
|
||||
// By default, it matches any of the results.
|
||||
EXPECT_TRUE(
|
||||
sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI), m_Opc(ISD::SMUL_LOHI))));
|
||||
EXPECT_TRUE(sd_match(PartsDiff, m_Sub(m_SpecificOpc(ISD::SMUL_LOHI),
|
||||
m_SpecificOpc(ISD::SMUL_LOHI))));
|
||||
// Matching a specific result.
|
||||
EXPECT_TRUE(sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI),
|
||||
m_Result<1>(m_Opc(ISD::SMUL_LOHI)))));
|
||||
EXPECT_FALSE(sd_match(PartsDiff, m_Sub(m_Opc(ISD::SMUL_LOHI),
|
||||
m_Result<0>(m_Opc(ISD::SMUL_LOHI)))));
|
||||
EXPECT_TRUE(
|
||||
sd_match(PartsDiff, m_Sub(m_SpecificOpc(ISD::SMUL_LOHI),
|
||||
m_Result<1>(m_SpecificOpc(ISD::SMUL_LOHI)))));
|
||||
EXPECT_FALSE(
|
||||
sd_match(PartsDiff, m_Sub(m_SpecificOpc(ISD::SMUL_LOHI),
|
||||
m_Result<0>(m_SpecificOpc(ISD::SMUL_LOHI)))));
|
||||
|
||||
// Conditionally bind the value from a certain sub-pattern.
|
||||
EXPECT_TRUE(sd_match(PartsDiff, m_Sub(m_Value(BindVal, m_Opc(ISD::SMUL_LOHI)),
|
||||
m_Opc(ISD::SMUL_LOHI))));
|
||||
EXPECT_TRUE(
|
||||
sd_match(PartsDiff, m_Sub(m_Value(BindVal, m_SpecificOpc(ISD::SMUL_LOHI)),
|
||||
m_SpecificOpc(ISD::SMUL_LOHI))));
|
||||
EXPECT_EQ(BindVal, SMulLoHi);
|
||||
BindVal = SDValue();
|
||||
EXPECT_FALSE(sd_match(PartsDiff, m_Sub(m_Value(BindVal, m_Opc(ISD::ADD)),
|
||||
m_Opc(ISD::SMUL_LOHI))));
|
||||
EXPECT_FALSE(
|
||||
sd_match(PartsDiff, m_Sub(m_Value(BindVal, m_SpecificOpc(ISD::ADD)),
|
||||
m_SpecificOpc(ISD::SMUL_LOHI))));
|
||||
EXPECT_NE(BindVal, SMulLoHi);
|
||||
|
||||
BindVal = SDValue();
|
||||
@ -894,10 +898,12 @@ TEST_F(SelectionDAGPatternMatchTest, patternCombinators) {
|
||||
SDValue Sub = DAG->getNode(ISD::SUB, DL, Int32VT, Add, Op0);
|
||||
|
||||
using namespace SDPatternMatch;
|
||||
EXPECT_TRUE(
|
||||
sd_match(Sub, m_AnyOf(m_SpecificOpc(ISD::ADD), m_SpecificOpc(ISD::SUB),
|
||||
m_SpecificOpc(ISD::MUL))));
|
||||
EXPECT_TRUE(sd_match(Add, m_AllOf(m_SpecificOpc(ISD::ADD), m_OneUse())));
|
||||
EXPECT_TRUE(sd_match(
|
||||
Sub, m_AnyOf(m_Opc(ISD::ADD), m_Opc(ISD::SUB), m_Opc(ISD::MUL))));
|
||||
EXPECT_TRUE(sd_match(Add, m_AllOf(m_Opc(ISD::ADD), m_OneUse())));
|
||||
EXPECT_TRUE(sd_match(Add, m_NoneOf(m_Opc(ISD::SUB), m_Opc(ISD::MUL))));
|
||||
Add, m_NoneOf(m_SpecificOpc(ISD::SUB), m_SpecificOpc(ISD::MUL))));
|
||||
}
|
||||
|
||||
TEST_F(SelectionDAGPatternMatchTest, optionalResizing) {
|
||||
@ -1073,7 +1079,7 @@ TEST_F(SelectionDAGPatternMatchTest, matchContext) {
|
||||
|
||||
using namespace SDPatternMatch;
|
||||
VPMatchContext VPCtx(DAG.get());
|
||||
EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Opc(ISD::ADD)));
|
||||
EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_SpecificOpc(ISD::ADD)));
|
||||
EXPECT_TRUE(
|
||||
sd_context_match(VPAdd, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));
|
||||
// VPMatchContext can't match pattern using explicit VP Opcode
|
||||
@ -1086,11 +1092,12 @@ TEST_F(SelectionDAGPatternMatchTest, matchContext) {
|
||||
EXPECT_TRUE(sd_context_match(VPAdd, VPCtx, m_Add(m_Value(), m_Value())));
|
||||
// VP_REDUCE_ADD doesn't have a based opcode, so we use a normal
|
||||
// sd_match before switching to VPMatchContext when checking VPAdd.
|
||||
EXPECT_TRUE(sd_match(VPReduceAdd, m_Node(ISD::VP_REDUCE_ADD, m_Value(),
|
||||
m_Context(VPCtx, m_Opc(ISD::ADD)),
|
||||
m_Value(), m_Value())));
|
||||
EXPECT_TRUE(
|
||||
sd_match(VPReduceAdd, m_Node(ISD::VP_REDUCE_ADD, m_Value(),
|
||||
m_Context(VPCtx, m_SpecificOpc(ISD::ADD)),
|
||||
m_Value(), m_Value())));
|
||||
// non-vector predicated should match too
|
||||
EXPECT_TRUE(sd_context_match(Add, VPCtx, m_Opc(ISD::ADD)));
|
||||
EXPECT_TRUE(sd_context_match(Add, VPCtx, m_SpecificOpc(ISD::ADD)));
|
||||
EXPECT_TRUE(
|
||||
sd_context_match(Add, VPCtx, m_Node(ISD::ADD, m_Value(), m_Value())));
|
||||
EXPECT_FALSE(sd_context_match(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user