Introduce !align metadata for load instruction
authorArtur Pilipenko <apilipenko@azulsystems.com>
Mon, 28 Sep 2015 17:41:08 +0000 (17:41 +0000)
committerArtur Pilipenko <apilipenko@azulsystems.com>
Mon, 28 Sep 2015 17:41:08 +0000 (17:41 +0000)
Reviewed By: hfinkel

Differential Revision: http://reviews.llvm.org/D12853

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248721 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 9b8aaa7a1fd278cd3e9ae6744a53e6788c0d0548..bc4df0586460e654b5998e04b98a1daf14c6069b 100644 (file)
@@ -6860,10 +6860,11 @@ Syntax:
 
 ::
 
-      <result> = load [volatile] <ty>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>][, !invariant.group !<index>][, !nonnull !<index>][, !dereferenceable !<deref_bytes_node>][, !dereferenceable_or_null !<deref_bytes_node>]
+      <result> = load [volatile] <ty>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>][, !invariant.group !<index>][, !nonnull !<index>][, !dereferenceable !<deref_bytes_node>][, !dereferenceable_or_null !<deref_bytes_node>][, !align !<align_node>]
       <result> = load atomic [volatile] <ty>* <pointer> [singlethread] <ordering>, align <alignment> [, !invariant.group !<index>]
       !<index> = !{ i32 1 }
       !<deref_bytes_node> = !{i64 <dereferenceable_bytes>}
+      !<align_node> = !{ i64 <value_alignment> }
 
 Overview:
 """""""""
@@ -6948,6 +6949,14 @@ value in the metadata node. This is analogous to the ''dereferenceable_or_null''
 attribute on parameters and return values. This metadata can only be applied
 to loads of a pointer type.
 
+The optional ``!align`` metadata must reference a single metadata name
+``<align_node>`` corresponding to a metadata node with one ``i64`` entry.
+The existence of the ``!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. The alignment must be a power of 2.
+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:
 """"""""""
 
index 336aca2d5ba13778a4853b06a5673a7130737c0f..24e95f6a62fd80828c18ca092a40e45bee3fe67b 100644 (file)
@@ -63,7 +63,8 @@ public:
     MD_dereferenceable_or_null = 13, // "dereferenceable_or_null"
     MD_make_implicit = 14, // "make.implicit"
     MD_unpredictable = 15, // "unpredictable"
-    MD_invariant_group = 16 // "invariant.group"
+    MD_invariant_group = 16, // "invariant.group"
+    MD_align = 17 // "align"
   };
 
   /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
index 736077dc47760a8ffd6fbcdfaa6afe48bdaa8ec9..5481e722e536d996ae08e3afe783c255912ba7c5 100644 (file)
@@ -2979,6 +2979,11 @@ static bool isAligned(const Value *Base, APInt Offset, unsigned Align,
     BaseAlign = A->getParamAlignment();
   else if (auto CS = ImmutableCallSite(Base))
     BaseAlign = CS.getAttributes().getParamAlignment(AttributeSet::ReturnIndex);
+  else if (const LoadInst *LI = dyn_cast<LoadInst>(Base))
+    if (MDNode *MD = LI->getMetadata(LLVMContext::MD_align)) {
+      ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));
+      BaseAlign = CI->getLimitedValue();
+    }
 
   if (!BaseAlign) {
     Type *Ty = Base->getType()->getPointerElementType();
index ee971c1be194e001ad6fd1a571c3970af939ec82..cecc6335ef1bd8b865d912f3a401c09a6d931635 100644 (file)
@@ -123,6 +123,10 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
          "invariant.group kind id drifted");
   (void)InvariantGroupId;
 
+  // Create the 'align' metadata kind.
+  unsigned AlignID = getMDKindID("align");
+  assert(AlignID == MD_align && "align kind id drifted");
+  (void)AlignID;
 }
 LLVMContext::~LLVMContext() { delete pImpl; }
 
index 550b01c4c9aa12e2f38690dcabe85c91f26cdfe0..c7ca21ab0614a04bfd80a3701cb571ba89f7b990 100644 (file)
@@ -122,6 +122,14 @@ entry:
     %load24 = load i32, i32* %deref_return, align 16
     %load25 = load i32, i32* %deref_and_aligned_return, 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, !align !{i64 16}
+    %load26 = load i32, i32* %d4_unaligned_load, align 16
+    %load27 = load i32, i32* %d4_aligned_load, align 16
+
     ret void
 }