diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4349,11 +4349,9 @@ // doesn't truncate the pointers. if (Ops[1]->getType()->getScalarSizeInBits() == Q.DL.getPointerSizeInBits(AS)) { - auto CanSimplify = [GEPTy, &P]() -> bool { - // FIXME: The following transforms are only legal if P and V have the - // same provenance (PR44403). Check whether getUnderlyingObject() is - // the same? - return P->getType() == GEPTy; + auto CanSimplify = [GEPTy, &P, V = Ops[0]]() -> bool { + return P->getType() == GEPTy && + getUnderlyingObject(P) == getUnderlyingObject(V); }; // getelementptr V, (sub P, V) -> P if P points to a type of size 1. if (TyAllocSize == 1 && diff --git a/llvm/test/Transforms/InstSimplify/gep.ll b/llvm/test/Transforms/InstSimplify/gep.ll --- a/llvm/test/Transforms/InstSimplify/gep.ll +++ b/llvm/test/Transforms/InstSimplify/gep.ll @@ -7,7 +7,12 @@ define %struct.A* @test1(%struct.A* %b, %struct.A* %e) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: ret %struct.A* [[E:%.*]] +; CHECK-NEXT: [[E_PTR:%.*]] = ptrtoint %struct.A* [[E:%.*]] to i64 +; CHECK-NEXT: [[B_PTR:%.*]] = ptrtoint %struct.A* [[B:%.*]] to i64 +; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[E_PTR]], [[B_PTR]] +; CHECK-NEXT: [[SDIV:%.*]] = sdiv exact i64 [[SUB]], 7 +; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[B]], i64 [[SDIV]] +; CHECK-NEXT: ret %struct.A* [[GEP]] ; %e_ptr = ptrtoint %struct.A* %e to i64 %b_ptr = ptrtoint %struct.A* %b to i64 @@ -19,7 +24,11 @@ define i8* @test2(i8* %b, i8* %e) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: ret i8* [[E:%.*]] +; CHECK-NEXT: [[E_PTR:%.*]] = ptrtoint i8* [[E:%.*]] to i64 +; CHECK-NEXT: [[B_PTR:%.*]] = ptrtoint i8* [[B:%.*]] to i64 +; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[E_PTR]], [[B_PTR]] +; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, i8* [[B]], i64 [[SUB]] +; CHECK-NEXT: ret i8* [[GEP]] ; %e_ptr = ptrtoint i8* %e to i64 %b_ptr = ptrtoint i8* %b to i64 @@ -30,7 +39,12 @@ define i64* @test3(i64* %b, i64* %e) { ; CHECK-LABEL: @test3( -; CHECK-NEXT: ret i64* [[E:%.*]] +; CHECK-NEXT: [[E_PTR:%.*]] = ptrtoint i64* [[E:%.*]] to i64 +; CHECK-NEXT: [[B_PTR:%.*]] = ptrtoint i64* [[B:%.*]] to i64 +; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[E_PTR]], [[B_PTR]] +; CHECK-NEXT: [[ASHR:%.*]] = ashr exact i64 [[SUB]], 3 +; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, i64* [[B]], i64 [[ASHR]] +; CHECK-NEXT: ret i64* [[GEP]] ; %e_ptr = ptrtoint i64* %e to i64 %b_ptr = ptrtoint i64* %b to i64