[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
This commit is contained in:
Michael Liao 2015-02-13 04:51:26 +00:00
parent e95568c0a0
commit 4235574ce3
2 changed files with 32 additions and 8 deletions

View File

@ -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<Constant>(ICI.getOperand(1))) {
if (PtrToIntOperator *RHSC = dyn_cast<PtrToIntOperator>(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<Constant>(ICI.getOperand(1)))
RHSOp = ConstantExpr::getIntToPtr(RHSC, SrcTy);
} else if (PtrToIntInst *RHSC = dyn_cast<PtrToIntInst>(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);

View File

@ -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)