<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:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@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:12.0pt;
        font-family:"Times New Roman",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;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:56.7pt 42.5pt 56.7pt 85.05pt;}
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="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">In progress of reverting, will investigate it after revert.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="RU" style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Thank you,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Serguei.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="RU" style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Chandler Carruth [mailto:chandlerc@gmail.com]
<br>
<b>Sent:</b> Monday, June 26, 2017 1:50 PM<br>
<b>To:</b> Serguei Katkov <serguei.katkov@azul.com>; llvm-commits@lists.llvm.org<br>
<b>Subject:</b> Re: [llvm] r306272 - [MBP] do not rotate loop if it creates extra branch<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">I have a strong suspicion this caused:<o:p></o:p></p>
<div>
<p class="MsoNormal"><a href="http://lab.llvm.org:8011/builders/clang-ppc64be-linux-multistage/builds/4273">http://lab.llvm.org:8011/builders/clang-ppc64be-linux-multistage/builds/4273</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">And several other stage2 failures in the bots right now. (stack trace looks like MBP)<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Sun, Jun 25, 2017 at 10:27 PM Serguei Katkov via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">Author: skatkov<br>
Date: Sun Jun 25 22:27:27 2017<br>
New Revision: 306272<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=306272&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=306272&view=rev</a><br>
Log:<br>
[MBP] do not rotate loop if it creates extra branch<br>
<br>
This is a last fix for the corner case of PR32214. Actually this is not really corner case in general.<br>
<br>
We should not do a loop rotation if we create an additional branch due to it.<br>
Consider the case where we have a loop chain H, M, B, C , where<br>
H is header with viable fallthrough from pre-header and exit from the loop<br>
M - some middle block<br>
B - backedge to Header but with exit from the loop also.<br>
C - some cold block of the loop.<br>
<br>
Let's H is determined as a best exit. If we do a loop rotation M, B, C, H we can introduce the extra branch.<br>
Let's compute the change in number of branches:<br>
+1 branch from pre-header to header<br>
-1 branch from header to exit<br>
+1 branch from header to middle block if there is such<br>
-1 branch from cold bock to header if there is one<br>
<br>
So if C is not a predecessor of H then we introduce extra branch.<br>
<br>
This change actually prohibits rotation of the loop if both true<br>
1) Best Exit has next element in chain as successor.<br>
2) Last element in chain is not a predecessor of first element of chain.<br>
<br>
Reviewers: iteratee, xur<br>
Reviewed By: iteratee<br>
Subscribers: llvm-commits<br>
Differential Revision: <a href="https://reviews.llvm.org/D34271" target="_blank">
https://reviews.llvm.org/D34271</a><br>
<br>
Modified:<br>
    llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp<br>
    llvm/trunk/test/CodeGen/X86/block-placement.ll<br>
    llvm/trunk/test/CodeGen/X86/code_placement_cold_loop_blocks.ll<br>
<br>
Modified: llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp?rev=306272&r1=306271&r2=306272&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp?rev=306272&r1=306271&r2=306272&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp Sun Jun 25 22:27:27 2017<br>
@@ -1944,6 +1944,35 @@ void MachineBlockPlacement::rotateLoop(B<br>
   if (ExitIt == LoopChain.end())<br>
     return;<br>
<br>
+  // Rotating a loop exit to the bottom when there is a fallthrough to top<br>
+  // trades the entry fallthrough for an exit fallthrough.<br>
+  // If there is no bottom->top edge, but the chosen exit block does have<br>
+  // a fallthrough, we break that fallthrough for nothing in return.<br>
+<br>
+  // Let's consider an example. We have a built chain of basic blocks<br>
+  // B1, B2, ..., Bn, where Bk is a ExitingBB - chosen exit block.<br>
+  // By doing a rotation we get<br>
+  // Bk+1, ..., Bn, B1, ..., Bk<br>
+  // Break of fallthrough to B1 is compensated by a fallthrough from Bk.<br>
+  // If we had a fallthrough Bk -> Bk+1 it is broken now.<br>
+  // It might be compensated by fallthrough Bn -> B1.<br>
+  // So we have a condition to avoid creation of extra branch by loop rotation.<br>
+  // All below must be true to avoid loop rotation:<br>
+  //   If there is a fallthrough to top (B1)<br>
+  //   There was fallthrough from chosen exit block (Bk) to next one (Bk+1)<br>
+  //   There is no fallthrough from bottom (Bn) to top (B1).<br>
+  // Please note that there is no exit fallthrough from Bn because we checked it<br>
+  // above.<br>
+  if (ViableTopFallthrough) {<br>
+    MachineBasicBlock *NextBlockInChain = *std::next(ExitIt);<br>
+    MachineBasicBlock *Bottom = *std::prev(LoopChain.end());<br>
+    if (NextBlockInChain->isPredecessor(ExitingBB))<br>
+      if (!Top->isPredecessor(Bottom))<br>
+        return;<br>
+  }<br>
+<br>
+  DEBUG(dbgs() << "Rotating loop to put exit " << getBlockName(ExitingBB)<br>
+               << " at bottom\n");<br>
   std::rotate(LoopChain.begin(), std::next(ExitIt), LoopChain.end());<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/block-placement.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/block-placement.ll?rev=306272&r1=306271&r2=306272&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/block-placement.ll?rev=306272&r1=306271&r2=306272&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/block-placement.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/block-placement.ll Sun Jun 25 22:27:27 2017<br>
@@ -354,6 +354,7 @@ define void @unnatural_cfg2() {<br>
 ; single-source GCC.<br>
 ; CHECK-LABEL: unnatural_cfg2<br>
 ; CHECK: %entry<br>
+; CHECK: %loop.header<br>
 ; CHECK: %loop.body1<br>
 ; CHECK: %loop.body2<br>
 ; CHECK: %loop.body4<br>
@@ -361,7 +362,6 @@ define void @unnatural_cfg2() {<br>
 ; CHECK: %loop.inner2.begin<br>
 ; CHECK: %loop.body3<br>
 ; CHECK: %loop.inner1.begin<br>
-; CHECK: %loop.header<br>
 ; CHECK: %bail<br>
<br>
 entry:<br>
@@ -1491,6 +1491,54 @@ ret:<br>
   ret void<br>
 }<br>
<br>
+define i32 @not_rotate_if_extra_branch(i32 %count) {<br>
+; Test checks that there is no loop rotation<br>
+; if it introduces extra branch.<br>
+; Specifically in this case because best exit is .header<br>
+; but it has fallthrough to .middle block and last block in<br>
+; loop chain .slow does not have afallthrough to .header.<br>
+; CHECK-LABEL: not_rotate_if_extra_branch<br>
+; CHECK: %.entry<br>
+; CHECK: %.header<br>
+; CHECK: %.middle<br>
+; CHECK: %.backedge<br>
+; CHECK: %.slow<br>
+; CHECK: %.bailout<br>
+; CHECK: %.stop<br>
+.entry:<br>
+  %sum.0 = shl nsw i32 %count, 1<br>
+  br label %.header<br>
+<br>
+.header:<br>
+  %i = phi i32 [ %i.1, %.backedge ], [ 0, %.entry ]<br>
+  %sum = phi i32 [ %sum.1, %.backedge ], [ %sum.0, %.entry ]<br>
+  %is_exc = icmp sgt i32 %i, 9000000<br>
+  br i1 %is_exc, label %.bailout, label %.middle, !prof !13<br>
+<br>
+.bailout:<br>
+  %sum.2 = add nsw i32 %count, 1<br>
+  br label %.stop<br>
+<br>
+.middle:<br>
+  %pr.1 = and i32 %i, 1023<br>
+  %pr.2 = icmp eq i32 %pr.1, 0<br>
+  br i1 %pr.2, label %.slow, label %.backedge, !prof !14<br>
+<br>
+.slow:<br>
+  tail call void @effect(i32 %sum)<br>
+  br label %.backedge<br>
+<br>
+.backedge:<br>
+  %sum.1 = add nsw i32 %i, %sum<br>
+  %i.1 = add nsw i32 %i, 1<br>
+  %end = icmp slt i32 %i.1, %count<br>
+  br i1 %end, label %.header, label %.stop, !prof !15<br>
+<br>
+.stop:<br>
+  %sum.phi = phi i32 [ %sum.1, %.backedge ], [ %sum.2, %.bailout ]<br>
+  ret i32 %sum.phi<br>
+}<br>
+<br>
 declare void @effect(i32)<br>
<br>
 !5 = !{!"branch_weights", i32 84, i32 16}<br>
@@ -1501,3 +1549,6 @@ declare void @effect(i32)<br>
 !10 = !{!"branch_weights", i32 90, i32 10}<br>
 !11 = !{!"branch_weights", i32 1, i32 1}<br>
 !12 = !{!"branch_weights", i32 5, i32 3}<br>
+!13 = !{!"branch_weights", i32 1, i32 1}<br>
+!14 = !{!"branch_weights", i32 1, i32 1023}<br>
+!15 = !{!"branch_weights", i32 4095, i32 1}<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/code_placement_cold_loop_blocks.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/code_placement_cold_loop_blocks.ll?rev=306272&r1=306271&r2=306272&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/code_placement_cold_loop_blocks.ll?rev=306272&r1=306271&r2=306272&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/code_placement_cold_loop_blocks.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/code_placement_cold_loop_blocks.ll Sun Jun 25 22:27:27 2017<br>
@@ -37,7 +37,7 @@ end:<br>
   ret void<br>
 }<br>
<br>
-define void @nested_loop_0() !prof !1 {<br>
+define void @nested_loop_0(i1 %flag) !prof !1 {<br>
 ; Test if a block that is cold in the inner loop but not cold in the outer loop<br>
 ; will merged to the outer loop chain.<br>
 ;<br>
@@ -68,8 +68,7 @@ if.then:<br>
<br>
 if.else:<br>
   call void @e()<br>
-  %call2 = call zeroext i1 @a()<br>
-  br i1 %call2, label %header2, label %header, !prof !3<br>
+  br i1 %flag, label %header2, label %header, !prof !3<br>
<br>
 end:<br>
   call void @f()<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</div>
</body>
</html>