<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:p="urn:schemas-microsoft-com:office:powerpoint" xmlns:a="urn:schemas-microsoft-com:office:access" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" xmlns:b="urn:schemas-microsoft-com:office:publisher" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:odc="urn:schemas-microsoft-com:office:odc" xmlns:oa="urn:schemas-microsoft-com:office:activation" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:q="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rtc="http://microsoft.com/officenet/conferencing" xmlns:D="DAV:" xmlns:Repl="http://schemas.microsoft.com/repl/" xmlns:mt="http://schemas.microsoft.com/sharepoint/soap/meetings/" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:ppda="http://www.passport.com/NameSpace.xsd" xmlns:ois="http://schemas.microsoft.com/sharepoint/soap/ois/" xmlns:dir="http://schemas.microsoft.com/sharepoint/soap/directory/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp" xmlns:udc="http://schemas.microsoft.com/data/udc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sub="http://schemas.microsoft.com/sharepoint/soap/2002/1/alerts/" xmlns:ec="http://www.w3.org/2001/04/xmlenc#" xmlns:sp="http://schemas.microsoft.com/sharepoint/" xmlns:sps="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:udcs="http://schemas.microsoft.com/data/udc/soap" xmlns:udcxf="http://schemas.microsoft.com/data/udc/xmlfile" xmlns:udcp2p="http://schemas.microsoft.com/data/udc/parttopart" xmlns:wf="http://schemas.microsoft.com/sharepoint/soap/workflow/" xmlns:dsss="http://schemas.microsoft.com/office/2006/digsig-setup" xmlns:dssi="http://schemas.microsoft.com/office/2006/digsig" xmlns:mdssi="http://schemas.openxmlformats.org/package/2006/digital-signature" xmlns:mver="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns:mrels="http://schemas.openxmlformats.org/package/2006/relationships" xmlns:spwp="http://microsoft.com/sharepoint/webpartpages" xmlns:ex12t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:ex12m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:pptsl="http://schemas.microsoft.com/sharepoint/soap/SlideLibrary/" xmlns:spsl="http://microsoft.com/webservices/SharePointPortalServer/PublishedLinksService" xmlns:Z="urn:schemas-microsoft-com:" xmlns:tax="http://schemas.microsoft.com/sharepoint/taxonomy/soap/" xmlns:tns="http://schemas.microsoft.com/sharepoint/soap/recordsrepository/" xmlns:spsup="http://microsoft.com/webservices/SharePointPortalServer/UserProfileService" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:st="" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<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:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
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:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
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]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="color:#1F497D">Update …<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">It is legal to insert an unreachable after the call to a noreturn function in the if block, but the optimizer should not discard the call in a later optimization pass.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">When the inliner pass is run after PruneEH, the call instruction is deemed to have no side effects and is removed.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">If I add a noinline attribute to the definition of the noreturn function, the call is again deemed to have no side effects and is removed.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">If I put an inline asm nop in the noreturn function, then calls to it are no longer considered trivially dead.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">Is a call to a function that contains only an empty “while (1) ;” loop considered dead code? I don’t think it should be.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">One use of such a function in an embedded system is as a “parking” function. For example, if an error condition occurs at run time which requires service from a regularly occurring interrupt handler, the code
 that detects the error condition may “park” a thread in an endless loop function to wait on the interrupt handler.<o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="color:#1F497D"><o:p> </o:p></span></a></p>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> llvm-dev [mailto:llvm-dev-bounces@lists.llvm.org]
