[llvm] [SeparateConstOffsetFromGEP] Reorder trivial GEP chains to separate constants (PR #73056)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 21 17:59:20 PST 2023


================
@@ -987,11 +987,50 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
   bool NeedsExtraction;
   int64_t AccumulativeByteOffset = accumulateByteOffset(GEP, NeedsExtraction);
 
-  if (!NeedsExtraction)
-    return Changed;
-
   TargetTransformInfo &TTI = GetTTI(*GEP->getFunction());
 
+  if (!NeedsExtraction) {
+    // Attempt to reassociate GEPs for better AddrMode construction.
+    if (auto PtrGEP = dyn_cast<GetElementPtrInst>(GEP->getPointerOperand())) {
+      // TODO: support reordering for non-trivial GEP chains
+      if (PtrGEP->getNumIndices() != 1 || GEP->getNumIndices() != 1)
+        return Changed;
+
+      Type *GEPType = GEP->getResultElementType();
+      Type *PtrGEPType = PtrGEP->getResultElementType();
+      // TODO: support reordering for non-trivial GEP chains
+      if ((PtrGEPType != GEPType) ||
+          (PtrGEP->getSourceElementType() != GEP->getSourceElementType()))
+        return Changed;
+
+      bool NestedNeedsExtraction;
+      int64_t NestedByteOffset =
+          accumulateByteOffset(PtrGEP, NestedNeedsExtraction);
+      if (!NestedNeedsExtraction)
+        return Changed;
+
+      unsigned AddrSpace = PtrGEP->getPointerAddressSpace();
+      if (!TTI.isLegalAddressingMode(GEP->getResultElementType(),
+                                     /*BaseGV=*/nullptr, NestedByteOffset,
+                                     /*HasBaseReg=*/true, /*Scale=*/0,
+                                     AddrSpace)) {
+        return Changed;
+      }
+
+      IRBuilder<> Builder(GEP);
+      Builder.SetCurrentDebugLocation(GEP->getDebugLoc());
+      // For trivial GEP chains, we can swap the indicies.
+      auto NewSrc = Builder.CreateGEP(PtrGEPType, PtrGEP->getPointerOperand(),
----------------
arsenm wrote:

Can this preserve inbounds? Can you add some mixed inbounds usage tests?

https://github.com/llvm/llvm-project/pull/73056


More information about the llvm-commits mailing list