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

Roel Jordans r.jordans at tue.nl
Tue Oct 16 06:47:38 PDT 2012


Hi all,

Are you sure that the problem here is with the nocapture flag and not 
with the noalias?

Removing noalias from the function definition of @f results in the 
expected output.

My guess is that something goes wrong in determining that *%q can be 
based on %p through @g which results in a 'no alias' relation for the 
two where there should be a 'may alias' result.

For example, the original version produces the following:

$ opt test.ll -basicaa -print-alias-sets -disable-output
Alias Set Tracker: 2 alias sets for 3 pointer values.
   AliasSet[0x9e22028, 2] may alias, Mod/Ref   Pointers: (i32** %q, 
18446744073709551615), (i32* %0, 18446744073709551615)
     1 Unknown instructions: void <badref>
   AliasSet[0x9e22868, 1] must alias, Mod/Ref   Pointers: (i32* %p, 
18446744073709551615)


Whereas the version without 'noalias' attribute produces the following:

$ opt test.ll -basicaa -print-alias-sets -disable-output
Alias Set Tracker: 1 alias sets for 3 pointer values.
   AliasSet[0x97db018, 3] may alias, Mod/Ref   Pointers: (i32* %p, 
18446744073709551615), (i32** %q, 18446744073709551615), (i32* %0, 
18446744073709551615)
     1 Unknown instructions: void <badref>

Cheers,
  Roel


> 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?
>
> --
> Richard Osborne | XMOS
> http://www.xmos.com




More information about the llvm-dev mailing list