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

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 14 11:36:01 PDT 2015


Hi,

But isn't this exactly the same semantics as the example I gave? I'm still
struggling to see the difference.

James
On Mon, 14 Sep 2015 at 19:32, Artur Pilipenko via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Hi,
>
> On 14 Sep 2015, at 21:12, James Molloy <james at jamesmolloy.co.uk> wrote:
>
> Hi,
>
> I'm probably missing something obvious, but it sounds like you want to do
> this:
>
> %1 = load i8*, i8** %p, !align !0 ; %1 is pointer-to-value
> %2 = load i8, i8* %1 ; value is %2
>
> Why can't you instead mark all loads of %1 as aligned?:
>
> %1 = load i8*, i8** %p, !align !0 ; %1 is pointer-to-value
> %2 = load i8, i8* %1, align 4
>
> 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.
>
> 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.
>
> Artur
>
>
> Again, I'm probably missing something obvious.
>
> Cheers,
>
> James
>
> On Mon, 14 Sep 2015 at 19:03 Artur Pilipenko via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> 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:
>>  """"""""""
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150914/64d9af01/attachment.html>


More information about the llvm-commits mailing list