[ConstantFold] Fix GEP of GEP fold with opaque pointers
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 23 Jul 2021 21:56:41 +0000 (23:56 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 23 Jul 2021 21:56:41 +0000 (23:56 +0200)
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.

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

index ca14787..5f05aa2 100644 (file)
@@ -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:
index ee7c752..7d84395 100644 (file)
@@ -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>)