Skip to content

Commit 5c4f25c

Browse files
nikicJonChesterfield
authored andcommitted
[PatternMatch] Add m_PtrAdd() matcher (NFC)
This matches a getelementptr i8 instruction or constant expression, with a given pointer operand and index.
1 parent 85a6f26 commit 5c4f25c

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,21 @@ struct m_SplatOrUndefMask {
16141614
}
16151615
};
16161616

1617+
template <typename PointerOpTy, typename OffsetOpTy> struct PtrAdd_match {
1618+
PointerOpTy PointerOp;
1619+
OffsetOpTy OffsetOp;
1620+
1621+
PtrAdd_match(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
1622+
: PointerOp(PointerOp), OffsetOp(OffsetOp) {}
1623+
1624+
template <typename OpTy> bool match(OpTy *V) {
1625+
auto *GEP = dyn_cast<GEPOperator>(V);
1626+
return GEP && GEP->getSourceElementType()->isIntegerTy(8) &&
1627+
PointerOp.match(GEP->getPointerOperand()) &&
1628+
OffsetOp.match(GEP->idx_begin()->get());
1629+
}
1630+
};
1631+
16171632
/// Matches ShuffleVectorInst independently of mask value.
16181633
template <typename V1_t, typename V2_t>
16191634
inline TwoOps_match<V1_t, V2_t, Instruction::ShuffleVector>
@@ -1647,6 +1662,13 @@ inline auto m_GEP(const OperandTypes &...Ops) {
16471662
return AnyOps_match<Instruction::GetElementPtr, OperandTypes...>(Ops...);
16481663
}
16491664

1665+
/// Matches GEP with i8 source element type
1666+
template <typename PointerOpTy, typename OffsetOpTy>
1667+
inline PtrAdd_match<PointerOpTy, OffsetOpTy>
1668+
m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) {
1669+
return PtrAdd_match<PointerOpTy, OffsetOpTy>(PointerOp, OffsetOp);
1670+
}
1671+
16501672
//===----------------------------------------------------------------------===//
16511673
// Matchers for CastInst classes
16521674
//

llvm/unittests/IR/PatternMatch.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,4 +1847,26 @@ TEST_F(PatternMatchTest, ConstExpr) {
18471847
EXPECT_TRUE(match(V, m_ConstantExpr()));
18481848
}
18491849

1850+
TEST_F(PatternMatchTest, PtrAdd) {
1851+
Type *PtrTy = PointerType::getUnqual(Ctx);
1852+
Type *IdxTy = Type::getInt64Ty(Ctx);
1853+
Constant *Null = Constant::getNullValue(PtrTy);
1854+
Constant *Offset = ConstantInt::get(IdxTy, 42);
1855+
Value *PtrAdd = IRB.CreatePtrAdd(Null, Offset);
1856+
Value *OtherGEP = IRB.CreateGEP(IdxTy, Null, Offset);
1857+
Value *PtrAddConst =
1858+
ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx), Null, Offset);
1859+
1860+
Value *A, *B;
1861+
EXPECT_TRUE(match(PtrAdd, m_PtrAdd(m_Value(A), m_Value(B))));
1862+
EXPECT_EQ(A, Null);
1863+
EXPECT_EQ(B, Offset);
1864+
1865+
EXPECT_TRUE(match(PtrAddConst, m_PtrAdd(m_Value(A), m_Value(B))));
1866+
EXPECT_EQ(A, Null);
1867+
EXPECT_EQ(B, Offset);
1868+
1869+
EXPECT_FALSE(match(OtherGEP, m_PtrAdd(m_Value(A), m_Value(B))));
1870+
}
1871+
18501872
} // anonymous namespace.

0 commit comments

Comments
 (0)