[llvm-branch-commits] [llvm] [IR] Account for byte width in m_PtrAdd (PR #106540)
Sergei Barannikov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Oct 6 20:53:44 PDT 2026
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106540
>From 44cc09c8d7ba15f017d167b37a4d19453103c92b Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Thu, 29 Aug 2024 00:54:20 +0300
Subject: [PATCH] [IR] Account for byte width in m_PtrAdd
The method has few uses yet, so just pass DL argument to it. The change
follows m_PtrToIntSameSize, and I don't see a better way of delivering
the byte width to the method.
---
llvm/include/llvm/IR/PatternMatch.h | 13 ++++++----
llvm/lib/Analysis/IVDescriptors.cpp | 3 ++-
llvm/lib/Analysis/InstructionSimplify.cpp | 2 +-
.../InstCombine/InstCombineCalls.cpp | 3 ++-
.../InstCombineSimplifyDemanded.cpp | 7 +++---
.../InstCombine/InstCombineVectorOps.cpp | 2 +-
.../InstCombine/InstructionCombining.cpp | 2 +-
.../Scalar/SeparateConstOffsetFromGEP.cpp | 5 ++--
llvm/unittests/IR/PatternMatch.cpp | 25 ++++++++++++++-----
9 files changed, 41 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 4b39b940338a9e..a0f9c37dcc596e 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -2059,15 +2059,17 @@ struct m_SplatOrPoisonMask {
};
template <typename PointerOpTy, typename OffsetOpTy> struct PtrAdd_match {
+ const DataLayout &DL;
PointerOpTy PointerOp;
OffsetOpTy OffsetOp;
- PtrAdd_match(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
- : PointerOp(PointerOp), OffsetOp(OffsetOp) {}
+ PtrAdd_match(const DataLayout &DL, const PointerOpTy &PointerOp,
+ const OffsetOpTy &OffsetOp)
+ : DL(DL), PointerOp(PointerOp), OffsetOp(OffsetOp) {}
template <typename OpTy> bool match(OpTy *V) const {
auto *GEP = dyn_cast<GEPOperator>(V);
- return GEP && GEP->getSourceElementType()->isIntegerTy(8) &&
+ return GEP && GEP->getSourceElementType()->isIntegerTy(DL.getByteWidth()) &&
PointerOp.match(GEP->getPointerOperand()) &&
OffsetOp.match(GEP->idx_begin()->get());
}
@@ -2125,8 +2127,9 @@ inline auto m_GEP(const OperandTypes &...Ops) {
/// Matches GEP with i8 source element type
template <typename PointerOpTy, typename OffsetOpTy>
inline PtrAdd_match<PointerOpTy, OffsetOpTy>
-m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) {
- return PtrAdd_match<PointerOpTy, OffsetOpTy>(PointerOp, OffsetOp);
+m_PtrAdd(const DataLayout &DL, const PointerOpTy &PointerOp,
+ const OffsetOpTy &OffsetOp) {
+ return PtrAdd_match<PointerOpTy, OffsetOpTy>(DL, PointerOp, OffsetOp);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp
index a7d572de681e71..8e98629ff3eee3 100644
--- a/llvm/lib/Analysis/IVDescriptors.cpp
+++ b/llvm/lib/Analysis/IVDescriptors.cpp
@@ -1753,7 +1753,8 @@ bool ConditionalInductionDescriptor::isConditionalInductionPHI(
Value *Step = nullptr;
bool StepMatch =
PN->getType()->isPointerTy()
- ? match(StepInst, m_PtrAdd(m_Specific(PN), m_Value(Step)))
+ ? match(StepInst,
+ m_PtrAdd(PN->getDataLayout(), m_Specific(PN), m_Value(Step)))
: match(StepInst, m_c_Add(m_Specific(PN), m_Value(Step)));
if (!StepMatch || !L->isLoopInvariant(Step))
return false;
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 74a266660b2341..7e444cb6d1cc79 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5701,7 +5701,7 @@ static Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
Value *Ptr, *X;
if (CastOpc == Instruction::PtrToAddr &&
match(Op,
- m_PtrAdd(m_Value(Ptr),
+ m_PtrAdd(Q.DL, m_Value(Ptr),
m_Sub(m_Value(X), m_PtrToIntOrAddr(m_Deferred(Ptr))))) &&
X->getType() == Ty && Ty == Q.DL.getIndexType(Ptr->getType()))
return X;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index e9b99d87cbbb5d..98662ca6dc4ad4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3894,7 +3894,8 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
Value *BasePtr;
const APInt *PtrOffset;
- if (match(Ptr.get(), m_PtrAdd(m_Value(BasePtr), m_APInt(PtrOffset)))) {
+ if (match(Ptr.get(),
+ m_PtrAdd(DL, m_Value(BasePtr), m_APInt(PtrOffset)))) {
auto PtrOffsetVal =
PtrOffset->sextOrTrunc(DL.getIndexTypeSizeInBits(Ptr->getType()))
.trySExtValue();
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index b121ff7ebc4417..41e749dbb85e70 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1059,9 +1059,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
Value *InnerPtr;
uint64_t GEPIndex;
uint64_t PtrMaskImmediate;
- if (match(I, m_Intrinsic<Intrinsic::ptrmask>(
- m_PtrAdd(m_Value(InnerPtr), m_ConstantInt(GEPIndex)),
- m_ConstantInt(PtrMaskImmediate)))) {
+ if (match(I,
+ m_Intrinsic<Intrinsic::ptrmask>(
+ m_PtrAdd(DL, m_Value(InnerPtr), m_ConstantInt(GEPIndex)),
+ m_ConstantInt(PtrMaskImmediate)))) {
LHSKnown = computeKnownBits(InnerPtr, I, Depth + 1);
if (!LHSKnown.isZero()) {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 3f3a27397250a7..5aa7007ea3b580 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -439,7 +439,7 @@ foldExtractOfStridedPointerVector(ExtractElementInst &EI,
const APInt *C;
APInt Offset(IdxWidth, 0);
// m_Value may bind even when the offset is not constant, so reset it.
- if (match(Elt, m_PtrAdd(m_Value(EltBase), m_APInt(C))))
+ if (match(Elt, m_PtrAdd(DL, m_Value(EltBase), m_APInt(C))))
Offset = C->sextOrTrunc(IdxWidth);
else
EltBase = Elt;
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 265310ea0ff41f..c44ed8b6bbda20 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2764,7 +2764,7 @@ static Instruction *canonicalizeGEPOfConstGEPI8(GetElementPtrInst &GEP,
auto &DL = IC.getDataLayout();
Value *Base;
const APInt *C1;
- if (!match(Src, m_PtrAdd(m_Value(Base), m_APInt(C1))))
+ if (!match(Src, m_PtrAdd(DL, m_Value(Base), m_APInt(C1))))
return nullptr;
Value *VarIndex;
const APInt *C2;
diff --git a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
index 8267305468c821..a07b64b6884133 100644
--- a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
+++ b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
@@ -1171,8 +1171,9 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
// offset from each is accumulated.
Value *NewBase;
const APInt *BaseOffset;
- bool ExtractBase = match(GEP->getPointerOperand(),
- m_PtrAdd(m_Value(NewBase), m_APInt(BaseOffset)));
+ bool ExtractBase =
+ match(GEP->getPointerOperand(),
+ m_PtrAdd(*DL, m_Value(NewBase), m_APInt(BaseOffset)));
unsigned IdxWidth = DL->getIndexTypeSizeInBits(GEP->getType());
APInt BaseByteOffset =
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 2cad6b38a5e94c..98925a8587612d 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -2712,26 +2712,39 @@ TEST_F(PatternMatchTest, ConstExpr) {
EXPECT_TRUE(match(V, m_ConstantExpr()));
}
-TEST_F(PatternMatchTest, PtrAdd) {
+// PatternMatchTest parametrized by byte width.
+class PatternMatchByteParamTest
+ : public PatternMatchTest,
+ public ::testing::WithParamInterface<unsigned> {
+public:
+ PatternMatchByteParamTest() {
+ M->setDataLayout("b:" + std::to_string(GetParam()));
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(ByteWidths, PatternMatchByteParamTest,
+ ::testing::Values(8, 16, 32));
+
+TEST_P(PatternMatchByteParamTest, PtrAdd) {
+ const DataLayout &DL = M->getDataLayout();
Type *PtrTy = PointerType::getUnqual(Ctx);
Type *IdxTy = Type::getInt64Ty(Ctx);
Constant *Null = Constant::getNullValue(PtrTy);
Constant *Offset = ConstantInt::get(IdxTy, 42);
Value *PtrAdd = IRB.CreatePtrAdd(Null, Offset);
Value *OtherGEP = IRB.CreateGEP(IdxTy, Null, Offset);
- Value *PtrAddConst =
- ConstantExpr::getPtrAdd(M->getDataLayout(), Null, Offset);
+ Value *PtrAddConst = ConstantExpr::getPtrAdd(DL, Null, Offset);
Value *A, *B;
- EXPECT_TRUE(match(PtrAdd, m_PtrAdd(m_Value(A), m_Value(B))));
+ EXPECT_TRUE(match(PtrAdd, m_PtrAdd(DL, m_Value(A), m_Value(B))));
EXPECT_EQ(A, Null);
EXPECT_EQ(B, Offset);
- EXPECT_TRUE(match(PtrAddConst, m_PtrAdd(m_Value(A), m_Value(B))));
+ EXPECT_TRUE(match(PtrAddConst, m_PtrAdd(DL, m_Value(A), m_Value(B))));
EXPECT_EQ(A, Null);
EXPECT_EQ(B, Offset);
- EXPECT_FALSE(match(OtherGEP, m_PtrAdd(m_Value(A), m_Value(B))));
+ EXPECT_FALSE(match(OtherGEP, m_PtrAdd(DL, m_Value(A), m_Value(B))));
}
TEST_F(PatternMatchTest, ShiftOrSelf) {
More information about the llvm-branch-commits
mailing list