[llvm] [InstCombine] Relax the same-underlying-object constraint for the GEP canonicalization (PR #76583)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 31 03:43:45 PST 2023
================
@@ -2471,14 +2471,37 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
if (TyAllocSize == 1) {
// Canonicalize (gep i8* X, (ptrtoint Y)-(ptrtoint X)) to (bitcast Y),
- // but only if both point to the same underlying object (otherwise
- // provenance is not necessarily retained).
+ // but only if the result pointer is only used as if it were an integer,
+ // or both point to the same underlying object (otherwise provenance is
+ // not necessarily retained).
Value *X = GEP.getPointerOperand();
Value *Y;
if (match(GEP.getOperand(1),
- m_Sub(m_PtrToInt(m_Value(Y)), m_PtrToInt(m_Specific(X)))) &&
- getUnderlyingObject(X) == getUnderlyingObject(Y))
- return CastInst::CreatePointerBitCastOrAddrSpaceCast(Y, GEPType);
+ m_Sub(m_PtrToInt(m_Value(Y)), m_PtrToInt(m_Specific(X))))) {
+ std::optional<bool> HasSameUnderlyingObjectCache;
+ auto HasSameUnderlyingObject = [&] {
+ if (!HasSameUnderlyingObjectCache)
+ HasSameUnderlyingObjectCache =
+ getUnderlyingObject(X) == getUnderlyingObject(Y);
+ return *HasSameUnderlyingObjectCache;
+ };
+ std::optional<Value *> CastedValueCache;
+ auto GetCastedValue = [&] {
+ if (!CastedValueCache)
+ CastedValueCache =
+ Builder.CreatePointerBitCastOrAddrSpaceCast(Y, GEPType);
+ return *CastedValueCache;
+ };
+
+ bool Changed = false;
+ for (User *U : GEP.users())
----------------
nikic wrote:
You can use `replaceUsesWithIf()`.
https://github.com/llvm/llvm-project/pull/76583
More information about the llvm-commits
mailing list