[PATCH] D12853: Introduce !value.align metadata for load instruction

Artur Pilipenko via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 14 11:03:22 PDT 2015


apilipenko created this revision.
apilipenko added reviewers: hfinkel, reames, sanjoy.
apilipenko added a subscriber: llvm-commits.

Since D9791 we take alignment into account to decide if it's safe to speculate load. Now pointer has to be both dereferenceable and properly aligned to be speculative loadable. It means that we want to support align attribute everywhere we support dereferenceable attribute.

Introduce new !value.align metadata for load instruction. This metadata specifies alignment of the loaded pointer value.

http://reviews.llvm.org/D12853

Files:
  docs/LangRef.rst
  include/llvm/IR/LLVMContext.h
  lib/Analysis/ValueTracking.cpp
  lib/IR/LLVMContext.cpp
  test/Analysis/ValueTracking/memory-dereferenceable.ll

Index: test/Analysis/ValueTracking/memory-dereferenceable.ll
===================================================================
--- test/Analysis/ValueTracking/memory-dereferenceable.ll
+++ test/Analysis/ValueTracking/memory-dereferenceable.ll
@@ -111,6 +111,14 @@
     %load21 = load i8, i8 addrspace(1)* %gep.align1.offset16, align 16
     %load22 = load i8, i8 addrspace(1)* %gep.align16.offset16, align 16
 
+    ; Load from a dereferenceable and aligned load
+; CHECK: %d4_unaligned_load{{.*}}(unaligned)
+; CHECK: %d4_aligned_load{{.*}}(aligned)
+    %d4_unaligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0
+    %d4_aligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0, !value.align !{i64 16}
+    %load23 = load i32, i32* %d4_unaligned_load, align 16
+    %load24 = load i32, i32* %d4_aligned_load, align 16
+
     ret void
 }
 
Index: lib/IR/LLVMContext.cpp
===================================================================
--- lib/IR/LLVMContext.cpp
+++ lib/IR/LLVMContext.cpp
@@ -116,6 +116,12 @@
   assert(UnpredictableID == MD_unpredictable &&
          "unpredictable kind id drifted");
   (void)UnpredictableID;
+
+  // Create the 'value.align' metadata kind.
+  unsigned ValueAlignID = getMDKindID("value.align");
+  assert(ValueAlignID == MD_value_align &&
+         "value.align kind id drifted");
+  (void)ValueAlignID;
 }
 LLVMContext::~LLVMContext() { delete pImpl; }
 
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -2952,6 +2952,11 @@
     BaseAlign = GV->getAlignment();
   else if (const Argument *A = dyn_cast<Argument>(Base))
     BaseAlign = A->getParamAlignment();
+  else if (const LoadInst *LI = dyn_cast<LoadInst>(Base))
+    if (MDNode *MD = LI->getMetadata(LLVMContext::MD_value_align)) {
+      ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));
+      BaseAlign = CI->getLimitedValue();
+    }
 
   if (!BaseAlign) {
     Type *Ty = Base->getType()->getPointerElementType();
Index: include/llvm/IR/LLVMContext.h
===================================================================
--- include/llvm/IR/LLVMContext.h
+++ include/llvm/IR/LLVMContext.h
@@ -62,7 +62,8 @@
     MD_dereferenceable = 12, // "dereferenceable"
     MD_dereferenceable_or_null = 13, // "dereferenceable_or_null"
     MD_make_implicit = 14, // "make.implicit"
-    MD_unpredictable = 15 // "unpredictable"
+    MD_unpredictable = 15, // "unpredictable"
+    MD_value_align = 16 // "value.align"
   };
 
   /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
Index: docs/LangRef.rst
===================================================================
--- docs/LangRef.rst
+++ docs/LangRef.rst
@@ -6768,9 +6768,10 @@
 
 ::
 
-      <result> = load [volatile] <ty>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>][, !nonnull !<index>][, !dereferenceable !<index>][, !dereferenceable_or_null !<index>]
+      <result> = load [volatile] <ty>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>][, !nonnull !<index>][, !dereferenceable !<index>][, !dereferenceable_or_null !<index>][, !value.align !<value_align_node>]
       <result> = load atomic [volatile] <ty>* <pointer> [singlethread] <ordering>, align <alignment>
       !<index> = !{ i32 1 }
+      !<value_align_node> = !{ i64 <alignment> }
 
 Overview:
 """""""""
@@ -6852,6 +6853,14 @@
 attribute on parameters and return values. This metadata can only be applied
 to loads of a pointer type.
 
+The optional ``!value.align`` metadata must reference a single
+metadata name ``<value_align_node>`` corresponding to a metadata node with one
+``i64`` entry. The existence of the ``!value.align`` metadata on the instruction
+tells the optimizer that the value loaded is known to be aligned to a boundary
+specified by the integer value in the metadata node. This is analogous to the
+''align'' attribute on parameters and return values. This metadata can only be
+applied to loads of a pointer type.
+
 Semantics:
 """"""""""
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12853.34706.patch
Type: text/x-patch
Size: 4176 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150914/09ab99d5/attachment.bin>


More information about the llvm-commits mailing list