<b>On Behalf Of </b>Snider, Todd via llvm-dev<br>
<b>Sent:</b> Tuesday, June 4, 2019 10:12 AM<br>
<b>To:</b> llvm-dev<br>
<b>Subject:</b> [EXTERNAL] [llvm-dev] is this a bug in PruneEH?<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I have the following C source:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">extern unsigned int donut;<o:p></o:p></p>
<p class="MsoNormal">void f1();<o:p></o:p></p>
<p class="MsoNormal">void f2();<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">void f1()<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">  unsigned int *magic = &donut;<o:p></o:p></p>
<p class="MsoNormal">  if (*magic != 286529877) {<o:p></o:p></p>
<p class="MsoNormal">    f2();<o:p></o:p></p>
<p class="MsoNormal">  }<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">void f2() {<o:p></o:p></p>
<p class="MsoNormal">/* Loop here forever if application is built with wrong version of ROM image */<o:p></o:p></p>
<p class="MsoNormal">  while(1) {<o:p></o:p></p>
<p class="MsoNormal">    ;<o:p></o:p></p>
<p class="MsoNormal">  }<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The –O2 level PruneEH pass uses SimplifyFunction() which contains this code:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )<o:p></o:p></p>
<p class="MsoNormal">      if (CallInst *CI = dyn_cast<CallInst>(I++))<o:p></o:p></p>
<p class="MsoNormal">        if (CI->doesNotReturn() && !CI->isMustTailCall() &&<o:p></o:p></p>
<p class="MsoNormal">            !isa<UnreachableInst>(I)) {<o:p></o:p></p>
<p class="MsoNormal">          // This call calls a function that cannot return.  Insert an<o:p></o:p></p>
<p class="MsoNormal">          // unreachable instruction after it and simplify the code.  Do this<o:p></o:p></p>
<p class="MsoNormal">          // by splitting the BB, adding the unreachable, then deleting the<o:p></o:p></p>
<p class="MsoNormal">          // new BB.<o:p></o:p></p>
<p class="MsoNormal">          BasicBlock *New = BB->splitBasicBlock(I);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">          // Remove the uncond branch and add an unreachable.<o:p></o:p></p>
<p class="MsoNormal">          BB->getInstList().pop_back();<o:p></o:p></p>
<p class="MsoNormal">          new UnreachableInst(BB->getContext(), &*BB);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">          DeleteBasicBlock(New, CG);  // Delete the new BB.<o:p></o:p></p>
<p class="MsoNormal">          MadeChange = true;<o:p></o:p></p>
<p class="MsoNormal">          ++NumUnreach;<o:p></o:p></p>
<p class="MsoNormal">          break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The nested if in SimplifyFunction() will essentially eliminate the call to f2() in the definition of f1() in the source that is being compiled. Here is the before and after pass IR dumps:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">*** IR Dump Before Remove unused exception handling info ***<o:p></o:p></p>
<p class="MsoNormal">; Function Attrs: nounwind<o:p></o:p></p>
<p class="MsoNormal">define hidden void @f1() local_unnamed_addr #0 {<o:p></o:p></p>
<p class="MsoNormal">  %1 = load i32, i32* @donut, align 4, !tbaa !3<o:p></o:p></p>
<p class="MsoNormal">  %2 = icmp eq i32 %1, 286529877<o:p></o:p></p>
<p class="MsoNormal">  br i1 %2, label %4, label %3<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">3:                                                ; preds = %0<o:p></o:p></p>
<p class="MsoNormal">  call void @f2()<o:p></o:p></p>
<p class="MsoNormal">  br label %4<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">4:                                                ; preds = %0, %3<o:p></o:p></p>
<p class="MsoNormal">  ret void<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">*** IR Dump After Remove unused exception handling info ***<o:p></o:p></p>
<p class="MsoNormal">; Function Attrs: nounwind<o:p></o:p></p>
<p class="MsoNormal">define hidden void @f1() local_unnamed_addr #0 {<o:p></o:p></p>
<p class="MsoNormal">  %1 = load i32, i32* @donut, align 4, !tbaa !3<o:p></o:p></p>
<p class="MsoNormal">  %2 = icmp eq i32 %1, 286529877<o:p></o:p></p>
<p class="MsoNormal">  br i1 %2, label %4, label %3<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">3:                                                ; preds = %0<o:p></o:p></p>
<p class="MsoNormal">  call void @f2()<o:p></o:p></p>
<p class="MsoNormal">  unreachable<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">4:                                                ; preds = %0<o:p></o:p></p>
<p class="MsoNormal">  ret void<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">If the call to f2() is the only thing in the if block, then inserting an unreachable after it will later be interpreted as an unreachable block.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Is this a legal optimization?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">~ Todd Snider<o:p></o:p></p>
</div>
</body>
</html>