Skip to content

Commit 43114cb

Browse files
author
luxufan
committed
[ValueTracking] Dereferenceable and !NullPointerIsDefined imply non-zero
Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D157253
1 parent 9d0cf88 commit 43114cb

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,14 +2707,20 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
27072707
return isKnownNonZero(I->getOperand(0), Depth, Q) &&
27082708
isGuaranteedNotToBePoison(I->getOperand(0), Q.AC, Q.CxtI, Q.DT,
27092709
Depth);
2710-
case Instruction::Load:
2711-
// A Load tagged with nonnull metadata is never null.
2712-
if (Q.IIQ.getMetadata(cast<LoadInst>(I), LLVMContext::MD_nonnull))
2713-
return true;
2710+
case Instruction::Load: {
2711+
auto *LI = cast<LoadInst>(I);
2712+
// A Load tagged with nonnull or dereferenceable with null pointer undefined
2713+
// is never null.
2714+
if (auto *PtrT = dyn_cast<PointerType>(I->getType()))
2715+
if (Q.IIQ.getMetadata(LI, LLVMContext::MD_nonnull) ||
2716+
(Q.IIQ.getMetadata(LI, LLVMContext::MD_dereferenceable) &&
2717+
!NullPointerIsDefined(LI->getFunction(), PtrT->getAddressSpace())))
2718+
return true;
27142719

27152720
// No need to fall through to computeKnownBits as range metadata is already
27162721
// handled in isKnownNonZero.
27172722
return false;
2723+
}
27182724
case Instruction::Call:
27192725
case Instruction::Invoke:
27202726
if (I->getType()->isPointerTy()) {

llvm/test/Transforms/InstSimplify/icmp.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,23 @@ define i1 @sub_even(i8 %x) {
258258
%cmp = icmp ne i8 %sub, %x
259259
ret i1 %cmp
260260
}
261+
262+
define i1 @load_ptr(ptr %p) {
263+
; CHECK-LABEL: @load_ptr(
264+
; CHECK-NEXT: ret i1 true
265+
;
266+
%load_p = load ptr, ptr %p, !dereferenceable !{i64 8}
267+
%r = icmp ne ptr %load_p, null
268+
ret i1 %r
269+
}
270+
271+
define i1 @load_ptr_null_valid(ptr %p) null_pointer_is_valid {
272+
; CHECK-LABEL: @load_ptr_null_valid(
273+
; CHECK-NEXT: [[LOAD_P:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable !0
274+
; CHECK-NEXT: [[R:%.*]] = icmp ne ptr [[LOAD_P]], null
275+
; CHECK-NEXT: ret i1 [[R]]
276+
;
277+
%load_p = load ptr, ptr %p, !dereferenceable !{i64 8}
278+
%r = icmp ne ptr %load_p, null
279+
ret i1 %r
280+
}

0 commit comments

Comments
 (0)