[LLVMdev] Meaning of the nocapture attribute (possible bug?)

Duncan Sands baldrick at free.fr
Tue Oct 16 00:30:44 PDT 2012


Hi Krzysztof,

> Is this code valid?

yes, I think so.

> Function f takes a "nocapture" pointer p, and passes it to function g that does
> not have nocapture in its parameter list.  There is nothing to stop g from
> "capturing" p.

It would be wrong for the optimizers to deduce a nocapture attribute for f in
this context, as they don't know anything about the semantics of g.  However if
whoever produced this bitcode knows the semantics of g, for example because it
is some funky routine in their runtime, then it could be correct.  For example, 
consider this definition of g:

define void @g(i32** %q, i32* %p) {
   store i32* %p, i32** %q
   ret void
}

In general this function captures the %p argument.  But in the special way it
is used from f, it doesn't result in f capturing its %p argument.

Ciao, Duncan.

>
> -Krzysztof
>
>
> On 10/8/2012 8:54 AM, Duncan Sands wrote:
>> Hi Richard, I think it is a bug.
>>
>> Ciao, Duncan.
>>
>> On 08/10/12 14:34, Richard Osborne wrote:
>>> Regarding the nocapture attribute the language ref says: "the callee
>>> does not
>>> make any copies of the pointer that outlive the callee itself". From I
>>> inferred
>>> that it is OK for the callee to make a copy of the pointer that
>>> doesn't outlive
>>> the call. However if I write some code that does this the optimizers
>>> don't do
>>> what I'd expect. Consider the following the example:
>>>
>>> declare void @g(i32** %p, i32* %q) nounwind
>>>
>>> define i32 @f(i32* noalias nocapture %p) nounwind {
>>> entry:
>>>    %q = alloca i32*
>>>    call void @g(i32** %q, i32* %p) nounwind
>>>    store i32 0, i32* %p
>>>    %0 = load i32** %q
>>>    store i32 1, i32* %0
>>>    %1 = load i32* %p
>>>    ret i32 %1
>>> }
>>>
>>> I would expect it to be valid for g() to store the value of its second
>>> argument
>>> to the object pointed to by its first argument. Because of this I
>>> would expect a
>>> possible memory dependency between the last load (%1 = load i32* %p)
>>> and the
>>> last store (store i32 1, i32* %0). However if I run the example
>>> through opt
>>> -basicaa -gvn then the return instruction is optimized to ret i32 0
>>> suggesting
>>> basicaa doesn't think there is any such dependency.
>>>
>>> Is this a bug in the basic alias analysis pass or am I
>>> misunderstanding the
>>> semantics of nocapture?
>>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>




More information about the llvm-dev mailing list