diff options
author | Florian Hahn <flo@fhahn.com> | 2025-01-30 20:58:38 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-30 20:58:38 +0000 |
commit | 55815b621b3a8f56a36c93229de1356e325a136f (patch) | |
tree | b41456d4e22d70229b81bbbd3248e2acbbe63346 /llvm/lib/IR/Value.cpp | |
parent | 9b52dbe0e0c3298438fd0a32495dd796b1d33970 (diff) | |
download | llvm-55815b621b3a8f56a36c93229de1356e325a136f.zip llvm-55815b621b3a8f56a36c93229de1356e325a136f.tar.gz llvm-55815b621b3a8f56a36c93229de1356e325a136f.tar.bz2 |
[Value] Look through inttoptr (add ..) in accumulateConstantOffsets (#124981)
Look through inttoptr (add (ptrtoint P), C) when accumulating offsets.
Adds a missing fold after
https://github.com/llvm/llvm-project/pull/123518
Alive2 for the tests with changes: https://alive2.llvm.org/ce/z/VvPrzv
PR: https://github.com/llvm/llvm-project/pull/124981
Diffstat (limited to 'llvm/lib/IR/Value.cpp')
-rw-r--r-- | llvm/lib/IR/Value.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index eddb672..b5a69b9 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -714,7 +714,8 @@ const Value *Value::stripPointerCastsForAliasAnalysis() const { const Value *Value::stripAndAccumulateConstantOffsets( const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup, - function_ref<bool(Value &, APInt &)> ExternalAnalysis) const { + function_ref<bool(Value &, APInt &)> ExternalAnalysis, + bool LookThroughIntToPtr) const { if (!getType()->isPtrOrPtrVectorTy()) return this; @@ -775,6 +776,24 @@ const Value *Value::stripAndAccumulateConstantOffsets( V = RV; if (AllowInvariantGroup && Call->isLaunderOrStripInvariantGroup()) V = Call->getArgOperand(0); + } else if (auto *Int2Ptr = dyn_cast<Operator>(V)) { + // Try to accumulate across (inttoptr (add (ptrtoint p), off)). + if (!AllowNonInbounds || !LookThroughIntToPtr || !Int2Ptr || + Int2Ptr->getOpcode() != Instruction::IntToPtr || + Int2Ptr->getOperand(0)->getType()->getScalarSizeInBits() != BitWidth) + return V; + + auto *Add = dyn_cast<AddOperator>(Int2Ptr->getOperand(0)); + if (!Add) + return V; + + auto *Ptr2Int = dyn_cast<PtrToIntOperator>(Add->getOperand(0)); + auto *CI = dyn_cast<ConstantInt>(Add->getOperand(1)); + if (!Ptr2Int || !CI) + return V; + + Offset += CI->getValue(); + V = Ptr2Int->getOperand(0); } assert(V->getType()->isPtrOrPtrVectorTy() && "Unexpected operand type!"); } while (Visited.insert(V).second); |