Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions llvm/include/llvm/CodeGen/SDPatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,11 @@ inline BinaryOpc_match<LHS, RHS, true> m_Xor(const LHS &L, const RHS &R) {
return BinaryOpc_match<LHS, RHS, true>(ISD::XOR, L, R);
}

template <typename LHS, typename RHS>
inline auto m_BitwiseLogic(const LHS &L, const RHS &R) {
return m_AnyOf(m_And(L, R), m_Or(L, R), m_Xor(L, R));
}

template <typename LHS, typename RHS>
inline BinaryOpc_match<LHS, RHS, true> m_SMin(const LHS &L, const RHS &R) {
return BinaryOpc_match<LHS, RHS, true>(ISD::SMIN, L, R);
Expand Down
31 changes: 11 additions & 20 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10553,29 +10553,20 @@ static SDValue foldBitOrderCrossLogicOp(SDNode *N, SelectionDAG &DAG) {
SDValue N0 = N->getOperand(0);
EVT VT = N->getValueType(0);
SDLoc DL(N);
if (ISD::isBitwiseLogicOp(N0.getOpcode()) && N0.hasOneUse()) {
SDValue OldLHS = N0.getOperand(0);
SDValue OldRHS = N0.getOperand(1);

// If both operands are bswap/bitreverse, ignore the multiuse
// Otherwise need to ensure logic_op and bswap/bitreverse(x) have one use.
if (OldLHS.getOpcode() == Opcode && OldRHS.getOpcode() == Opcode) {
return DAG.getNode(N0.getOpcode(), DL, VT, OldLHS.getOperand(0),
OldRHS.getOperand(0));
}
SDValue X, Y;

if (OldLHS.getOpcode() == Opcode && OldLHS.hasOneUse()) {
SDValue NewBitReorder = DAG.getNode(Opcode, DL, VT, OldRHS);
return DAG.getNode(N0.getOpcode(), DL, VT, OldLHS.getOperand(0),
NewBitReorder);
}
// If both operands are bswap/bitreverse, ignore the multiuse
if (sd_match(N0, m_OneUse(m_BitwiseLogic(m_UnaryOp(Opcode, m_Value(X)),
m_UnaryOp(Opcode, m_Value(Y))))))
return DAG.getNode(N0.getOpcode(), DL, VT, X, Y);

if (OldRHS.getOpcode() == Opcode && OldRHS.hasOneUse()) {
SDValue NewBitReorder = DAG.getNode(Opcode, DL, VT, OldLHS);
return DAG.getNode(N0.getOpcode(), DL, VT, NewBitReorder,
OldRHS.getOperand(0));
}
// Otherwise need to ensure logic_op and bswap/bitreverse(x) have one use.
if (sd_match(N0, m_OneUse(m_BitwiseLogic(
m_OneUse(m_UnaryOp(Opcode, m_Value(X))), m_Value(Y))))) {
SDValue NewBitReorder = DAG.getNode(Opcode, DL, VT, Y);
return DAG.getNode(N0.getOpcode(), DL, VT, X, NewBitReorder);
}

return SDValue();
}

Expand Down
5 changes: 5 additions & 0 deletions llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,13 +302,18 @@ TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) {
EXPECT_TRUE(
sd_match(SFAdd, m_ChainedBinOp(ISD::STRICT_FADD, m_SpecificVT(Float32VT),
m_SpecificVT(Float32VT))));
EXPECT_FALSE(sd_match(Add, m_BitwiseLogic(m_Value(), m_Value())));
EXPECT_FALSE(sd_match(Sub, m_BitwiseLogic(m_Value(), m_Value())));

EXPECT_TRUE(sd_match(And, m_c_BinOp(ISD::AND, m_Value(), m_Value())));
EXPECT_TRUE(sd_match(And, m_And(m_Value(), m_Value())));
EXPECT_TRUE(sd_match(And, m_BitwiseLogic(m_Value(), m_Value())));
EXPECT_TRUE(sd_match(Xor, m_c_BinOp(ISD::XOR, m_Value(), m_Value())));
EXPECT_TRUE(sd_match(Xor, m_Xor(m_Value(), m_Value())));
EXPECT_TRUE(sd_match(Xor, m_BitwiseLogic(m_Value(), m_Value())));
EXPECT_TRUE(sd_match(Or, m_c_BinOp(ISD::OR, m_Value(), m_Value())));
EXPECT_TRUE(sd_match(Or, m_Or(m_Value(), m_Value())));
EXPECT_TRUE(sd_match(Or, m_BitwiseLogic(m_Value(), m_Value())));
EXPECT_FALSE(sd_match(Or, m_DisjointOr(m_Value(), m_Value())));

EXPECT_TRUE(sd_match(DisOr, m_Or(m_Value(), m_Value())));
Expand Down
Loading