diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -344,6 +344,34 @@ if (isDereferenceableAndAlignedPointer(Ptr, Align(1), APInt(64, 1), DL)) { return new BitCastInst(Ptr, CI.getDestTy()); } + // Vector to find out all target users of roundtrip (int2ptr/ptr2int) cast + // which are dominated by load/store instruction of same address as of + // roundtripcast. + SmallVector TargetUsers; + Instruction *I; + for (auto *CU : CI.users()) { + if (!(I = dyn_cast(CU))) + continue; + int NumIterations = 0; + for (auto *U : Ptr->users()) { + if (NumIterations == 10) + goto DoneWithUsers; + NumIterations++; + if ((isa(U) || isa(U)) && + DT.dominates(cast(U), I)) { + TargetUsers.push_back(CU); + break; + } + } + } + DoneWithUsers: + if (!TargetUsers.empty()) { + Value *BitCast = Builder.CreateBitCast(Ptr, CI.getDestTy()); + for (auto *U : TargetUsers) { + U->replaceUsesOfWith(&CI, BitCast); + } + return &CI; + } } return nullptr; } diff --git a/llvm/test/Transforms/InstCombine/load-int2ptr-fold.ll b/llvm/test/Transforms/InstCombine/load-int2ptr-fold.ll --- a/llvm/test/Transforms/InstCombine/load-int2ptr-fold.ll +++ b/llvm/test/Transforms/InstCombine/load-int2ptr-fold.ll @@ -75,18 +75,14 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[XVAL]], [[YVAL]] ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; CHECK: if.then: -; CHECK-NEXT: [[Y_I:%.*]] = ptrtoint i8* [[Y]] to i64 -; CHECK-NEXT: [[Y_P:%.*]] = inttoptr i64 [[Y_I]] to i8* -; CHECK-NEXT: [[X_I:%.*]] = ptrtoint i8* [[X]] to i64 -; CHECK-NEXT: [[X_P:%.*]] = inttoptr i64 [[X_I]] to i8* ; CHECK-NEXT: br label [[CALL:%.*]] ; CHECK: if.else: ; CHECK-NEXT: [[Z_I:%.*]] = ptrtoint i8* [[Z:%.*]] to i64 ; CHECK-NEXT: [[Z_P:%.*]] = inttoptr i64 [[Z_I]] to i8* ; CHECK-NEXT: br label [[CALL]] ; CHECK: call: -; CHECK-NEXT: [[PHI_1:%.*]] = phi i8* [ [[Z_P]], [[IF_ELSE]] ], [ [[Y_P]], [[IF_THEN]] ] -; CHECK-NEXT: [[PHI_2:%.*]] = phi i8* [ [[Z_P]], [[IF_ELSE]] ], [ [[X_P]], [[IF_THEN]] ] +; CHECK-NEXT: [[PHI_1:%.*]] = phi i8* [ [[Z_P]], [[IF_ELSE]] ], [ [[Y]], [[IF_THEN]] ] +; CHECK-NEXT: [[PHI_2:%.*]] = phi i8* [ [[Z_P]], [[IF_ELSE]] ], [ [[X]], [[IF_THEN]] ] ; CHECK-NEXT: tail call void @foo(i8* [[PHI_1]], i8* [[PHI_2]]) ; CHECK-NEXT: ret void ; @@ -124,9 +120,7 @@ ; CHECK-NEXT: [[YVAL:%.*]] = load i8, i8* [[Y:%.*]], align 1 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: -; CHECK-NEXT: [[PHI:%.*]] = phi i8* [ [[X_P:%.*]], [[FOR_BODY]] ], [ [[Y]], [[FOR_BODY_PREHEADER]] ] -; CHECK-NEXT: [[X_I:%.*]] = ptrtoint i8* [[X]] to i64 -; CHECK-NEXT: [[X_P]] = inttoptr i64 [[X_I]] to i8* +; CHECK-NEXT: [[PHI:%.*]] = phi i8* [ [[X]], [[FOR_BODY]] ], [ [[Y]], [[FOR_BODY_PREHEADER]] ] ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[XVAL]], [[YVAL]] ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY]], label [[FOR_END]] ; CHECK: for.end: