[llvm] [ValueTracking] Support ptrtoaddr in isKnownNonZero() (PR #173275)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 22 07:58:26 PST 2025
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/173275
Add support for ptrtoaddr in isKnownNonZero(). We can directly forward to isKnownNonZero() for the pointer here, as we define nonnull as applying to the address bits.
Also adjust the ptrtoint implementation to match, by requiring that the result type >= address size (rather than >= pointer size). This is just for clarity, in practice this is a non-canonical form.
>From b061a03785fe12d83aa83e6548bd2cac10e6724b Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 22 Dec 2025 16:53:07 +0100
Subject: [PATCH] [ValueTracking] Support ptrtoaddr in isKnownNonZero()
Add support for ptrtoaddr in isKnownNonZero(). We can directly
forward to isKnownNonZero() for the pointer here, as we define
nonnull as applying to the address bits.
Also adjust the ptrtoint implementation to match, by requiring that
the result type >= address size (rather than >= pointer size).
This is just for clarity, in practice this is a non-canonical form.
---
llvm/lib/Analysis/ValueTracking.cpp | 13 +++--
.../test/Transforms/InstSimplify/ptrtoaddr.ll | 58 +++++++++++++++++++
2 files changed, 66 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 0321c08f55776..6d8c966deb7e0 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3232,12 +3232,15 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
Q.DL.getTypeSizeInBits(I->getType()).getFixedValue())
return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
break;
+ case Instruction::PtrToAddr:
+ // isKnownNonZero() for pointers refers to the address bits being non-zero,
+ // so we can directly forward.
+ return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
case Instruction::PtrToInt:
- // Similar to int2ptr above, we can look through ptr2int here if the cast
- // is a no-op or an extend and not a truncate.
- if (!isa<ScalableVectorType>(I->getType()) &&
- Q.DL.getTypeSizeInBits(I->getOperand(0)->getType()).getFixedValue() <=
- Q.DL.getTypeSizeInBits(I->getType()).getFixedValue())
+ // For inttoptr, make sure the result size is >= the address size. If the
+ // address is non-zero, any larger value is also non-zero.
+ if (Q.DL.getAddressSizeInBits(I->getOperand(0)->getType()) <=
+ I->getType()->getScalarSizeInBits())
return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
break;
case Instruction::Trunc:
diff --git a/llvm/test/Transforms/InstSimplify/ptrtoaddr.ll b/llvm/test/Transforms/InstSimplify/ptrtoaddr.ll
index 5f1a531b65931..d517414ff93d7 100644
--- a/llvm/test/Transforms/InstSimplify/ptrtoaddr.ll
+++ b/llvm/test/Transforms/InstSimplify/ptrtoaddr.ll
@@ -470,3 +470,61 @@ define i1 @icmp_ptrtoint_null_dyn_addrsize(ptr addrspace(1) nonnull %a) {
%cmp = icmp ne i64 %a.addr, 0
ret i1 %cmp
}
+
+define i1 @non_zero_ptrtoaddr(ptr nonnull %p, i64 %unknown) {
+; CHECK-LABEL: define i1 @non_zero_ptrtoaddr(
+; CHECK-SAME: ptr nonnull [[P:%.*]], i64 [[UNKNOWN:%.*]]) {
+; CHECK-NEXT: ret i1 true
+;
+ %p.addr = ptrtoaddr ptr %p to i64
+ %or = or i64 %p.addr, %unknown
+ %cmp = icmp ne i64 %or, 0
+ ret i1 %cmp
+}
+
+define i1 @non_zero_ptrtoaddr_addrsize(ptr addrspace(1) nonnull %p, i32 %unknown) {
+; CHECK-LABEL: define i1 @non_zero_ptrtoaddr_addrsize(
+; CHECK-SAME: ptr addrspace(1) nonnull [[P:%.*]], i32 [[UNKNOWN:%.*]]) {
+; CHECK-NEXT: ret i1 true
+;
+ %p.addr = ptrtoaddr ptr addrspace(1) %p to i32
+ %or = or i32 %p.addr, %unknown
+ %cmp = icmp ne i32 %or, 0
+ ret i1 %cmp
+}
+
+define i1 @non_zero_ptrtoint_equal_addrsize(ptr addrspace(1) nonnull %p, i32 %unknown) {
+; CHECK-LABEL: define i1 @non_zero_ptrtoint_equal_addrsize(
+; CHECK-SAME: ptr addrspace(1) nonnull [[P:%.*]], i32 [[UNKNOWN:%.*]]) {
+; CHECK-NEXT: ret i1 true
+;
+ %p.addr = ptrtoint ptr addrspace(1) %p to i32
+ %or = or i32 %p.addr, %unknown
+ %cmp = icmp ne i32 %or, 0
+ ret i1 %cmp
+}
+
+define i1 @non_zero_ptrtoint_larger_addrsize(ptr addrspace(1) nonnull %p, i64 %unknown) {
+; CHECK-LABEL: define i1 @non_zero_ptrtoint_larger_addrsize(
+; CHECK-SAME: ptr addrspace(1) nonnull [[P:%.*]], i64 [[UNKNOWN:%.*]]) {
+; CHECK-NEXT: ret i1 true
+;
+ %p.addr = ptrtoint ptr addrspace(1) %p to i64
+ %or = or i64 %p.addr, %unknown
+ %cmp = icmp ne i64 %or, 0
+ ret i1 %cmp
+}
+
+define i1 @non_zero_ptrtoint_smaller_addrsize(ptr addrspace(1) nonnull %p, i16 %unknown) {
+; CHECK-LABEL: define i1 @non_zero_ptrtoint_smaller_addrsize(
+; CHECK-SAME: ptr addrspace(1) nonnull [[P:%.*]], i16 [[UNKNOWN:%.*]]) {
+; CHECK-NEXT: [[P_ADDR:%.*]] = ptrtoint ptr addrspace(1) [[P]] to i16
+; CHECK-NEXT: [[OR:%.*]] = or i16 [[P_ADDR]], [[UNKNOWN]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[OR]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %p.addr = ptrtoint ptr addrspace(1) %p to i16
+ %or = or i16 %p.addr, %unknown
+ %cmp = icmp ne i16 %or, 0
+ ret i1 %cmp
+}
More information about the llvm-commits
mailing list