diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h index 4faa090901a6a..4488a6152117c 100644 --- a/llvm/include/llvm/CodeGen/SDPatternMatch.h +++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h @@ -896,6 +896,10 @@ inline UnaryOpc_match m_ChainedUnaryOp(unsigned Opc, return UnaryOpc_match(Opc, Op); } +template inline UnaryOpc_match m_BitCast(const Opnd &Op) { + return UnaryOpc_match(ISD::BITCAST, Op); +} + template inline UnaryOpc_match m_BSwap(const Opnd &Op) { return UnaryOpc_match(ISD::BSWAP, Op); diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index de7fb21f5903e..49e5b7d9ef014 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -15770,7 +15770,7 @@ SDValue DAGCombiner::foldBitcastedFPLogic(SDNode *N, SelectionDAG &DAG, // FIXME: I don't think looking for bitcast intrinsically makes sense, but // removing this would require more changes. auto IsBitCastOrFree = [&TLI, FPOpcode](SDValue Op, EVT VT) { - if (Op.getOpcode() == ISD::BITCAST && Op.getOperand(0).getValueType() == VT) + if (sd_match(Op, m_BitCast(m_SpecificVT(VT)))) return true; return FPOpcode == ISD::FABS ? TLI.isFAbsFree(VT) : TLI.isFNegFree(VT); diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp index bf9c597d8ac5e..736a36da97f57 100644 --- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp @@ -392,6 +392,7 @@ TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) { SDValue FPToSI = DAG->getNode(ISD::FP_TO_SINT, DL, FloatVT, Op2); SDValue FPToUI = DAG->getNode(ISD::FP_TO_UINT, DL, FloatVT, Op2); + SDValue Bcast = DAG->getNode(ISD::BITCAST, DL, FloatVT, Op0); SDValue Brev = DAG->getNode(ISD::BITREVERSE, DL, Int32VT, Op0); SDValue Bswap = DAG->getNode(ISD::BSWAP, DL, Int32VT, Op0); @@ -423,8 +424,12 @@ TEST_F(SelectionDAGPatternMatchTest, matchUnaryOp) { EXPECT_FALSE(sd_match(FPToUI, m_FPToSI(m_Value()))); EXPECT_FALSE(sd_match(FPToSI, m_FPToUI(m_Value()))); + EXPECT_TRUE(sd_match(Bcast, m_BitCast(m_Value()))); + EXPECT_TRUE(sd_match(Bcast, m_BitCast(m_SpecificVT(MVT::i32)))); EXPECT_TRUE(sd_match(Brev, m_BitReverse(m_Value()))); EXPECT_TRUE(sd_match(Bswap, m_BSwap(m_Value()))); + EXPECT_FALSE(sd_match(Bcast, m_BitReverse(m_Value()))); + EXPECT_FALSE(sd_match(Bcast, m_BitCast(m_SpecificVT(MVT::f32)))); EXPECT_FALSE(sd_match(Brev, m_BSwap(m_Value()))); EXPECT_FALSE(sd_match(Bswap, m_BitReverse(m_Value())));