[llvm] Preserve inbound of transformed GEPs (PR #86885)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 27 15:42:47 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: AtariDreams (AtariDreams)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/86885.diff


6 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+16) 
- (modified) llvm/lib/Transforms/Scalar/LoopFlatten.cpp (+1-1) 
- (modified) llvm/lib/Transforms/Scalar/NaryReassociate.cpp (+1-2) 
- (modified) llvm/lib/Transforms/Scalar/Scalarizer.cpp (+1-4) 
- (modified) llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp (+2-4) 
- (modified) llvm/test/Transforms/LoopFlatten/loop-flatten-gep.ll (+3-3) 


``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 7c40fb4fc86082..0f1c9aea32e6d5 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2895,6 +2895,12 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
       // as:
       //   %newptr = getelementptr i32, ptr %ptr, i64 %idx1
       //   %newgep = getelementptr i32, ptr %newptr, i64 %idx2
+      if (GEP.isInBounds()) {
+        auto *NewPtr = Builder.CreateInBoundsGEP(GEP.getResultElementType(),
+                                                 GEP.getPointerOperand(), Idx1);
+        return GetElementPtrInst::CreateInBounds(GEP.getResultElementType(),
+                                                 NewPtr, Idx2);
+      }
       auto *NewPtr = Builder.CreateGEP(GEP.getResultElementType(),
                                        GEP.getPointerOperand(), Idx1);
       return GetElementPtrInst::Create(GEP.getResultElementType(), NewPtr,
@@ -2909,6 +2915,16 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
       // as:
       // %newptr = getelementptr i32, ptr %ptr, i32 %idx1
       // %newgep = getelementptr i32, ptr %newptr, i32 idx2
+
+      if (GEP.isInBounds()) {
+        auto *NewPtr = Builder.CreateInBoundsGEP(
+            GEP.getResultElementType(), GEP.getPointerOperand(),
+            Builder.CreateSExt(Idx1, GEP.getOperand(1)->getType()));
+        return GetElementPtrInst::CreateInBounds(
+            GEP.getResultElementType(), NewPtr,
+            Builder.CreateSExt(C, GEP.getOperand(1)->getType()));
+      }
+
       auto *NewPtr = Builder.CreateGEP(
           GEP.getResultElementType(), GEP.getPointerOperand(),
           Builder.CreateSExt(Idx1, GEP.getOperand(1)->getType()));
diff --git a/llvm/lib/Transforms/Scalar/LoopFlatten.cpp b/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
index 0e9cf328f149be..f1bdc20140759c 100644
--- a/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
@@ -809,7 +809,7 @@ static bool DoFlattenLoopPair(FlattenInfo &FI, DominatorTree *DT, LoopInfo *LI,
       if (!DT->dominates(Base, &*Builder.GetInsertPoint()))
         Builder.SetInsertPoint(cast<Instruction>(V));
       OuterValue = Builder.CreateGEP(GEP->getSourceElementType(), Base,
-                                     OuterValue, "flatten." + V->getName());
+                                     OuterValue, "flatten." + V->getName(), GEP->isInBounds());
     }
 
     LLVM_DEBUG(dbgs() << "Replacing: "; V->dump(); dbgs() << "with:      ";
diff --git a/llvm/lib/Transforms/Scalar/NaryReassociate.cpp b/llvm/lib/Transforms/Scalar/NaryReassociate.cpp
index 308622615332f8..6ebe48813d77b8 100644
--- a/llvm/lib/Transforms/Scalar/NaryReassociate.cpp
+++ b/llvm/lib/Transforms/Scalar/NaryReassociate.cpp
@@ -457,8 +457,7 @@ NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
         RHS, ConstantInt::get(PtrIdxTy, IndexedSize / ElementSize));
   }
   GetElementPtrInst *NewGEP = cast<GetElementPtrInst>(
-      Builder.CreateGEP(GEP->getResultElementType(), Candidate, RHS));
-  NewGEP->setIsInBounds(GEP->isInBounds());
+      Builder.CreateGEP(GEP->getResultElementType(), Candidate, RHS, "", GEP->isInBounds()));
   NewGEP->takeName(GEP);
   return NewGEP;
 }
diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp
index 3eca9ac7c2673b..5301bd8b0c2f90 100644
--- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp
+++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp
@@ -847,10 +847,7 @@ bool ScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
     }
     Res[I] = Builder.CreateGEP(GEPI.getSourceElementType(), SplitOps[0],
                                ArrayRef(SplitOps).drop_front(),
-                               GEPI.getName() + ".i" + Twine(I));
-    if (GEPI.isInBounds())
-      if (GetElementPtrInst *NewGEPI = dyn_cast<GetElementPtrInst>(Res[I]))
-        NewGEPI->setIsInBounds();
+                               GEPI.getName() + ".i" + Twine(I), GEPI.isInBounds());
   }
   gather(&GEPI, Res, *VS);
   return true;
diff --git a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
index c54a956fc7e243..145c50104aab22 100644
--- a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
+++ b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
@@ -1020,11 +1020,9 @@ bool SeparateConstOffsetFromGEP::reorderGEP(GetElementPtrInst *GEP,
 
   // For trivial GEP chains, we can swap the indicies.
   auto NewSrc = Builder.CreateGEP(PtrGEPType, PtrGEP->getPointerOperand(),
-                                  SmallVector<Value *, 4>(GEP->indices()));
-  cast<GetElementPtrInst>(NewSrc)->setIsInBounds(IsChainInBounds);
+                                  SmallVector<Value *, 4>(GEP->indices()), "", IsChainInBounds);
   auto NewGEP = Builder.CreateGEP(GEPType, NewSrc,
-                                  SmallVector<Value *, 4>(PtrGEP->indices()));
-  cast<GetElementPtrInst>(NewGEP)->setIsInBounds(IsChainInBounds);
+                                  SmallVector<Value *, 4>(PtrGEP->indices()), "", IsChainInBounds);
   GEP->replaceAllUsesWith(NewGEP);
   RecursivelyDeleteTriviallyDeadInstructions(GEP);
   return true;
diff --git a/llvm/test/Transforms/LoopFlatten/loop-flatten-gep.ll b/llvm/test/Transforms/LoopFlatten/loop-flatten-gep.ll
index f4b8ea97237fe6..e30001670b1e95 100644
--- a/llvm/test/Transforms/LoopFlatten/loop-flatten-gep.ll
+++ b/llvm/test/Transforms/LoopFlatten/loop-flatten-gep.ll
@@ -15,7 +15,7 @@ for.outer.preheader:
   br label %for.inner.preheader
 
 ; CHECK-LABEL: for.inner.preheader:
-; CHECK: %flatten.arrayidx = getelementptr i32, ptr %A, i32 %i
+; CHECK: %flatten.arrayidx = getelementptr inbounds i32, ptr %A, i32 %i
 for.inner.preheader:
   %i = phi i32 [ 0, %for.outer.preheader ], [ %inc2, %for.outer ]
   br label %for.inner
@@ -61,13 +61,13 @@ for.outer.preheader:
   br label %for.inner.preheader
 
 ; CHECK-LABEL: for.inner.preheader:
-; CHECK-NOT: getelementptr i32, ptr %ptr, i32 %i
+; CHECK-NOT: getelementptr inbounds i32, ptr %ptr, i32 %i
 for.inner.preheader:
   %i = phi i32 [ 0, %for.outer.preheader ], [ %inc2, %for.outer ]
   br label %for.inner
 
 ; CHECK-LABEL: for.inner:
-; CHECK: %flatten.arrayidx = getelementptr i32, ptr %ptr, i32 %i
+; CHECK: %flatten.arrayidx = getelementptr inbounds i32, ptr %ptr, i32 %i
 ; CHECK: store i32 0, ptr %flatten.arrayidx, align 4
 ; CHECK: br label %for.outer
 for.inner:

``````````

</details>


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


More information about the llvm-commits mailing list