[llvm] f623b3a - [ConstantFold] Fix GEP of GEP fold with opaque pointers

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 23 14:59:00 PDT 2021


Author: Nikita Popov
Date: 2021-07-23T23:56:41+02:00
New Revision: f623b3a29aa9932fedf5b043b0f3b7535a19fdb7

URL: https://github.com/llvm/llvm-project/commit/f623b3a29aa9932fedf5b043b0f3b7535a19fdb7
DIFF: https://github.com/llvm/llvm-project/commit/f623b3a29aa9932fedf5b043b0f3b7535a19fdb7.diff

LOG: [ConstantFold] Fix GEP of GEP fold with opaque pointers

This was previously combining indices even though they operate on
different types. For non-opaque pointers, the condition is
automatically satisfied based on the pointer types being equal.

Added: 
    

Modified: 
    llvm/lib/IR/ConstantFold.cpp
    llvm/test/Other/force-opaque-ptrs.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index ca1478787606..5f05aa2e94e7 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -2347,8 +2347,11 @@ static bool isIndexInRangeOfArrayType(uint64_t NumElements,
 // Combine Indices - If the source pointer to this getelementptr instruction
 // is a getelementptr instruction, combine the indices of the two
 // getelementptr instructions into a single instruction.
-static Constant *foldGEPOfGEP(GEPOperator *GEP, bool InBounds,
+static Constant *foldGEPOfGEP(GEPOperator *GEP, Type *PointeeTy, bool InBounds,
                               ArrayRef<Value *> Idxs) {
+  if (PointeeTy != GEP->getResultElementType())
+    return nullptr;
+
   Constant *Idx0 = cast<Constant>(Idxs[0]);
   if (Idx0->isNullValue()) {
     // Handle the simple case of a zero index.
@@ -2491,7 +2494,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
 
   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
     if (auto *GEP = dyn_cast<GEPOperator>(CE))
-      if (Constant *C = foldGEPOfGEP(GEP, InBounds, Idxs))
+      if (Constant *C = foldGEPOfGEP(GEP, PointeeTy, InBounds, Idxs))
         return C;
 
     // Attempt to fold casts to the same type away.  For example, folding:

diff  --git a/llvm/test/Other/force-opaque-ptrs.ll b/llvm/test/Other/force-opaque-ptrs.ll
index ee7c752de411..7d843950ea70 100644
--- a/llvm/test/Other/force-opaque-ptrs.ll
+++ b/llvm/test/Other/force-opaque-ptrs.ll
@@ -64,6 +64,13 @@ define void @remangle_intrinsic() {
   ret void
 }
 
+define i32* @constexpr_gep() {
+; CHECK-LABEL: define {{[^@]+}}@constexpr_gep() {
+; CHECK-NEXT:    ret ptr getelementptr (i32, ptr getelementptr (i8, ptr null, i64 4), i64 1)
+;
+  ret i32* getelementptr(i32, i32* bitcast (i8* getelementptr (i8, i8* null, i64 4) to i32*), i64 1)
+}
+
 declare i8* @llvm.stacksave()
 declare void @llvm.stackprotector(i8*, i8**)
 declare <2 x i64> @llvm.masked.expandload.v2i64(i64*, <2 x i1>, <2 x i64>)


        


More information about the llvm-commits mailing list