<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">
<br class="">
<div>
<blockquote type="cite" class="">
<div class="">On 14 Sep 2015, at 21:36, James Molloy <<a href="mailto:james@jamesmolloy.co.uk" class="">james@jamesmolloy.co.uk</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">Hi,<br class="">
<br class="">
But isn't this exactly the same semantics as the example I gave? I'm still struggling to see the difference.</div>
</blockquote>
In the first example the load %2 can be executed speculatively because we know that the pointer alignment is greater than operation alignment. No UB.</div>
<div><br class="">
</div>
<div>In the second example operation alignment restricts the set of possible pointers. We can assume nothing about %1 alignment, but load operation requires it to be at least 4 bytes aligned. We can’t guarantee that there is no UB, so this load can’t be executed
 speculatively.</div>
<div><br class="">
</div>
<div>In both cases I assume that %1 is dereferenceable.</div>
<div><br class="">
</div>
<div>Artur<br class="">
<blockquote type="cite" class="">
<div class=""><br class="">
<br class="">
James<br class="">
<div class="gmail_quote">
<div dir="ltr" class="">On Mon, 14 Sep 2015 at 19:32, Artur Pilipenko via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>> wrote:<br class="">
</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word" class="">Hi,
<div class=""><br class="">
</div>
<div class="">
<div class="">
<div class=""></div>
</div>
</div>
</div>
<div style="word-wrap:break-word" class="">
<div class="">
<div class="">
<div class="">
<blockquote type="cite" class="">
<div class="">On 14 Sep 2015, at 21:12, James Molloy <<a href="mailto:james@jamesmolloy.co.uk" target="_blank" class="">james@jamesmolloy.co.uk</a>> wrote:</div>
<br class="">
<div class="">
<div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">
Hi,
<div class=""><br class="">
</div>
<div class="">I'm probably missing something obvious, but it sounds like you want to do this:</div>
<div class=""><br class="">
</div>
<div class="">%1 = load i8*, i8** %p, !align !0 ; %1 is pointer-to-value</div>
<div class="">%2 = load i8, i8* %1 ; value is %2</div>
<div class=""><br class="">
</div>
<div class="">Why can't you instead mark all loads of %1 as aligned?:</div>
<div class=""><br class="">
</div>
<div class="">
<div style="font-size:13.2px;line-height:19.8px" class="">%1 = load i8*, i8** %p, !align !0 ; %1 is pointer-to-value</div>
</div>
<div class="">%2 = load i8, i8* %1, align 4</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
<div style="word-wrap:break-word" class="">
<div class="">
<div class="">
<div class="">Align argument here specifies alignment which is “required" for the load. If actual alignment of a pointer is less than load alignment it’s an undefined behaviour. </div>
<div class=""><br class="">
</div>
<div class="">If we want to execute this load speculatively we need be sure that the load doesn’t have undefined behaviour. So we need to know that a pointer we are dereferencing is properly aligned.</div>
<div class=""><br class="">
</div>
<div class="">Artur </div>
</div>
</div>
</div>
<div style="word-wrap:break-word" class="">
<div class="">
<div class="">
<div class=""><br class="">
<blockquote type="cite" class="">
<div class="">
<div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">
<div class=""><br class="">
</div>
<div class="">Again, I'm probably missing something obvious.</div>
<div class=""><br class="">
</div>
<div class="">Cheers,</div>
<div class=""><br class="">
</div>
<div class="">James</div>
</div>
<br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">
<div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div dir="ltr" class="">On Mon, 14 Sep 2015 at 19:03 Artur Pilipenko via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a>> wrote:<br class="">
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
apilipenko created this revision.<br class="">
apilipenko added reviewers: hfinkel, reames, sanjoy.<br class="">
apilipenko added a subscriber: llvm-commits.<br class="">
<br class="">
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.<br class="">
<br class="">
Introduce new !value.align metadata for load instruction. This metadata specifies alignment of the loaded pointer value.<br class="">
<br class="">
<a href="http://reviews.llvm.org/D12853" rel="noreferrer" target="_blank" class="">http://reviews.llvm.org/D12853</a><br class="">
<br class="">
Files:<br class="">
  docs/LangRef.rst<br class="">
  include/llvm/IR/LLVMContext.h<br class="">
  lib/Analysis/ValueTracking.cpp<br class="">
  lib/IR/LLVMContext.cpp<br class="">
  test/Analysis/ValueTracking/memory-dereferenceable.ll<br class="">
<br class="">
Index: test/Analysis/ValueTracking/memory-dereferenceable.ll<br class="">
===================================================================<br class="">
--- test/Analysis/ValueTracking/memory-dereferenceable.ll<br class="">
+++ test/Analysis/ValueTracking/memory-dereferenceable.ll<br class="">
@@ -111,6 +111,14 @@<br class="">
     %load21 = load i8, i8 addrspace(1)* %gep.align1.offset16, align 16<br class="">
     %load22 = load i8, i8 addrspace(1)* %gep.align16.offset16, align 16<br class="">
