diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4539,6 +4539,21 @@ auto *CastOp0 = dyn_cast(ICmp.getOperand(0)); if (!CastOp0) return nullptr; + + // icmp (inttoptr (ptrtoint p1)), p2 --> icmp p1, p2. + if (CastOp0->getOpcode() == Instruction::IntToPtr && + (DL.getPointerTypeSizeInBits(CastOp0->getDestTy()) == + DL.getTypeSizeInBits(CastOp0->getSrcTy()))) { + auto *I = dyn_cast(CastOp0->getOperand(0)); + if (I && (DL.getPointerTypeSizeInBits(I->getSrcTy()) == + DL.getTypeSizeInBits(I->getDestTy()))) { + Value *P = I->getOperand(0); + Type *Op0Ty = CastOp0->getDestTy(); + Value *NewOp0 = Builder.CreateBitCast(P, Op0Ty); + return new ICmpInst(ICmp.getPredicate(), NewOp0, ICmp.getOperand(1)); + } + } + if (!isa(ICmp.getOperand(1)) && !isa(ICmp.getOperand(1))) return nullptr; diff --git a/llvm/test/Transforms/InstCombine/ptr-int-ptr-icmp.ll b/llvm/test/Transforms/InstCombine/ptr-int-ptr-icmp.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/ptr-int-ptr-icmp.ll @@ -0,0 +1,58 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -instcombine -S < %s | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; icmp (inttoptr (ptrtoint p1)), p2 --> icmp p1, p2. + +define i1 @func(i8* %X, i8* %Y) { +; CHECK-LABEL: @func( +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %i = ptrtoint i8* %X to i64 + %p = inttoptr i64 %i to i8* + %cmp = icmp eq i8* %p, %Y + ret i1 %cmp +} + +define i1 @func2(i16* %X, i8* %Y) { +; CHECK-LABEL: @func2( +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i16* [[X:%.*]] to i8* +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[TMP1]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %i = ptrtoint i16* %X to i64 + %p = inttoptr i64 %i to i8* + %cmp = icmp eq i8* %p, %Y + ret i1 %cmp +} + +define i1 @func3(i16* %X, i8* %Y) { +; CHECK-LABEL: @func3( +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i16* [[X:%.*]] to i8* +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[TMP1]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %i = ptrtoint i16* %X to i64 + %p = inttoptr i64 %i to i8* + %cmp = icmp eq i8* %Y, %p + ret i1 %cmp +} + +; Negative test - Wrong Integer type. + +define i1 @func4(i16* %X, i8* %Y) { +; CHECK-LABEL: @func4( +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i16* [[X:%.*]] to i64 +; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], 4294967295 +; CHECK-NEXT: [[P:%.*]] = inttoptr i64 [[TMP2]] to i8* +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[P]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %i = ptrtoint i16* %X to i32 + %p = inttoptr i32 %i to i8* + %cmp = icmp eq i8* %Y, %p + ret i1 %cmp +}