From: Michael Liao Date: Fri, 13 Feb 2015 04:51:26 +0000 (+0000) Subject: [InstCombine] Fix a bug when combining `icmp` from `ptrtoint` X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4235574ce3c02c2c8ba8885a61a4f056cf30f4c4;p=oota-llvm.git [InstCombine] Fix a bug when combining `icmp` from `ptrtoint` - First, there's a crash when we try to combine that pointers into `icmp` directly by creating a `bitcast`, which is invalid if that two pointers are from different address spaces. - It's not always appropriate to cast one pointer to another if they are from different address spaces as that is not no-op cast. Instead, we only combine `icmp` from `ptrtoint` if that two pointers are of the same address space. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229063 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 27b6ed9d064..f48d89b426b 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1931,14 +1931,17 @@ Instruction *InstCombiner::visitICmpInstWithCastAndCast(ICmpInst &ICI) { if (DL && LHSCI->getOpcode() == Instruction::PtrToInt && DL->getPointerTypeSizeInBits(SrcTy) == DestTy->getIntegerBitWidth()) { Value *RHSOp = nullptr; - if (Constant *RHSC = dyn_cast(ICI.getOperand(1))) { + if (PtrToIntOperator *RHSC = dyn_cast(ICI.getOperand(1))) { + Value *RHSCIOp = RHSC->getOperand(0); + if (RHSCIOp->getType()->getPointerAddressSpace() == + LHSCIOp->getType()->getPointerAddressSpace()) { + RHSOp = RHSC->getOperand(0); + // If the pointer types don't match, insert a bitcast. + if (LHSCIOp->getType() != RHSOp->getType()) + RHSOp = Builder->CreateBitCast(RHSOp, LHSCIOp->getType()); + } + } else if (Constant *RHSC = dyn_cast(ICI.getOperand(1))) RHSOp = ConstantExpr::getIntToPtr(RHSC, SrcTy); - } else if (PtrToIntInst *RHSC = dyn_cast(ICI.getOperand(1))) { - RHSOp = RHSC->getOperand(0); - // If the pointer types don't match, insert a bitcast. - if (LHSCIOp->getType() != RHSOp->getType()) - RHSOp = Builder->CreateBitCast(RHSOp, LHSCIOp->getType()); - } if (RHSOp) return new ICmpInst(ICI.getPredicate(), LHSCIOp, RHSOp); diff --git a/test/Transforms/InstCombine/cast_ptr.ll b/test/Transforms/InstCombine/cast_ptr.ll index 23006a84604..cc7a2bf1859 100644 --- a/test/Transforms/InstCombine/cast_ptr.ll +++ b/test/Transforms/InstCombine/cast_ptr.ll @@ -3,6 +3,8 @@ target datalayout = "p:32:32-p1:32:32-p2:16:16" +@global = global i8 0 + ; This shouldn't convert to getelementptr because the relationship ; between the arithmetic and the layout of allocated memory is ; entirely unknown. @@ -47,10 +49,29 @@ define i1 @test2_as2_larger(i8 addrspace(2)* %a, i8 addrspace(2)* %b) { ret i1 %r } +; These casts should not be folded away. +; CHECK-LABEL: @test2_diff_as +; CHECK: icmp sge i32 %i0, %i1 +define i1 @test2_diff_as(i8* %p, i8 addrspace(1)* %q) { + %i0 = ptrtoint i8* %p to i32 + %i1 = ptrtoint i8 addrspace(1)* %q to i32 + %r0 = icmp sge i32 %i0, %i1 + ret i1 %r0 +} + +; These casts should not be folded away. +; CHECK-LABEL: @test2_diff_as_global +; CHECK: icmp sge i32 %i1 +define i1 @test2_diff_as_global(i8 addrspace(1)* %q) { + %i0 = ptrtoint i8* @global to i32 + %i1 = ptrtoint i8 addrspace(1)* %q to i32 + %r0 = icmp sge i32 %i1, %i0 + ret i1 %r0 +} + ; These casts should also be folded away. ; CHECK-LABEL: @test3( ; CHECK: icmp eq i8* %a, @global -@global = global i8 0 define i1 @test3(i8* %a) { %tmpa = ptrtoint i8* %a to i32 %r = icmp eq i32 %tmpa, ptrtoint (i8* @global to i32)