[LLVMdev] lifetime.start/end clarification
Arnaud A. de Grandmaison
arnaud.degrandmaison at arm.com
Tue Nov 4 03:59:28 PST 2014
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141104/64e2f5f7/attachment.html>
More information about the llvm-dev
mailing list