Skip to content

Commit 80b900e

Browse files
authored
[InstSimplify] Support ptrtoaddr in simplifyICmpInst() (#171985)
This is basically the same change as #162653, but for InstSimplify instead of ConstantFolding. It folds `icmp (ptrtoaddr x, ptrtoaddr y)` to `icmp (x, y)` and `icmp (ptrtoaddr x, C)` to `icmp (x, inttoptr C)`. The fold is restricted to the case where the result type is the address type, as icmp only compares the icmp bits. As in the other PR, I think in practice all the folds are also going to work if the ptrtoint result type is larger than the address size, but it's unclear how to justify this in general.
1 parent 37c7f69 commit 80b900e

File tree

2 files changed

+79
-5
lines changed

2 files changed

+79
-5
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3847,17 +3847,19 @@ static Value *simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS,
38473847
Type *SrcTy = SrcOp->getType();
38483848
Type *DstTy = LI->getType();
38493849

3850-
// Turn icmp (ptrtoint x), (ptrtoint/constant) into a compare of the input
3851-
// if the integer type is the same size as the pointer type.
3852-
if (MaxRecurse && isa<PtrToIntInst>(LI) &&
3853-
Q.DL.getTypeSizeInBits(SrcTy) == DstTy->getPrimitiveSizeInBits()) {
3850+
// Turn icmp (ptrtoint/ptrtoaddr x), (ptrtoint/ptrtoaddr/constant) into a
3851+
// compare of the input if the integer type is the same size as the
3852+
// pointer address type (icmp only compares the address of the pointer).
3853+
if (MaxRecurse && (isa<PtrToIntInst, PtrToAddrInst>(LI)) &&
3854+
Q.DL.getAddressType(SrcTy) == DstTy) {
38543855
if (Constant *RHSC = dyn_cast<Constant>(RHS)) {
38553856
// Transfer the cast to the constant.
38563857
if (Value *V = simplifyICmpInst(Pred, SrcOp,
38573858
ConstantExpr::getIntToPtr(RHSC, SrcTy),
38583859
Q, MaxRecurse - 1))
38593860
return V;
3860-
} else if (PtrToIntInst *RI = dyn_cast<PtrToIntInst>(RHS)) {
3861+
} else if (isa<PtrToIntInst, PtrToAddrInst>(RHS)) {
3862+
auto *RI = cast<CastInst>(RHS);
38613863
if (RI->getOperand(0)->getType() == SrcTy)
38623864
// Compare without the cast.
38633865
if (Value *V = simplifyICmpInst(Pred, SrcOp, RI->getOperand(0), Q,

llvm/test/Transforms/InstSimplify/ptrtoaddr.ll

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,3 +398,75 @@ define i1 @icmp_relational_ptrtoint_ptrtoint_addrsize() {
398398
%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)
399399
ret i1 %cmp
400400
}
401+
402+
define i1 @icmp_ptrtoaddr_ptrtoaddr_dyn(ptr %a) {
403+
; CHECK-LABEL: define i1 @icmp_ptrtoaddr_ptrtoaddr_dyn(
404+
; CHECK-SAME: ptr [[A:%.*]]) {
405+
; CHECK-NEXT: ret i1 true
406+
;
407+
%gep = getelementptr i8, ptr %a, i64 1
408+
%a.addr = ptrtoaddr ptr %a to i64
409+
%gep.addr = ptrtoaddr ptr %gep to i64
410+
%cmp = icmp ne i64 %a.addr, %gep.addr
411+
ret i1 %cmp
412+
}
413+
414+
define i1 @icmp_ptrtoaddr_ptrtoaddr_dyn_addrsize(ptr addrspace(1) %a) {
415+
; CHECK-LABEL: define i1 @icmp_ptrtoaddr_ptrtoaddr_dyn_addrsize(
416+
; CHECK-SAME: ptr addrspace(1) [[A:%.*]]) {
417+
; CHECK-NEXT: ret i1 true
418+
;
419+
%gep = getelementptr i8, ptr addrspace(1) %a, i32 1
420+
%a.addr = ptrtoaddr ptr addrspace(1) %a to i32
421+
%gep.addr = ptrtoaddr ptr addrspace(1) %gep to i32
422+
%cmp = icmp ne i32 %a.addr, %gep.addr
423+
ret i1 %cmp
424+
}
425+
426+
; This could still be folded, because the non-address bits being non-equal
427+
; implies that all bits taken together are also non-equal.
428+
define i1 @icmp_ptrtoint_ptrtoint_dyn_addrsize(ptr addrspace(1) %a) {
429+
; CHECK-LABEL: define i1 @icmp_ptrtoint_ptrtoint_dyn_addrsize(
430+
; CHECK-SAME: ptr addrspace(1) [[A:%.*]]) {
431+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[A]], i32 1
432+
; CHECK-NEXT: [[A_ADDR:%.*]] = ptrtoint ptr addrspace(1) [[A]] to i64
433+
; CHECK-NEXT: [[GEP_ADDR:%.*]] = ptrtoint ptr addrspace(1) [[GEP]] to i64
434+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[A_ADDR]], [[GEP_ADDR]]
435+
; CHECK-NEXT: ret i1 [[CMP]]
436+
;
437+
%gep = getelementptr i8, ptr addrspace(1) %a, i32 1
438+
%a.addr = ptrtoint ptr addrspace(1) %a to i64
439+
%gep.addr = ptrtoint ptr addrspace(1) %gep to i64
440+
%cmp = icmp ne i64 %a.addr, %gep.addr
441+
ret i1 %cmp
442+
}
443+
444+
define i1 @icmp_ptrtoaddr_null_dyn(ptr nonnull %a) {
445+
; CHECK-LABEL: define i1 @icmp_ptrtoaddr_null_dyn(
446+
; CHECK-SAME: ptr nonnull [[A:%.*]]) {
447+
; CHECK-NEXT: ret i1 true
448+
;
449+
%a.addr = ptrtoaddr ptr %a to i64
450+
%cmp = icmp ne i64 %a.addr, 0
451+
ret i1 %cmp
452+
}
453+
454+
define i1 @icmp_ptrtoaddr_null_dyn_addrsize(ptr addrspace(1) nonnull %a) {
455+
; CHECK-LABEL: define i1 @icmp_ptrtoaddr_null_dyn_addrsize(
456+
; CHECK-SAME: ptr addrspace(1) nonnull [[A:%.*]]) {
457+
; CHECK-NEXT: ret i1 true
458+
;
459+
%a.addr = ptrtoaddr ptr addrspace(1) %a to i32
460+
%cmp = icmp ne i32 %a.addr, 0
461+
ret i1 %cmp
462+
}
463+
464+
define i1 @icmp_ptrtoint_null_dyn_addrsize(ptr addrspace(1) nonnull %a) {
465+
; CHECK-LABEL: define i1 @icmp_ptrtoint_null_dyn_addrsize(
466+
; CHECK-SAME: ptr addrspace(1) nonnull [[A:%.*]]) {
467+
; CHECK-NEXT: ret i1 true
468+
;
469+
%a.addr = ptrtoint ptr addrspace(1) %a to i64
470+
%cmp = icmp ne i64 %a.addr, 0
471+
ret i1 %cmp
472+
}

0 commit comments

Comments
 (0)