[LLVMdev] lifetime.start/end clarification

Renato Golin renato.golin at linaro.org
Tue Nov 4 05:19:03 PST 2014


Hi Arnaud.

In that path, X x seems to be undefined, so the behaviour is anyone's
guess. If I'm not mistaken, the standard says that kind of code is
ill-formed (6.7-p3).

Clang folks might know better.

cheers,
--renato

On 4 November 2014 11:59, Arnaud A. de Grandmaison
<arnaud.degrandmaison at arm.com> wrote:
> The LRM (http://llvm.org/docs/LangRef.html#llvm-lifetime-start-intrinsic)
> essentially  states that:
>
> - ptr is dead before a call to “lifetime.start size, ptr”
>
> - ptr is dead after a call to “lifetime.end size, ptr”
>
>
>
> This is all good and fine, and the expected use case is that all
> “lifetime.end size, ptr” markers are matched with a preceding
> “lifetime.start size, ptr” in the CFG.
>
>
>
> What is supposed to happen when a “lifetime.end size, ptr” is not matched
> with a “lifetime.start size, ptr” ? I think there are a few possible
> answers:
>
> - the memory area pointed to by ptr is assumed to be alive since function
> entry
>
> - the memory area pointed to by ptr is assumed to be dead since function
> entry, as it has not been marked alive
>
> - this is an unexpected situation
>
>
>
> I think this ambiguity should be cleared in the LRM, because today’s
> implicit assumption may be broken at any time.
>
>
>
> 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.
>
>
>
> Cheers,
>
> --
>
> Arnaud
>
>
>
>
> _______________________________________________
> 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