<div dir="ltr">Hi All,<div><br></div><div>In order to confine the scope of a local variable allocated using "alloca", we had written a pass named 'undeflocal'. This helps avoid pseudo phi nodes inserted because of the path (carrying an undefined value) starting from the "entry" block. This unwanted phi instruction was preventing some of the optimizations from getting triggered later on.</div><div><br></div><div>For example, consider the following case:</div><div><br></div><div>// void fn() {<br>//    Block 1.... block 3<br>//    for (i=0 ; i<n ; i++) {<br>//      int k;<br>//      if (<>)<br>//       define k<br>//      use of k<br>// }<br><br>Though the value of k gets defined in the "if" block inside the "for" loop, due to the presence of "alloca" in entry block, the initial garbage value of k flows from the entry block of the function.  This expands the scope of the variable k. The undeflocal pass adds a store instruction (say SI) to store value "undef", to the local variable pointer. SI is added just "before" the "lifetime.start" intrinsic for the variable k; the intention was to kill the liveness of the variable k at this point and help avoid insertion of the phi instruction.</div><div><br></div><div>However, now we are facing an issue triggered by the AddressSanitizer, when "clang" is built using our bootstrap build. It throws the "stack-use-after-scope" error. We identified this is due to the "store" introduced by "undeflocal" pass before the lifetime.start intrinsic.<font face="arial, sans-serif" style=""><span style="font-size:11pt"> </span>The value of the additional store is changed to “0” in
place of “undef” by the SROA pass later invoked. As “undeflocal”  has
inserted it before the lifetime.start intrinsic and now the store has a legal
value “0” stored into it, which in turn causes the address sanitizer to complain about
use-after-scope.</font></div><div><font face="arial, sans-serif" style=""><br></font></div><div><p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif" style="">Here is the part of the IR that does this</font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"><b> </b></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><u style=""><font face="arial, sans-serif" style="">After undeflocal</font></u></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><br></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif">if.end9:         
                                ;
preds =
%_ZN4llvm10IndexedMapIN12_GLOBAL__N_18RAGreedy7RegInfoENS_20VirtReg2IndexFunctorEEixEj.exit,
%if.then8</font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif">  %Cascade.0 = phi i32 [ %7,
%_ZN4llvm10IndexedMapIN12_GLOBAL__N_18RAGreedy7RegInfoENS_20VirtReg2IndexFunctorEEixEj.exit
], [ %8, %if.then8 ], !dbg !22012</font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><span style="color:red"><font face="arial, sans-serif">  store i64 undef, i64*
%Cost, align 8, !dbg !22013</font></span></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><span style="color:red"><font face="arial, sans-serif">  %9 = bitcast i64* %Cost to
i8*, !dbg !22013</font></span></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><span style="color:red"><font face="arial, sans-serif">  call void
@llvm.lifetime.start.p0i8(i64 8, i8* nonnull %9) #24, !dbg !22013</font></span></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif"> </font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><u><font face="arial, sans-serif">After SROA</font></u></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif"> </font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif">if.end9:                           
              ;
preds =
%_ZN4llvm10IndexedMapIN12_GLOBAL__N_18RAGreedy7RegInfoENS_20VirtReg2IndexFunctorEEixEj.exit,
%if.then8</font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif">  %Cascade.0 = phi i32 [ %7,
%_ZN4llvm10IndexedMapIN12_GLOBAL__N_18RAGreedy7RegInfoENS_20VirtReg2IndexFunctorEEixEj.exit
], [ %8, %if.then8 ], !dbg !22012</font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><span style="color:red"><font face="arial, sans-serif">  store i32 0, i32*
%Cost.sroa.10, !dbg !22013</font></span></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif">  %Cost.sroa.10.0..sroa_cast349 = bitcast i32*
%Cost.sroa.10 to i8*, !dbg !22013</font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif" style="">  call void @llvm.lifetime.start.p0i8(i64 4, i8*
%Cost.sroa.10.0..sroa_cast349), !dbg !22013</font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"><br></p></div><div><font face="arial, sans-serif">It could be great, if we get suggestions for the proper solution for this. We have thought about the following solutions, however, not certain about its implications on other passes.</font></div><div><font face="arial, sans-serif"><br></font></div><div><ol style="margin-top:0in;margin-bottom:0in" start="1" type="1">
 <li class="gmail-MsoListParagraph" style="margin:0in 0in 0.0001pt 0.25in"><font face="arial, sans-serif" style="">To make “undeflocal” pass add the
     store instruction after lifetime.start.</font></li>
 <li class="gmail-MsoListParagraph" style="margin:0in 0in 0.0001pt 0.25in"><font face="arial, sans-serif">To stop SROA from
     converting undef to 0.</font></li><li class="gmail-MsoListParagraph" style="margin:0in 0in 0.0001pt 0.25in"><font face="arial, sans-serif">To add 'metadata', to SI so that </font>the AddressSanitizer ignores SI.</li>
</ol></div><div><br></div><div>We are skeptical about the solution 1 because the semantics of lifetime.start defined in <font face="arial, sans-serif">"lib/CodeGen/StackColoring.cpp" is a bit confusing. It says:</font></div><div><font face="arial, sans-serif" style=""><br></font></div><div><p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif">//   L2) on a `lifetime.start`, a stack slot is
marked as *in-scope* and</font></p>

<p class="MsoNormal" style="margin:0in 0in 0.0001pt"><font face="arial, sans-serif" style="">//   the stack slot is overwritten with `undef`.</font></p></div><div><br></div><div>As it mentioned, "on" a 'lifteime.start', we are unsure about if it is meant to be before or after it. Will there be any issue in later passes, if we have an "undef" value "store" after lifetime.start.</div><div><br></div><div>Regards,</div><div><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif;font-size:small">------------------------------</span><br></p><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Raghesh Aloor</div><div>AMD India Pvt. Ltd.</div><div>Bengaluru.</div><div>------------------------------</div></div></div></div></div></div></div></div>