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 @@ -13,6 +13,7 @@ #include "InstCombineInternal.h" #include "llvm/ADT/SetVector.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/Loads.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/DIBuilder.h" #include "llvm/IR/DataLayout.h" @@ -336,7 +337,14 @@ return new ShuffleVectorInst(CastX, UndefValue::get(DestTy), Mask); } } - + // Replace Int2Ptr/Ptr2Int RoundTrip Cast with bitcast if the pointer + // is dereferenceable. + Value *Ptr = isIntToPtrRoundTripCast(&CI); + if (Ptr) { + if (isDereferenceableAndAlignedPointer(Ptr, Align(1), APInt(64, 1), DL)) { + return new BitCastInst(Ptr, CI.getDestTy()); + } + } 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 @@ -10,13 +10,13 @@ ; CHECK-LABEL: @test_dereferenceable( ; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; CHECK: if.then: +; 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: br label [[CALL]] ; CHECK: call: -; CHECK-NEXT: [[PHI_1_IN_IN:%.*]] = phi i8* [ [[Z:%.*]], [[IF_ELSE]] ], [ [[X:%.*]], [[IF_THEN]] ] -; CHECK-NEXT: [[PHI_1_IN:%.*]] = ptrtoint i8* [[PHI_1_IN_IN]] to i64 -; CHECK-NEXT: [[PHI_1:%.*]] = inttoptr i64 [[PHI_1_IN]] to i8* +; CHECK-NEXT: [[PHI_1:%.*]] = phi i8* [ [[Z:%.*]], [[IF_ELSE]] ], [ [[X_P]], [[IF_THEN]] ] ; CHECK-NEXT: tail call void @foo(i8* [[PHI_1]], i8* [[PHI_1]]) ; CHECK-NEXT: ret void ; @@ -46,9 +46,7 @@ ; CHECK: if.else: ; CHECK-NEXT: br label [[CALL]] ; CHECK: call: -; CHECK-NEXT: [[PHI_1_IN_IN:%.*]] = phi i8* [ [[Z:%.*]], [[IF_ELSE]] ], [ [[X:%.*]], [[IF_THEN]] ] -; CHECK-NEXT: [[PHI_1_IN:%.*]] = ptrtoint i8* [[PHI_1_IN_IN]] to i64 -; CHECK-NEXT: [[PHI_1:%.*]] = inttoptr i64 [[PHI_1_IN]] to i8* +; CHECK-NEXT: [[PHI_1:%.*]] = phi i8* [ [[Z:%.*]], [[IF_ELSE]] ], [ [[X:%.*]], [[IF_THEN]] ] ; CHECK-NEXT: tail call void @foo(i8* nonnull [[PHI_1]], i8* nonnull [[PHI_1]]) ; CHECK-NEXT: ret void ;