Index: llvm/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/lib/Analysis/ConstantFolding.cpp +++ llvm/lib/Analysis/ConstantFolding.cpp @@ -771,6 +771,7 @@ ArrayRef Ops, const DataLayout &DL, const TargetLibraryInfo *TLI) { + bool InBounds = GEP->isInBounds(); Type *SrcElemTy = GEP->getSourceElementType(); Type *ResElemTy = GEP->getResultElementType(); Type *ResTy = GEP->getType(); @@ -820,6 +821,8 @@ // If this is a GEP of a GEP, fold it all into a single GEP. while (auto *GEP = dyn_cast(Ptr)) { + InBounds &= GEP->isInBounds(); + SmallVector NestedOps(GEP->op_begin() + 1, GEP->op_end()); // Do not try the incorporate the sub-GEP if some index is not a number. @@ -926,7 +929,8 @@ return nullptr; // Create a GEP. - Constant *C = ConstantExpr::getGetElementPtr(SrcElemTy, Ptr, NewIdxs); + Constant *C = + ConstantExpr::getGetElementPtr(SrcElemTy, Ptr, NewIdxs, InBounds); assert(C->getType()->getPointerElementType() == Ty && "Computed GetElementPtr has unexpected type!"); Index: llvm/test/Other/constant-fold-gep.ll =================================================================== --- llvm/test/Other/constant-fold-gep.ll +++ llvm/test/Other/constant-fold-gep.ll @@ -106,9 +106,9 @@ ; PLAIN: @Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2) ; PLAIN: @Z = global i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1) -; OPT: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2) +; OPT: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2) ; OPT: @Z = local_unnamed_addr global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1) -; TO: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2) +; TO: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2) ; TO: @Z = local_unnamed_addr global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1) @ext = external global [3 x { i32, i32 }]