[LLVMdev] lifetime.start/end clarification

Philip Reames listmail at philipreames.com
Wed Nov 5 11:31:40 PST 2014


On 11/05/2014 10:54 AM, Arnaud A. de Grandmaison wrote:
>
> *trimmed for length*
>
> This is not a theoretical question: clang can generate such cases. For 
> example, the following testcase:
>
> struct X {
>
>   void doSomething();
>
>   char b[33];
>
> };
>
> void bar(X &);
>
> void baz();
>
> void test(int i) {
>
>   if (i==9) {
>
>     X x;
>
> x.doSomething();
>
> label:
>
>     bar(x);
>
>   } else {
>
>     baz();
>
>     if (i==0)
>
>       goto label;
>
>   }
>
> }
>
> Produces:
>
> %struct.X = type { [33 x i8] }
>
> define void @_Z4testi(i32 %i) {
>
> entry:
>
>   %x = alloca %struct.X, align 1
>
>   %cmp = icmp eq i32 %i, 9
>
>   br i1 %cmp, label %if.then, label %if.else
>
> if.then: ; preds = %entry
>
>   %0 = getelementptr inbounds %struct.X* %x, i64 0, i32 0, i64 0
>
>   call void @llvm.lifetime.start(i64 33, i8* %0)
>
>   call void @_ZN1X11doSomethingEv(%struct.X* %x)
>
>   br label %label
>
> label: ; preds = %if.else.label_crit_edge, %if.then
>
>   %.pre-phi = phi i8* [ %.pre, %if.else.label_crit_edge ], [ %0, 
> %if.then ]
>
>   call void @_Z3barR1X(%struct.X* dereferenceable(33) %x)
>
>   call void @llvm.lifetime.end(i64 33, i8* %.pre-phi)
>
>   br label %if.end3
>
> if.else:       ; preds = %entry
>
>   tail call void @_Z3bazv()
>
>   %cmp1 = icmp eq i32 %i, 0
>
>   br i1 %cmp1, label %if.else.label_crit_edge, label %if.end3
>
> if.else.label_crit_edge: ; preds = %if.else
>
>   %.pre = getelementptr inbounds %struct.X* %x, i64 0, i32 0, i64 0
>
>   br label %label
>
> if.end3: ; preds = %if.else, %label
>
>   ret void
>
> }
>
> Note that the path thru if.else.label_crit_edge has no lifetime start.
>
> This seems fine to me.  The optimizer can (soundly) conclude that %p 
> is dead after the "lifetime.end" (for the two instructions), and dead 
> before the "lifetime.start" (for the *single* instruction in that 
> basic block, *not* for the previous BB).  This seems like the proper 
> result for this example, am I missing something?
>
> With the clarification you made on the semantics, the above IR is 
> correct, but could be improved when clang generates it: the 
> label_crit_edge block should contain a lifetime.start for the alloca.
>
Another approach would be have LLVM prove that %x is uninitialized along 
the path through if.else.label_crit_edge and then combine that with the 
lifetime.start along the other path.  This would require reasoning about 
pointer escapes, but that's fairly tractable.  It actually doesn't seem 
unreasonable that GVN would get this case.  Do you have a counter 
example where an optimization is missed only when the lifetime.start is 
not present?

More generally, are there specific optimizations which aren't kicking in 
with the current placement strategy that you'd like to see?

Philip


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141105/f75ceb16/attachment.html>


More information about the llvm-dev mailing list