<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;}
/* 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-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@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"><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>