diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -6656,7 +6656,8 @@ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The existence of the ``!dereferenceable`` metadata on the instruction -tells the optimizer that the value loaded is known to be dereferenceable. +tells the optimizer that the value loaded is known to be dereferenceable, +otherwise the behavior is undefined. 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. @@ -6668,7 +6669,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, otherwise the behavior is undefined. 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. diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -2701,8 +2701,9 @@ break; case LLVMContext::MD_dereferenceable: case LLVMContext::MD_dereferenceable_or_null: - K->setMetadata(Kind, - MDNode::getMostGenericAlignmentOrDereferenceable(JMD, KMD)); + if (DoesKMove) + K->setMetadata(Kind, + MDNode::getMostGenericAlignmentOrDereferenceable(JMD, KMD)); break; case LLVMContext::MD_preserve_access_index: // Preserve !preserve.access.index in K. diff --git a/llvm/test/Transforms/GVN/metadata.ll b/llvm/test/Transforms/GVN/metadata.ll --- a/llvm/test/Transforms/GVN/metadata.ll +++ b/llvm/test/Transforms/GVN/metadata.ll @@ -138,7 +138,7 @@ define void @load_dereferenceable_dominating(ptr %p) { ; CHECK-LABEL: define void @load_dereferenceable_dominating ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[A:%.*]] = load ptr, ptr [[P]], align 8 +; CHECK-NEXT: [[A:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable !7 ; CHECK-NEXT: call void @use.ptr(ptr [[A]]) ; CHECK-NEXT: call void @use.ptr(ptr [[A]]) ; CHECK-NEXT: ret void