Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -1269,15 +1269,21 @@ to ensure a pointer is not null or otherwise the behavior is undefined. ``dereferenceable()`` - This indicates that the parameter or return pointer is dereferenceable. This - attribute may only be applied to pointer typed parameters. A pointer that - is dereferenceable can be loaded from speculatively without a risk of - trapping. The number of bytes known to be dereferenceable must be provided - in parentheses. It is legal for the number of bytes to be less than the - size of the pointee type. The ``nonnull`` attribute does not imply - dereferenceability (consider a pointer to one element past the end of an - array), however ``dereferenceable()`` does imply ``nonnull`` in - ``addrspace(0)`` (which is the default address space), except if the + This indicates that the parameter or return pointer is dereferenceable at + the instant of the call. This attribute may only be applied to pointer + typed parameters. The number of bytes known to be dereferenceable must + be provided in parentheses. It is legal for the number of bytes to be less + than the size of the pointee type. + + A pointer that is dereferenceable at a particular location in the program + can be loaded from speculatively without a risk of trapping at that + location. In general, once a memory location becomes dereferenceable, it + will remain dereferenceable until the underlying object is freed. + + The ``nonnull`` attribute does not imply dereferenceability (consider a + pointer to one element past the end of an array), however + ``dereferenceable()`` does imply ``nonnull`` in ``addrspace(0)`` + (which is the default address space), except if the ``null_pointer_is_valid`` function attribute is present. ``n`` should be a positive number. The pointer should be well defined, otherwise it is undefined behavior. This means ``dereferenceable()`` @@ -6215,10 +6221,10 @@ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The existence of the ``!dereferenceable`` metadata on the instruction -tells the optimizer that the value loaded is known to be dereferenceable. -The number of bytes known to be dereferenceable is specified by the integer -value in the metadata node. This is analogous to the ''dereferenceable'' -attribute on parameters and return values. +tells the optimizer that the value loaded is known to be dereferenceable at +that program location. The number of bytes known to be dereferenceable is +specified by the integer value in the metadata node. This is analogous to the +''dereferenceable'' attribute on parameters and return values. .. _md_dereferenceable_or_null: @@ -6227,7 +6233,7 @@ The existence of the ``!dereferenceable_or_null`` metadata on the instruction tells the optimizer that the value loaded is known to be either -dereferenceable or null. +dereferenceable or null at that program location. The number of bytes known to be dereferenceable is specified by the integer value in the metadata node. This is analogous to the ''dereferenceable_or_null'' attribute on parameters and return values. Index: llvm/lib/IR/Value.cpp =================================================================== --- llvm/lib/IR/Value.cpp +++ llvm/lib/IR/Value.cpp @@ -39,7 +39,7 @@ using namespace llvm; static cl::opt UseDerefAtPointSemantics( - "use-dereferenceable-at-point-semantics", cl::Hidden, cl::init(false), + "use-dereferenceable-at-point-semantics", cl::Hidden, cl::init(true), cl::desc("Deref attributes and metadata infer facts at definition only")); //===----------------------------------------------------------------------===// Index: llvm/test/Analysis/BasicAA/dereferenceable.ll =================================================================== --- llvm/test/Analysis/BasicAA/dereferenceable.ll +++ llvm/test/Analysis/BasicAA/dereferenceable.ll @@ -63,7 +63,7 @@ define i32 @local_and_deref_ret_2() { ; CHECK: Function: local_and_deref_ret_2: 2 pointers, 2 call sites -; CHECK-NEXT: NoAlias: i32* %obj, i32* %ret +; CHECK-NEXT: MayAlias: i32* %obj, i32* %ret bb: %obj = alloca i32 call void @unknown(i32* %obj) Index: llvm/test/CodeGen/X86/load-partial.ll =================================================================== --- llvm/test/CodeGen/X86/load-partial.ll +++ llvm/test/CodeGen/X86/load-partial.ll @@ -156,7 +156,7 @@ ret <4 x float> %11 } -define <4 x float> @load_float4_float3_trunc(<4 x float>* nocapture readonly dereferenceable(16)) { +define <4 x float> @load_float4_float3_trunc(<4 x float>* nocapture readonly dereferenceable(16)) nofree nosync { ; SSE-LABEL: load_float4_float3_trunc: ; SSE: # %bb.0: ; SSE-NEXT: movaps (%rdi), %xmm0 Index: llvm/test/Transforms/LICM/hoist-deref-load.ll =================================================================== --- llvm/test/Transforms/LICM/hoist-deref-load.ll +++ llvm/test/Transforms/LICM/hoist-deref-load.ll @@ -426,18 +426,18 @@ ; CHECK-NEXT: [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0 ; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]] ; CHECK: for.body.preheader: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[C]], align 4 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] ; CHECK: if.then: +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[C]], align 4 ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX3]], align 4 -; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]] +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]] ; CHECK-NEXT: store i32 [[MUL]], i32* [[ARRAYIDX]], align 4 ; CHECK-NEXT: br label [[FOR_INC]] ; CHECK: for.inc: @@ -501,18 +501,18 @@ ; CHECK-NEXT: [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0 ; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END]] ; CHECK: for.body.preheader: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[C]], align 4 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] ; CHECK: if.then: +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[C]], align 4 ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX3]], align 4 -; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]] +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]] ; CHECK-NEXT: store i32 [[MUL]], i32* [[ARRAYIDX]], align 4 ; CHECK-NEXT: br label [[FOR_INC]] ; CHECK: for.inc: