Skip to content

Commit

Permalink
Introduce a 'nonnull' metadata on Load instructions.
Browse files Browse the repository at this point in the history
The newly introduced 'nonnull' metadata is analogous to existing 'nonnull' attributes, but applies to load instructions rather than call arguments or returns.  Long term, it would be nice to combine these into a single construct.   The value of the load is allowed to vary between successive loads, but null is not a valid value to be loaded by any load marked nonnull.

Reviewed by: Hal Finkel
Differential Revision:  http://reviews.llvm.org/D5220

llvm-svn: 220240
  • Loading branch information
preames committed Oct 20, 2014
1 parent 2f9548a commit cdb72f3
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
10 changes: 9 additions & 1 deletion llvm/docs/LangRef.rst
Expand Up @@ -5157,7 +5157,7 @@ Syntax:

::

<result> = load [volatile] <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>]
<result> = load [volatile] <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>][, !nonnull !<index>]
<result> = load atomic [volatile] <ty>* <pointer> [singlethread] <ordering>, align <alignment>
!<index> = !{ i32 1 }

Expand Down Expand Up @@ -5213,6 +5213,14 @@ address points to memory which does not change value during program
execution. The optimizer may then move this load around, for example, by
hoisting it out of loops using loop invariant code motion.

The optional ``!nonnull`` metadata must reference a single
metadata name ``<index>`` corresponding to a metadata node with no
entries. The existence of the ``!nonnull`` metadata on the
instruction tells the optimizer that the value loaded is known to
never be null. This is analogous to the ''nonnull'' attribute
on parameters and return values. This metadata can only be applied
to loads of a pointer type.

Semantics:
""""""""""

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Expand Up @@ -2622,6 +2622,10 @@ bool llvm::isKnownNonNull(const Value *V, const TargetLibraryInfo *TLI) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
return !GV->hasExternalWeakLinkage();

// A Load tagged w/nonnull metadata is never null.
if (const LoadInst *LI = dyn_cast<LoadInst>(V))
return LI->getMetadata("nonnull");

if (ImmutableCallSite CS = V)
if (CS.isReturnNonNull())
return true;
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/Transforms/InstSimplify/compare.ll
Expand Up @@ -949,6 +949,29 @@ define i1 @returns_nonnull_as_deref() {
; CHECK: ret
}

define i1 @nonnull_load(i32** %addr) {
%ptr = load i32** %addr, !nonnull !{}
%cmp = icmp eq i32* %ptr, null
ret i1 %cmp
; CHECK-LABEL: @nonnull_load
; CHECK: ret i1 false
}

define i1 @nonnull_load_as_outer(i32* addrspace(1)* %addr) {
%ptr = load i32* addrspace(1)* %addr, !nonnull !{}
%cmp = icmp eq i32* %ptr, null
ret i1 %cmp
; CHECK-LABEL: @nonnull_load_as_outer
; CHECK: ret i1 false
}
define i1 @nonnull_load_as_inner(i32 addrspace(1)** %addr) {
%ptr = load i32 addrspace(1)** %addr, !nonnull !{}
%cmp = icmp eq i32 addrspace(1)* %ptr, null
ret i1 %cmp
; CHECK-LABEL: @nonnull_load_as_inner
; CHECK: ret i1 false
}

; If a bit is known to be zero for A and known to be one for B,
; then A and B cannot be equal.
define i1 @icmp_eq_const(i32 %a) nounwind {
Expand Down

0 comments on commit cdb72f3

Please sign in to comment.