<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<div class="moz-cite-prefix">On 11/05/2014 10:54 AM, Arnaud A. de
Grandmaison wrote:<br>
</div>
<blockquote cite="mid:000501cff929$f9823870$ec86a950$@arm.com"
type="cite">
<meta http-equiv="Content-Type" content="text/html;
charset=windows-1252">
<meta name="Generator" content="Microsoft Word 14 (filtered
medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
color:black;
mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal;
font-family:"Calibri","sans-serif";
color:windowtext;}
span.EmailStyle18
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
<div class="WordSection1">
<p class="MsoNormal"><span
style="color:#1F497D;mso-fareast-language:EN-GB"><o:p> </o:p>*trimmed
for length*<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">This is not a
theoretical question: clang can generate such cases. For
example, the following testcase:<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">struct X {<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> void
doSomething();<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> char b[33];<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">};<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">void bar(X
&);<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">void baz();<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">void test(int i)
{<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> if (i==9) {<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> X x;<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">
x.doSomething();<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">label:<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> bar(x);<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> } else {<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> baz();<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> if (i==0)<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> goto
label;<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> }<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">}<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">Produces:<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">%struct.X = type
{ [33 x i8] }<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">define void
@_Z4testi(i32 %i) {<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">entry:<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> %x = alloca
%struct.X, align 1<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> %cmp = icmp eq
i32 %i, 9<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> br i1 %cmp,
label %if.then, label %if.else<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">if.then:
; preds = %entry<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> %0 =
getelementptr inbounds %struct.X* %x, i64 0, i32 0, i64 0<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> call void
@llvm.lifetime.start(i64 33, i8* %0)<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> call void
@_ZN1X11doSomethingEv(%struct.X* %x)<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> br label
%label<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">label:
; preds = %if.else.label_crit_edge, %if.then<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> %.pre-phi =
phi i8* [ %.pre, %if.else.label_crit_edge ], [ %0, %if.then ]<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> call void
@_Z3barR1X(%struct.X* dereferenceable(33) %x)<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> call void
@llvm.lifetime.end(i64 33, i8* %.pre-phi)<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> br label
%if.end3<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">if.else:
; preds = %entry<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> tail call void
@_Z3bazv()<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> %cmp1 = icmp
eq i32 %i, 0<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> br i1 %cmp1,
label %if.else.label_crit_edge, label %if.end3<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">if.else.label_crit_edge:
; preds = %if.else<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> %.pre =
getelementptr inbounds %struct.X* %x, i64 0, i32 0, i64 0<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> br label
%label<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">if.end3:
; preds = %if.else, %label<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> ret void<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">}<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt">Note that the
path thru if.else.label_crit_edge has no lifetime start.<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span
style="font-size:12.0pt;font-family:"Times New
Roman","serif";mso-fareast-language:EN-GB">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?<br>
<br>
</span><span style="font-size:12.0pt;font-family:"Times
New
Roman","serif";color:#1F497D;mso-fareast-language:EN-GB"><o:p></o:p></span></p>
<p class="MsoNormal"><span
style="color:#1F497D;mso-fareast-language:EN-GB">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.</span></p>
</div>
</blockquote>
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? <br>
<br>
More generally, are there specific optimizations which aren't
kicking in with the current placement strategy that you'd like to
see?<br>
<br>
Philip<br>
<br>
<br>
</body>
</html>