Index: llvm/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/lib/Analysis/ConstantFolding.cpp +++ llvm/lib/Analysis/ConstantFolding.cpp @@ -986,7 +986,7 @@ /// attempting to fold instructions like loads and stores, which have no /// constant expression form. /// -/// TODO: This function neither utilizes nor preserves nsw/nuw/inbounds/inrange +/// TODO: This function neither utilizes nor preserves nsw/nuw/inbounds /// etc information, due to only being passed an opcode and operands. Constant /// folding using this function strips this information. /// @@ -1004,6 +1004,10 @@ return ConstantFoldCastOperand(Opcode, Ops[0], DestTy, DL); if (auto *GEP = dyn_cast(InstOrCE)) { + // Do not optimize inrange GEPs + if (GEP->getInRangeIndex() != None) + return nullptr; + if (Constant *C = SymbolicallyEvaluateGEP(GEP, Ops, DL, TLI)) return C; Index: llvm/test/Other/optimize-inrange-gep.ll =================================================================== --- /dev/null +++ llvm/test/Other/optimize-inrange-gep.ll @@ -0,0 +1,18 @@ +; RUN: opt -O0 -S < %s | FileCheck %s +; RUN: opt -O1 -S < %s | FileCheck %s +; RUN: opt -O2 -S < %s | FileCheck %s +; RUN: opt -O3 -S < %s | FileCheck %s +; RUN: opt -Os -S < %s | FileCheck %s +; RUN: opt -Oz -S < %s | FileCheck %s + +target datalayout = "e-p:64:64" + +; Make sure that optimizations do not optimize inrange GEP. + +@vtable = constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* null, i8* null] } + +define void @foo(i8*** %p) { + ;CHECK: store i8** getelementptr {{.*}} ({ [3 x i8*] }, { [3 x i8*] }* @vtable, i32 0, inrange i32 0, i32 3), i8*** %p + store i8** getelementptr ({ [3 x i8*] }, { [3 x i8*] }* @vtable, i32 0, inrange i32 0, i32 3), i8*** %p + ret void +} \ No newline at end of file