[LLVMdev] lifetime.start/end clarification

Hal Finkel hfinkel at anl.gov
Tue Nov 4 08:16:07 PST 2014


----- Original Message -----
> From: "Arnaud A. de Grandmaison" <arnaud.degrandmaison at arm.com>
> To: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
> Sent: Tuesday, November 4, 2014 5:59:28 AM
> Subject: [LLVMdev] lifetime.start/end clarification
> 
> 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
> 

When you say "unmatched", do you mean not visible in any dominating block? Assuming we realize that the lifetime begin could also be inside a function called by any of these dominating blocks (assuming the pointer is an argument or is captured prior to the call), it seems most logical to say that the ptr is alive (and invariant) from the function entry.

> 
> 
> I think this ambiguity should be cleared in the LRM, because today’s
> implicit assumption

What is today's implicit assumption?

Thanks again,
Hal

> 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
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory




More information about the llvm-dev mailing list