diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 63930617071f..927d05b3f1ea 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3847,17 +3847,19 @@ static Value *simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, Type *SrcTy = SrcOp->getType(); Type *DstTy = LI->getType(); - // Turn icmp (ptrtoint x), (ptrtoint/constant) into a compare of the input - // if the integer type is the same size as the pointer type. - if (MaxRecurse && isa(LI) && - Q.DL.getTypeSizeInBits(SrcTy) == DstTy->getPrimitiveSizeInBits()) { + // Turn icmp (ptrtoint/ptrtoaddr x), (ptrtoint/ptrtoaddr/constant) into a + // compare of the input if the integer type is the same size as the + // pointer address type (icmp only compares the address of the pointer). + if (MaxRecurse && (isa(LI)) && + Q.DL.getAddressType(SrcTy) == DstTy) { if (Constant *RHSC = dyn_cast(RHS)) { // Transfer the cast to the constant. if (Value *V = simplifyICmpInst(Pred, SrcOp, ConstantExpr::getIntToPtr(RHSC, SrcTy), Q, MaxRecurse - 1)) return V; - } else if (PtrToIntInst *RI = dyn_cast(RHS)) { + } else if (isa(RHS)) { + auto *RI = cast(RHS); if (RI->getOperand(0)->getType() == SrcTy) // Compare without the cast. if (Value *V = simplifyICmpInst(Pred, SrcOp, RI->getOperand(0), Q, diff --git a/llvm/test/Transforms/InstSimplify/ptrtoaddr.ll b/llvm/test/Transforms/InstSimplify/ptrtoaddr.ll index eaccf15cd80f..5f1a531b6593 100644 --- a/llvm/test/Transforms/InstSimplify/ptrtoaddr.ll +++ b/llvm/test/Transforms/InstSimplify/ptrtoaddr.ll @@ -398,3 +398,75 @@ define i1 @icmp_relational_ptrtoint_ptrtoint_addrsize() { %cmp = icmp ult i64 ptrtoint (ptr addrspace(1) @g.as1 to i64), ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) @g.as1, i64 1) to i64) ret i1 %cmp } + +define i1 @icmp_ptrtoaddr_ptrtoaddr_dyn(ptr %a) { +; CHECK-LABEL: define i1 @icmp_ptrtoaddr_ptrtoaddr_dyn( +; CHECK-SAME: ptr [[A:%.*]]) { +; CHECK-NEXT: ret i1 true +; + %gep = getelementptr i8, ptr %a, i64 1 + %a.addr = ptrtoaddr ptr %a to i64 + %gep.addr = ptrtoaddr ptr %gep to i64 + %cmp = icmp ne i64 %a.addr, %gep.addr + ret i1 %cmp +} + +define i1 @icmp_ptrtoaddr_ptrtoaddr_dyn_addrsize(ptr addrspace(1) %a) { +; CHECK-LABEL: define i1 @icmp_ptrtoaddr_ptrtoaddr_dyn_addrsize( +; CHECK-SAME: ptr addrspace(1) [[A:%.*]]) { +; CHECK-NEXT: ret i1 true +; + %gep = getelementptr i8, ptr addrspace(1) %a, i32 1 + %a.addr = ptrtoaddr ptr addrspace(1) %a to i32 + %gep.addr = ptrtoaddr ptr addrspace(1) %gep to i32 + %cmp = icmp ne i32 %a.addr, %gep.addr + ret i1 %cmp +} + +; This could still be folded, because the non-address bits being non-equal +; implies that all bits taken together are also non-equal. +define i1 @icmp_ptrtoint_ptrtoint_dyn_addrsize(ptr addrspace(1) %a) { +; CHECK-LABEL: define i1 @icmp_ptrtoint_ptrtoint_dyn_addrsize( +; CHECK-SAME: ptr addrspace(1) [[A:%.*]]) { +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[A]], i32 1 +; CHECK-NEXT: [[A_ADDR:%.*]] = ptrtoint ptr addrspace(1) [[A]] to i64 +; CHECK-NEXT: [[GEP_ADDR:%.*]] = ptrtoint ptr addrspace(1) [[GEP]] to i64 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[A_ADDR]], [[GEP_ADDR]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %gep = getelementptr i8, ptr addrspace(1) %a, i32 1 + %a.addr = ptrtoint ptr addrspace(1) %a to i64 + %gep.addr = ptrtoint ptr addrspace(1) %gep to i64 + %cmp = icmp ne i64 %a.addr, %gep.addr + ret i1 %cmp +} + +define i1 @icmp_ptrtoaddr_null_dyn(ptr nonnull %a) { +; CHECK-LABEL: define i1 @icmp_ptrtoaddr_null_dyn( +; CHECK-SAME: ptr nonnull [[A:%.*]]) { +; CHECK-NEXT: ret i1 true +; + %a.addr = ptrtoaddr ptr %a to i64 + %cmp = icmp ne i64 %a.addr, 0 + ret i1 %cmp +} + +define i1 @icmp_ptrtoaddr_null_dyn_addrsize(ptr addrspace(1) nonnull %a) { +; CHECK-LABEL: define i1 @icmp_ptrtoaddr_null_dyn_addrsize( +; CHECK-SAME: ptr addrspace(1) nonnull [[A:%.*]]) { +; CHECK-NEXT: ret i1 true +; + %a.addr = ptrtoaddr ptr addrspace(1) %a to i32 + %cmp = icmp ne i32 %a.addr, 0 + ret i1 %cmp +} + +define i1 @icmp_ptrtoint_null_dyn_addrsize(ptr addrspace(1) nonnull %a) { +; CHECK-LABEL: define i1 @icmp_ptrtoint_null_dyn_addrsize( +; CHECK-SAME: ptr addrspace(1) nonnull [[A:%.*]]) { +; CHECK-NEXT: ret i1 true +; + %a.addr = ptrtoint ptr addrspace(1) %a to i64 + %cmp = icmp ne i64 %a.addr, 0 + ret i1 %cmp +}