[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