[PATCH] D148202: [LangRef][Local] dereferenceable metadata violation is UB

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 13 02:04:13 PDT 2023


nikic created this revision.
nikic added reviewers: StephenFan, nlopes, efriedma, jdoerfert.
Herald added a subscriber: hiraditya.
Herald added a project: All.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

I believe `!dereferencable` violation is immediate undefined behavior, but this was not explicitly spelled out in LangRef. We already assume that `!dereferenceable` is implicitly `!noundef` and cannot return poison in isGuaranteedNotToBeUndefOrPoison().

The reason why we made dereferenceable implicitly noundef is that the purpose of this metadata is to allow speculation, and that would not be legal on a potential poison pointer.


https://reviews.llvm.org/D148202

Files:
  llvm/docs/LangRef.rst
  llvm/lib/Transforms/Utils/Local.cpp
  llvm/test/Transforms/GVN/metadata.ll


Index: llvm/test/Transforms/GVN/metadata.ll
===================================================================
--- llvm/test/Transforms/GVN/metadata.ll
+++ 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
Index: llvm/lib/Transforms/Utils/Local.cpp
===================================================================
--- llvm/lib/Transforms/Utils/Local.cpp
+++ 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.
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ 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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148202.513108.patch
Type: text/x-patch
Size: 2421 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230413/7656cf8b/attachment.bin>


More information about the llvm-commits mailing list