Skip to content

Commit

Permalink
[LangRef][Local] dereferenceable metadata violation is UB
Browse files Browse the repository at this point in the history
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.

Differential Revision: https://reviews.llvm.org/D148202
  • Loading branch information
nikic committed Apr 14, 2023
1 parent c508e93 commit e4251fc
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 5 deletions.
5 changes: 3 additions & 2 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Transforms/Utils/Local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GVN/metadata.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit e4251fc

Please sign in to comment.