diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 3f1ddea04d965..77f1e1302e49e 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -6656,7 +6656,8 @@ or switch that it is attached to is completely unpredictable. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 @@ attribute on parameters and return values. 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 index c0d95694eb06e..2c232076a7fdf 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -2701,8 +2701,9 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J, 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 index 7e52cb2e4e9d4..d6331125f809b 100644 --- a/llvm/test/Transforms/GVN/metadata.ll +++ b/llvm/test/Transforms/GVN/metadata.ll @@ -138,7 +138,7 @@ define i32 @load_load_noundef(ptr %p) { 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