diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -2298,6 +2298,29 @@ return ExtractValue_match(V); } +/// Matcher for a single index InsertValue instruction. +template struct InsertValue_match { + T0 Op0; + T1 Op1; + + InsertValue_match(const T0 &Op0, const T1 &Op1) : Op0(Op0), Op1(Op1) {} + + template bool match(OpTy *V) { + if (auto *I = dyn_cast(V)) { + return Op0.match(I->getOperand(0)) && Op1.match(I->getOperand(1)) && + I->getNumIndices() == 1 && Ind == I->getIndices()[0]; + } + return false; + } +}; + +/// Matches a single index InsertValue instruction. +template +inline InsertValue_match m_InsertValue(const Val_t &Val, + const Elt_t &Elt) { + return InsertValue_match(Val, Elt); +} + /// Matches patterns for `vscale`. This can either be a call to `llvm.vscale` or /// the constant expression /// `ptrtoint(gep , * null, i32 1>` diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -1581,6 +1581,27 @@ match(CF32NaNWithUndef, cstfp_pred_ty>())); } +TEST_F(PatternMatchTest, InsertValue) { + Type *StructTy = StructType::create(IRB.getContext(), + {IRB.getInt32Ty(), IRB.getInt64Ty()}); + Value *Ins0 = + IRB.CreateInsertValue(UndefValue::get(StructTy), IRB.getInt32(20), 0); + Value *Ins1 = IRB.CreateInsertValue(Ins0, IRB.getInt64(90), 1); + + EXPECT_TRUE(match(Ins0, m_InsertValue<0>(m_Value(), m_Value()))); + EXPECT_FALSE(match(Ins0, m_InsertValue<1>(m_Value(), m_Value()))); + EXPECT_FALSE(match(Ins1, m_InsertValue<0>(m_Value(), m_Value()))); + EXPECT_TRUE(match(Ins1, m_InsertValue<1>(m_Value(), m_Value()))); + + EXPECT_TRUE(match(Ins0, m_InsertValue<0>(m_Undef(), m_SpecificInt(20)))); + EXPECT_FALSE(match(Ins0, m_InsertValue<0>(m_Undef(), m_SpecificInt(0)))); + + EXPECT_TRUE( + match(Ins1, m_InsertValue<1>(m_InsertValue<0>(m_Value(), m_Value()), + m_SpecificInt(90)))); + EXPECT_FALSE(match(IRB.getInt64(99), m_InsertValue<0>(m_Value(), m_Value()))); +} + template struct MutableConstTest : PatternMatchTest { }; typedef ::testing::Types,