<br class="">
+    ; Load from a dereferenceable and aligned load<br class="">
+; CHECK: %d4_unaligned_load{{.*}}(unaligned)<br class="">
+; CHECK: %d4_aligned_load{{.*}}(aligned)<br class="">
+    %d4_unaligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0<br class="">
+    %d4_aligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0, !value.align !{i64 16}<br class="">
+    %load23 = load i32, i32* %d4_unaligned_load, align 16<br class="">
+    %load24 = load i32, i32* %d4_aligned_load, align 16<br class="">
+<br class="">
     ret void<br class="">
 }<br class="">
<br class="">
Index: lib/IR/LLVMContext.cpp<br class="">
===================================================================<br class="">
--- lib/IR/LLVMContext.cpp<br class="">
+++ lib/IR/LLVMContext.cpp<br class="">
@@ -116,6 +116,12 @@<br class="">
   assert(UnpredictableID == MD_unpredictable &&<br class="">
          "unpredictable kind id drifted");<br class="">
   (void)UnpredictableID;<br class="">
+<br class="">
+  // Create the 'value.align' metadata kind.<br class="">
+  unsigned ValueAlignID = getMDKindID("value.align");<br class="">
+  assert(ValueAlignID == MD_value_align &&<br class="">
+         "value.align kind id drifted");<br class="">
+  (void)ValueAlignID;<br class="">
 }<br class="">
 LLVMContext::~LLVMContext() { delete pImpl; }<br class="">
<br class="">
Index: lib/Analysis/ValueTracking.cpp<br class="">
===================================================================<br class="">
--- lib/Analysis/ValueTracking.cpp<br class="">
+++ lib/Analysis/ValueTracking.cpp<br class="">
@@ -2952,6 +2952,11 @@<br class="">
     BaseAlign = GV->getAlignment();<br class="">
   else if (const Argument *A = dyn_cast<Argument>(Base))<br class="">
     BaseAlign = A->getParamAlignment();<br class="">
+  else if (const LoadInst *LI = dyn_cast<LoadInst>(Base))<br class="">
+    if (MDNode *MD = LI->getMetadata(LLVMContext::MD_value_align)) {<br class="">
+      ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));<br class="">
+      BaseAlign = CI->getLimitedValue();<br class="">
+    }<br class="">
<br class="">
   if (!BaseAlign) {<br class="">
     Type *Ty = Base->getType()->getPointerElementType();<br class="">
Index: include/llvm/IR/LLVMContext.h<br class="">
===================================================================<br class="">
--- include/llvm/IR/LLVMContext.h<br class="">
+++ include/llvm/IR/LLVMContext.h<br class="">
@@ -62,7 +62,8 @@<br class="">
     MD_dereferenceable = 12, // "dereferenceable"<br class="">
     MD_dereferenceable_or_null = 13, // "dereferenceable_or_null"<br class="">
     MD_make_implicit = 14, // "make.implicit"<br class="">
-    MD_unpredictable = 15 // "unpredictable"<br class="">
+    MD_unpredictable = 15, // "unpredictable"<br class="">
+    MD_value_align = 16 // "value.align"<br class="">
   };<br class="">
<br class="">
   /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.<br class="">
Index: docs/LangRef.rst<br class="">
===================================================================<br class="">
--- docs/LangRef.rst<br class="">
+++ docs/LangRef.rst<br class="">
@@ -6768,9 +6768,10 @@<br class="">
<br class="">
 ::<br class="">
<br class="">
-      <result> = load [volatile] <ty>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>][, !nonnull !<index>][, !dereferenceable !<index>][, !dereferenceable_or_null !<index>]<br class="">
+      <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>]<br class="">
       <result> = load atomic [volatile] <ty>* <pointer> [singlethread] <ordering>, align <alignment><br class="">
       !<index> = !{ i32 1 }<br class="">
+      !<value_align_node> = !{ i64 <alignment> }<br class="">
<br class="">
 Overview:<br class="">
 """""""""<br class="">
@@ -6852,6 +6853,14 @@<br class="">
 attribute on parameters and return values. This metadata can only be applied<br class="">
 to loads of a pointer type.<br class="">
<br class="">
+The optional ``!value.align`` metadata must reference a single<br class="">
+metadata name ``<value_align_node>`` corresponding to a metadata node with one<br class="">
+``i64`` entry. The existence of the ``!value.align`` metadata on the instruction<br class="">
+tells the optimizer that the value loaded is known to be aligned to a boundary<br class="">
+specified by the integer value in the metadata node. This is analogous to the<br class="">
+''align'' attribute on parameters and return values. This metadata can only be<br class="">
+applied to loads of a pointer type.<br class="">
+<br class="">
 Semantics:<br class="">
 """"""""""<br class="">
<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a></blockquote>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
_______________________________________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="">
</blockquote>
</div>
</div>
</blockquote>
</div>
<br class="">
</body>
</html>