// 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.
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:
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>)