<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>I second Max's request that the pass be disabled while you work
through reported miscompiles. <br>
</p>
<p>Philip<br>
</p>
<div class="moz-cite-prefix">On 11/15/18 9:40 PM, Maxim Kazantsev
via llvm-commits wrote:<br>
</div>
<blockquote type="cite"
cite="mid:58ba6095f6ab4c99af4d789cda2676d1@azul.com">
<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:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@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:0cm;
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;}
p.msonormal0, li.msonormal0, div.msonormal0
{mso-style-name:msonormal;
mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle18
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:2.0cm 42.5pt 2.0cm 3.0cm;}
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="mso-fareast-language:EN-US"
lang="EN-US">Hi again,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"
lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"
lang="EN-US">Your fix is not helping the miscompile, I tried
to explain why in the patch’s review. It also worries me
that I have other tests with miscompiles because of this
pass, and I am not sure whether or not it is the same bug.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"
lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"
lang="EN-US">I’d suggest you to disable the pass first, and
then we could work together on its re-enabling.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"
lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"
lang="EN-US">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"
lang="EN-US">Max<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"
lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US">From:</span></b><span
lang="EN-US"> Rong Xu <a class="moz-txt-link-rfc2396E" href="mailto:xur@google.com"><xur@google.com></a>
<br>
<b>Sent:</b> Friday, November 16, 2018 12:22 AM<br>
<b>To:</b> Maxim Kazantsev <a class="moz-txt-link-rfc2396E" href="mailto:max.kazantsev@azul.com"><max.kazantsev@azul.com></a><br>
<b>Cc:</b> llvm-commits <a class="moz-txt-link-rfc2396E" href="mailto:llvm-commits@lists.llvm.org"><llvm-commits@lists.llvm.org></a><br>
<b>Subject:</b> Re: [llvm] r344085 - Recommit r343993: [X86]
condition branches folding for three-way conditional codes<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">Thanks for the analysis. I agree the Phi
update is problematic. I will have a fix shortly.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">-Rong<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Thu, Nov 15, 2018 at 3:58 AM Maxim
Kazantsev <<a href="mailto:max.kazantsev@azul.com"
moz-do-not-send="true">max.kazantsev@azul.com</a>>
wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC
1.0pt;padding:0cm 0cm 0cm
6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">Looks like the bug was not in what I
described (the jumps after transform are OK), but
the problem is with Phi update, see
<a
href="https://bugs.llvm.org/show_bug.cgi?id=39658#c11"
target="_blank" moz-do-not-send="true">https://bugs.llvm.org/show_bug.cgi?id=39658#c11</a></span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1
1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span
lang="EN-US">From:</span></b><span
lang="EN-US"> Maxim Kazantsev
<br>
<b>Sent:</b> Thursday, November 15, 2018 6:46 PM<br>
<b>To:</b> 'Rong Xu' <<a
href="mailto:xur@google.com" target="_blank"
moz-do-not-send="true">xur@google.com</a>><br>
<b>Cc:</b> '<a
href="mailto:llvm-commits@lists.llvm.org"
target="_blank" moz-do-not-send="true">llvm-commits@lists.llvm.org</a>'
<<a href="mailto:llvm-commits@lists.llvm.org"
target="_blank" moz-do-not-send="true">llvm-commits@lists.llvm.org</a>><br>
<b>Subject:</b> RE: [llvm] r344085 - Recommit
r343993: [X86] condition branches folding for
three-way conditional codes</span><o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">Sorry for confusing, it’s not a bug
here; I’ve misread the code in the first block.
</span><span style="font-family:Wingdings"
lang="EN-US">L</span><span lang="EN-US"> I don’t see
what is wrong.</span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1
1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span
lang="EN-US">From:</span></b><span
lang="EN-US"> Maxim Kazantsev
<br>
<b>Sent:</b> Thursday, November 15, 2018 6:41 PM<br>
<b>To:</b> 'Rong Xu' <<a
href="mailto:xur@google.com" target="_blank"
moz-do-not-send="true">xur@google.com</a>><br>
<b>Cc:</b> '<a
href="mailto:llvm-commits@lists.llvm.org"
target="_blank" moz-do-not-send="true">llvm-commits@lists.llvm.org</a>'
<<a href="mailto:llvm-commits@lists.llvm.org"
target="_blank" moz-do-not-send="true">llvm-commits@lists.llvm.org</a>><br>
<b>Subject:</b> RE: [llvm] r344085 - Recommit
r343993: [X86] condition branches folding for
three-way conditional codes</span><o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">I also made some research and I think
I’ve found the exact place of miscompile, please see
<a
href="https://bugs.llvm.org/show_bug.cgi?id=39658#c8"
target="_blank" moz-do-not-send="true">https://bugs.llvm.org/show_bug.cgi?id=39658#c8</a>.
</span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">If you agree that it’s a bug, please
disable the pass by default and re-enable it after
it is fixed.</span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">Thanks,</span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">Max</span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1
1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span
lang="EN-US">From:</span></b><span
lang="EN-US"> Maxim Kazantsev
<br>
<b>Sent:</b> Thursday, November 15, 2018 11:50
AM<br>
<b>To:</b> 'Rong Xu' <<a
href="mailto:xur@google.com" target="_blank"
moz-do-not-send="true">xur@google.com</a>><br>
<b>Cc:</b> '<a
href="mailto:llvm-commits@lists.llvm.org"
target="_blank" moz-do-not-send="true">llvm-commits@lists.llvm.org</a>'
<<a href="mailto:llvm-commits@lists.llvm.org"
target="_blank" moz-do-not-send="true">llvm-commits@lists.llvm.org</a>><br>
<b>Subject:</b> RE: [llvm] r344085 - Recommit
r343993: [X86] condition branches folding for
three-way conditional codes</span><o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">I have a Java test that runs on our
Zing VM that uses LLVM as compiler backend, and this
Java program produces incorrect results when the
pass is on. The results are OK when the pass is
disabled. There was only one application of this
optimization on the IR I’ve provided. I’ve reduced
it slightly, but maybe I’ve lost the bad transform
during reduction. I’ll give you the full original IR
on which it happens.</span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">I’ll update the bug with this
attachment.</span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span
lang="EN-US">From:</span></b><span lang="EN-US">
Rong Xu <<a href="mailto:xur@google.com"
target="_blank" moz-do-not-send="true">xur@google.com</a>>
<br>
<b>Sent:</b> Thursday, November 15, 2018 5:52 AM<br>
<b>To:</b> Maxim Kazantsev <<a
href="mailto:max.kazantsev@azul.com"
target="_blank" moz-do-not-send="true">max.kazantsev@azul.com</a>><br>
<b>Subject:</b> Re: [llvm] r344085 - Recommit
r343993: [X86] condition branches folding for
three-way conditional codes</span><o:p></o:p></p>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">What was the error? Wrong result or
set fault?</span><o:p></o:p></p>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">This pass removed 7 BBs for this
function. I checked all of them. They seem to be
good to me.</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">Can you give me a reproducer of the
error?</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">Thanks,</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">-Rong</span><o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">On Wed, Nov 14, 2018 at 10:15 AM
Rong Xu <</span><a
href="mailto:xur@google.com" target="_blank"
moz-do-not-send="true"><span lang="EN-US">xur@google.com</span></a><span
lang="EN-US">> wrote:</span><o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid
#CCCCCC 1.0pt;padding:0cm 0cm 0cm
6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt">
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">Thanks for the information. I'm
looking into this.</span><o:p></o:p></p>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">-Rong</span><o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US"> </span><o:p></o:p></p>
<div>
<div>
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">On Tue, Nov 13, 2018 at 10:12
PM Maxim Kazantsev <</span><a
href="mailto:max.kazantsev@azul.com"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">max.kazantsev@azul.com</span></a><span
lang="EN-US">> wrote:</span><o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid
#CCCCCC 1.0pt;padding:0cm 0cm 0cm
6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt">
<p class="MsoNormal"
style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
lang="EN-US">Hello Rong,<br>
<br>
It seems that this patch contains a bug that
causes a miscompile on our test. I have
filed a bug
</span><a
href="https://bugs.llvm.org/show_bug.cgi?id=39658"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">https://bugs.llvm.org/show_bug.cgi?id=39658</span></a><span
lang="EN-US"> with description of the
failure. We know for sure that disabling of
this pass makes the failure gone, but I
wasn't able to figure out what exactly is
wrong about the transforms it does.<br>
<br>
You can find the IR on which we see the
transform triggering and the machine
function before and after this particular
transform in bug attachment.<br>
<br>
Please take a look at this bug and fix or
disable this transform until we can figure
out the fix. I'll gladly provide you any
extra information you need.<br>
<br>
Thanks,<br>
Max<br>
<br>
-----Original Message-----<br>
From: llvm-commits <</span><a
href="mailto:llvm-commits-bounces@lists.llvm.org"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">llvm-commits-bounces@lists.llvm.org</span></a><span
lang="EN-US">> On Behalf Of Rong Xu via
llvm-commits<br>
Sent: Wednesday, October 10, 2018 5:04 AM<br>
To: </span><a
href="mailto:llvm-commits@lists.llvm.org"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">llvm-commits@lists.llvm.org</span></a><span
lang="EN-US"><br>
Subject: [llvm] r344085 - Recommit r343993:
[X86] condition branches folding for
three-way conditional codes<br>
<br>
Author: xur<br>
Date: Tue Oct 9 15:03:40 2018<br>
New Revision: 344085<br>
<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project?rev=344085&view=rev"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project?rev=344085&view=rev</span></a><span
lang="EN-US"><br>
Log:<br>
Recommit r343993: [X86] condition branches
folding for three-way conditional codes<br>
<br>
Fix the memory issue exposed by sanitizer.<br>
<br>
Added:<br>
llvm/trunk/lib/Target/X86/X86CondBrFolding.cpp<br>
llvm/trunk/test/CodeGen/X86/condbr_if.ll<br>
llvm/trunk/test/CodeGen/X86/condbr_switch.ll<br>
Modified:<br>
llvm/trunk/lib/Target/X86/CMakeLists.txt<br>
llvm/trunk/lib/Target/X86/X86.h<br>
llvm/trunk/lib/Target/X86/X86.td<br>
llvm/trunk/lib/Target/X86/X86Subtarget.h<br>
llvm/trunk/lib/Target/X86/X86TargetMachine.cpp<br>
llvm/trunk/test/CodeGen/X86/O3-pipeline.ll<br>
<br>
Modified:
llvm/trunk/lib/Target/X86/CMakeLists.txt<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/CMakeLists.txt?rev=344085&r1=344084&r2=344085&view=diff"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/CMakeLists.txt?rev=344085&r1=344084&r2=344085&view=diff</span></a><span
lang="EN-US"><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/CMakeLists.txt
(original)<br>
+++ llvm/trunk/lib/Target/X86/CMakeLists.txt
Tue Oct 9 15:03:40 2018<br>
@@ -27,6 +27,7 @@ set(sources<br>
X86CallingConv.cpp<br>
X86CallLowering.cpp<br>
X86CmovConversion.cpp<br>
+ X86CondBrFolding.cpp<br>
X86DomainReassignment.cpp<br>
X86ExpandPseudo.cpp<br>
X86FastISel.cpp<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86.h<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.h?rev=344085&r1=344084&r2=344085&view=diff"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.h?rev=344085&r1=344084&r2=344085&view=diff</span></a><span
lang="EN-US"><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86.h
(original)<br>
+++ llvm/trunk/lib/Target/X86/X86.h Tue Oct
9 15:03:40 2018<br>
@@ -75,6 +75,9 @@ FunctionPass
*createX86OptimizeLEAs(); /// Return a pass
that transforms setcc + movzx pairs into xor
+ setcc.<br>
FunctionPass *createX86FixupSetCC();<br>
<br>
+/// Return a pass that folds conditional
branch jumps.<br>
+FunctionPass *createX86CondBrFolding();<br>
+<br>
/// Return a pass that avoids creating
store forward block issues in the hardware.<br>
FunctionPass
*createX86AvoidStoreForwardingBlocks();<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86.td<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=344085&r1=344084&r2=344085&view=diff"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=344085&r1=344084&r2=344085&view=diff</span></a><span
lang="EN-US"><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86.td
(original)<br>
+++ llvm/trunk/lib/Target/X86/X86.td Tue
Oct 9 15:03:40 2018<br>
@@ -404,6 +404,12 @@ def FeatureFastBEXTR :
SubtargetFeature<<br>
"Indicates that the BEXTR
instruction is implemented as a single uop "<br>
"with good throughput.">;<br>
<br>
+// Merge branches using three-way
conditional code.<br>
+def FeatureMergeToThreeWayBranch :
SubtargetFeature<"merge-to-threeway-branch",<br>
+
"ThreewayBranchProfitable", "true",<br>
+
"Merge branches to a three-way "<br>
+
"conditional branch">;<br>
+<br>
//===----------------------------------------------------------------------===//<br>
// Register File Description<br>
//===----------------------------------------------------------------------===//<br>
@@ -732,6 +738,7 @@ def SNBFeatures :
ProcessorFeatures<[],<br>
FeatureFastScalarFSQRT,<br>
FeatureFastSHLDRotate,<br>
FeatureSlowIncDec,<br>
+ FeatureMergeToThreeWayBranch,<br>
FeatureMacroFusion<br>
]>;<br>
<br>
<br>
Added:
llvm/trunk/lib/Target/X86/X86CondBrFolding.cpp<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CondBrFolding.cpp?rev=344085&view=auto"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CondBrFolding.cpp?rev=344085&view=auto</span></a><span
lang="EN-US"><br>
==============================================================================<br>
---
llvm/trunk/lib/Target/X86/X86CondBrFolding.cpp
(added)<br>
+++
llvm/trunk/lib/Target/X86/X86CondBrFolding.cpp
Tue Oct 9 15:03:40 <br>
+++ 2018<br>
@@ -0,0 +1,579 @@<br>
+//===---- X86CondBrFolding.cpp - optimize
conditional branches <br>
+------------===// //<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is distributed under the
University of Illinois Open <br>
+Source // License. See LICENSE.TXT for
details.<br>
+//<br>
+//===------------------------------------------------------------------<br>
+----===// // This file defines a pass that
optimizes condition branches <br>
+on x86 by taking // advantage of the
three-way conditional code <br>
+generated by compare // instructions.<br>
+// Currently, it tries to hoisting EQ and
NE conditional branch to a <br>
+dominant // conditional branch condition
where the same EQ/NE <br>
+conditional code is // computed. An
example:<br>
+// bb_0:<br>
+// cmp %0, 19<br>
+// jg bb_1<br>
+// jmp bb_2<br>
+// bb_1:<br>
+// cmp %0, 40<br>
+// jg bb_3<br>
+// jmp bb_4<br>
+// bb_4:<br>
+// cmp %0, 20<br>
+// je bb_5<br>
+// jmp bb_6<br>
+// Here we could combine the two compares
in bb_0 and bb_4 and have the <br>
+// following code:<br>
+// bb_0:<br>
+// cmp %0, 20<br>
+// jg bb_1<br>
+// jl bb_2<br>
+// jmp bb_5<br>
+// bb_1:<br>
+// cmp %0, 40<br>
+// jg bb_3<br>
+// jmp bb_6<br>
+// For the case of %0 == 20 (bb_5), we
eliminate two jumps, and the <br>
+control // height for bb_6 is also reduced.
bb_4 is gone after the optimization.<br>
+//<br>
+// There are plenty of this code patterns,
especially from the switch <br>
+case // lowing where we generate compare of
"pivot-1" for the inner <br>
+nodes in the // binary search tree.<br>
+//===------------------------------------------------------------------<br>
+----===//<br>
+<br>
+#include "X86.h"<br>
+#include "X86InstrInfo.h"<br>
+#include "X86Subtarget.h"<br>
+#include "llvm/ADT/Statistic.h"<br>
+#include
"llvm/CodeGen/MachineBranchProbabilityInfo.h"<br>
+#include
"llvm/CodeGen/MachineFunctionPass.h"<br>
+#include
"llvm/CodeGen/MachineInstrBuilder.h"<br>
+#include
"llvm/CodeGen/MachineRegisterInfo.h"<br>
+#include "llvm/Support/BranchProbability.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+#define DEBUG_TYPE "x86-condbr-folding"<br>
+<br>
+STATISTIC(NumFixedCondBrs, "Number of x86
condbr folded");<br>
+<br>
+namespace {<br>
+class X86CondBrFoldingPass : public
MachineFunctionPass {<br>
+public:<br>
+ X86CondBrFoldingPass() :
MachineFunctionPass(ID) {}<br>
+<br>
+ StringRef getPassName() const override {
return "X86 CondBr Folding"; <br>
+ }<br>
+<br>
+ bool runOnMachineFunction(MachineFunction
&MF) override;<br>
+<br>
+ void getAnalysisUsage(AnalysisUsage
&AU) const override {<br>
+
MachineFunctionPass::getAnalysisUsage(AU);<br>
+
AU.addRequired<MachineBranchProbabilityInfo>();<br>
+ }<br>
+<br>
+private:<br>
+ static char ID;<br>
+};<br>
+<br>
+char X86CondBrFoldingPass::ID = 0;<br>
+} // namespace<br>
+<br>
+FunctionPass
*llvm::createX86CondBrFolding() {<br>
+ return new X86CondBrFoldingPass();<br>
+}<br>
+<br>
+// A class the stores the auxiliary
information for each MBB.<br>
+struct TargetMBBInfo {<br>
+ MachineBasicBlock *TBB;<br>
+ MachineBasicBlock *FBB;<br>
+ MachineInstr *BrInstr;<br>
+ MachineInstr *CmpInstr;<br>
+ X86::CondCode BranchCode;<br>
+ unsigned SrcReg;<br>
+ int CmpValue;<br>
+ bool Modified;<br>
+ bool CmpBrOnly;<br>
+};<br>
+<br>
+// A class that optimizes the conditional
branch by hoisting and merge CondCode.<br>
+class X86CondBrFolding {<br>
+public:<br>
+ X86CondBrFolding(const X86InstrInfo *TII,<br>
+ const
MachineBranchProbabilityInfo *MBPI,<br>
+ MachineFunction &MF)<br>
+ : TII(TII), MBPI(MBPI), MF(MF) {}<br>
+ bool optimize();<br>
+<br>
+private:<br>
+ const X86InstrInfo *TII;<br>
+ const MachineBranchProbabilityInfo *MBPI;<br>
+ MachineFunction &MF;<br>
+
std::vector<std::unique_ptr<TargetMBBInfo>>
MBBInfos;<br>
+ SmallVector<MachineBasicBlock *, 4>
RemoveList;<br>
+<br>
+ void optimizeCondBr(MachineBasicBlock
&MBB,<br>
+
SmallVectorImpl<MachineBasicBlock *> <br>
+&BranchPath);<br>
+ void fixBranchProb(MachineBasicBlock
*NextMBB, MachineBasicBlock *RootMBB,<br>
+
SmallVectorImpl<MachineBasicBlock *>
&BranchPath);<br>
+ void replaceBrDest(MachineBasicBlock
*MBB, MachineBasicBlock *OrigDest,<br>
+ MachineBasicBlock
*NewDest);<br>
+ void fixupModifiedCond(MachineBasicBlock
*MBB);<br>
+ std::unique_ptr<TargetMBBInfo>
analyzeMBB(MachineBasicBlock &MBB);<br>
+ static bool analyzeCompare(const
MachineInstr &MI, unsigned &SrcReg,<br>
+ int
&CmpValue);<br>
+ bool findPath(MachineBasicBlock *MBB,<br>
+
SmallVectorImpl<MachineBasicBlock *>
&BranchPath);<br>
+ TargetMBBInfo
*getMBBInfo(MachineBasicBlock *MBB) const {<br>
+ return
MBBInfos[MBB->getNumber()].get();<br>
+ }<br>
+};<br>
+<br>
+// Find a valid path that we can reuse the
CondCode.<br>
+// The resulted path (if return true) is
stored in BranchPath.<br>
+// Return value:<br>
+// false: is no valid path is found.<br>
+// true: a valid path is found and the
targetBB can be reached.<br>
+bool X86CondBrFolding::findPath(<br>
+ MachineBasicBlock *MBB,
SmallVectorImpl<MachineBasicBlock *> <br>
+&BranchPath) {<br>
+ TargetMBBInfo *MBBInfo = getMBBInfo(MBB);<br>
+ assert(MBBInfo && "Expecting a
candidate MBB");<br>
+ int CmpValue = MBBInfo->CmpValue;<br>
+<br>
+ MachineBasicBlock *PredMBB =
*MBB->pred_begin(); MachineBasicBlock <br>
+ *SaveMBB = MBB; while (PredMBB) {<br>
+ TargetMBBInfo *PredMBBInfo =
getMBBInfo(PredMBB);<br>
+ if (!PredMBBInfo ||
PredMBBInfo->SrcReg !=
MBBInfo->SrcReg)<br>
+ return false;<br>
+<br>
+ assert(SaveMBB == PredMBBInfo->TBB
|| SaveMBB == PredMBBInfo->FBB);<br>
+ bool IsFalseBranch = (SaveMBB ==
PredMBBInfo->FBB);<br>
+<br>
+ X86::CondCode CC =
PredMBBInfo->BranchCode;<br>
+ assert(CC == X86::COND_L || CC ==
X86::COND_G || CC == X86::COND_E);<br>
+ int PredCmpValue =
PredMBBInfo->CmpValue;<br>
+ bool ValueCmpTrue = ((CmpValue <
PredCmpValue && CC == X86::COND_L)
||<br>
+ (CmpValue >
PredCmpValue && CC == X86::COND_G)
||<br>
+ (CmpValue ==
PredCmpValue && CC == X86::COND_E));<br>
+ // Check if both the result of value
compare and the branch target match.<br>
+ if (!(ValueCmpTrue ^ IsFalseBranch)) {<br>
+ LLVM_DEBUG(dbgs() << "Dead BB
detected!\n");<br>
+ return false;<br>
+ }<br>
+<br>
+ BranchPath.push_back(PredMBB);<br>
+ // These are the conditions on which we
could combine the compares.<br>
+ if ((CmpValue == PredCmpValue) ||<br>
+ (CmpValue == PredCmpValue - 1
&& CC == X86::COND_L) ||<br>
+ (CmpValue == PredCmpValue + 1
&& CC == X86::COND_G))<br>
+ return true;<br>
+<br>
+ // If PredMBB has more than on preds,
or not a pure cmp and br, we bailout.<br>
+ if (PredMBB->pred_size() != 1 ||
!PredMBBInfo->CmpBrOnly)<br>
+ return false;<br>
+<br>
+ SaveMBB = PredMBB;<br>
+ PredMBB = *PredMBB->pred_begin();<br>
+ }<br>
+ return false;<br>
+}<br>
+<br>
+// Fix up any PHI node in the successor of
MBB.<br>
+static void fixPHIsInSucc(MachineBasicBlock
*MBB, MachineBasicBlock *OldMBB,<br>
+ MachineBasicBlock
*NewMBB) {<br>
+ if (NewMBB == OldMBB)<br>
+ return;<br>
+ for (auto MI = MBB->instr_begin(), ME
= MBB->instr_end();<br>
+ MI != ME && MI->isPHI();
++MI)<br>
+ for (unsigned i = 2, e =
MI->getNumOperands() + 1; i != e; i += 2)
{<br>
+ MachineOperand &MO =
MI->getOperand(i);<br>
+ if (MO.getMBB() == OldMBB)<br>
+ MO.setMBB(NewMBB);<br>
+ }<br>
+}<br>
+<br>
+// Utility function to set branch
probability for edge MBB->SuccMBB.<br>
+static inline bool
setBranchProb(MachineBasicBlock *MBB,<br>
+
MachineBasicBlock *SuccMBB,<br>
+
BranchProbability Prob) {<br>
+ auto MBBI =
std::find(MBB->succ_begin(),
MBB->succ_end(), SuccMBB);<br>
+ if (MBBI == MBB->succ_end())<br>
+ return false;<br>
+ MBB->setSuccProbability(MBBI, Prob);<br>
+ return true;<br>
+}<br>
+<br>
+// Utility function to find the
unconditional br instruction in MBB.<br>
+static inline MachineBasicBlock::iterator <br>
+findUncondBrI(MachineBasicBlock *MBB) {<br>
+ return std::find_if(MBB->begin(),
MBB->end(), [](MachineInstr &MI)
-> bool {<br>
+ return MI.getOpcode() == X86::JMP_1;<br>
+ });<br>
+}<br>
+<br>
+// Replace MBB's original successor,
OrigDest, with NewDest.<br>
+// Also update the MBBInfo for MBB.<br>
+void
X86CondBrFolding::replaceBrDest(MachineBasicBlock
*MBB,<br>
+
MachineBasicBlock *OrigDest,<br>
+
MachineBasicBlock *NewDest) {<br>
+ TargetMBBInfo *MBBInfo = getMBBInfo(MBB);<br>
+ MachineInstr *BrMI;<br>
+ if (MBBInfo->TBB == OrigDest) {<br>
+ BrMI = MBBInfo->BrInstr;<br>
+ unsigned JNCC =
GetCondBranchFromCond(MBBInfo->BranchCode);<br>
+ MachineInstrBuilder MIB =<br>
+ BuildMI(*MBB, BrMI,
MBB->findDebugLoc(BrMI),
TII->get(JNCC))<br>
+ .addMBB(NewDest);<br>
+ MBBInfo->TBB = NewDest;<br>
+ MBBInfo->BrInstr = MIB.getInstr();<br>
+ } else { // Should be the unconditional
jump stmt.<br>
+ MachineBasicBlock::iterator UncondBrI =
findUncondBrI(MBB);<br>
+ BuildMI(*MBB, UncondBrI,
MBB->findDebugLoc(UncondBrI),
TII->get(X86::JMP_1))<br>
+ .addMBB(NewDest);<br>
+ MBBInfo->FBB = NewDest;<br>
+ BrMI = &*UncondBrI;<br>
+ }<br>
+ fixPHIsInSucc(NewDest, OrigDest, MBB);<br>
+ BrMI->eraseFromParent();<br>
+ MBB->addSuccessor(NewDest);<br>
+ setBranchProb(MBB, NewDest,
MBPI->getEdgeProbability(MBB, OrigDest));<br>
+ MBB->removeSuccessor(OrigDest);<br>
+}<br>
+<br>
+// Change the CondCode and BrInstr
according to MBBInfo.<br>
+void
X86CondBrFolding::fixupModifiedCond(MachineBasicBlock
*MBB) {<br>
+ TargetMBBInfo *MBBInfo = getMBBInfo(MBB);<br>
+ if (!MBBInfo->Modified)<br>
+ return;<br>
+<br>
+ MachineInstr *BrMI =
MBBInfo->BrInstr; X86::CondCode CC = <br>
+ MBBInfo->BranchCode;
MachineInstrBuilder MIB = BuildMI(*MBB,
BrMI, <br>
+ MBB->findDebugLoc(BrMI),<br>
+
TII->get(GetCondBranchFromCond(CC)))<br>
+
.addMBB(MBBInfo->TBB); <br>
+ BrMI->eraseFromParent();
MBBInfo->BrInstr = MIB.getInstr();<br>
+<br>
+ MachineBasicBlock::iterator UncondBrI =
findUncondBrI(MBB);<br>
+ BuildMI(*MBB, UncondBrI,
MBB->findDebugLoc(UncondBrI),
TII->get(X86::JMP_1))<br>
+ .addMBB(MBBInfo->FBB);<br>
+ MBB->erase(UncondBrI);<br>
+ MBBInfo->Modified = false;<br>
+}<br>
+<br>
+//<br>
+// Apply the transformation:<br>
+// RootMBB -1-> ... PredMBB -3-> MBB
-5-> TargetMBB<br>
+// \-2-> \-4->
\-6-> FalseMBB<br>
+// ==><br>
+// RootMBB -1-> ... PredMBB
-7-> FalseMBB<br>
+// TargetMBB <-8-/ \-2->
\-4-><br>
+//<br>
+// Note that PredMBB and RootMBB could be
the same.<br>
+// And in the case of dead TargetMBB, we
will not have TargetMBB and edge 8.<br>
+//<br>
+// There are some special handling where
the RootMBB is COND_E in which <br>
+case // we directly short-cycle the
brinstr.<br>
+//<br>
+void X86CondBrFolding::optimizeCondBr(<br>
+ MachineBasicBlock &MBB,
SmallVectorImpl<MachineBasicBlock *> <br>
+&BranchPath) {<br>
+<br>
+ X86::CondCode CC;<br>
+ TargetMBBInfo *MBBInfo =
getMBBInfo(&MBB); assert(MBBInfo
&& <br>
+ "Expecting a candidate MBB");
MachineBasicBlock *TargetMBB = <br>
+ MBBInfo->TBB; BranchProbability
TargetProb = <br>
+ MBPI->getEdgeProbability(&MBB,
MBBInfo->TBB);<br>
+<br>
+ // Forward the jump from MBB's
predecessor to MBB's false target.<br>
+ MachineBasicBlock *PredMBB =
BranchPath.front(); TargetMBBInfo <br>
+ *PredMBBInfo = getMBBInfo(PredMBB);
assert(PredMBBInfo && "Expecting <br>
+ a candidate MBB"); if
(PredMBBInfo->Modified)<br>
+ fixupModifiedCond(PredMBB);<br>
+ CC = PredMBBInfo->BranchCode;<br>
+ // Don't do this if depth of BranchPath
is 1 and PredMBB is of COND_E.<br>
+ // We will short-cycle directly for this
case.<br>
+ if (!(CC == X86::COND_E &&
BranchPath.size() == 1))<br>
+ replaceBrDest(PredMBB, &MBB,
MBBInfo->FBB);<br>
+<br>
+ MachineBasicBlock *RootMBB =
BranchPath.back(); TargetMBBInfo <br>
+ *RootMBBInfo = getMBBInfo(RootMBB);
assert(RootMBBInfo && "Expecting <br>
+ a candidate MBB"); if
(RootMBBInfo->Modified)<br>
+ fixupModifiedCond(RootMBB);<br>
+ CC = RootMBBInfo->BranchCode;<br>
+<br>
+ if (CC != X86::COND_E) {<br>
+ MachineBasicBlock::iterator UncondBrI =
findUncondBrI(RootMBB);<br>
+ // RootMBB: Cond jump to the original
not-taken MBB.<br>
+ X86::CondCode NewCC;<br>
+ switch (CC) {<br>
+ case X86::COND_L:<br>
+ NewCC = X86::COND_G;<br>
+ break;<br>
+ case X86::COND_G:<br>
+ NewCC = X86::COND_L;<br>
+ break;<br>
+ default:<br>
+ llvm_unreachable("unexpected
condtional code.");<br>
+ }<br>
+ BuildMI(*RootMBB, UncondBrI,
RootMBB->findDebugLoc(UncondBrI),<br>
+
TII->get(GetCondBranchFromCond(NewCC)))<br>
+ .addMBB(RootMBBInfo->FBB);<br>
+<br>
+ // RootMBB: Jump to TargetMBB<br>
+ BuildMI(*RootMBB, UncondBrI,
RootMBB->findDebugLoc(UncondBrI),<br>
+ TII->get(X86::JMP_1))<br>
+ .addMBB(TargetMBB);<br>
+ RootMBB->addSuccessor(TargetMBB);<br>
+ fixPHIsInSucc(TargetMBB, &MBB,
RootMBB);<br>
+ RootMBB->erase(UncondBrI);<br>
+ } else {<br>
+ replaceBrDest(RootMBB,
RootMBBInfo->TBB, TargetMBB); }<br>
+<br>
+ // Fix RootMBB's CmpValue to MBB's
CmpValue to TargetMBB. Don't set <br>
+ Imm // directly. Move MBB's stmt to here
as the opcode might be different.<br>
+ if (RootMBBInfo->CmpValue !=
MBBInfo->CmpValue) {<br>
+ MachineInstr *NewCmp =
MBBInfo->CmpInstr;<br>
+ NewCmp->removeFromParent();<br>
+
RootMBB->insert(RootMBBInfo->CmpInstr,
NewCmp);<br>
+
RootMBBInfo->CmpInstr->eraseFromParent();<br>
+ }<br>
+<br>
+ // Fix branch Probabilities.<br>
+ auto fixBranchProb =
[&](MachineBasicBlock *NextMBB) {<br>
+ BranchProbability Prob;<br>
+ for (auto &I : BranchPath) {<br>
+ MachineBasicBlock *ThisMBB = I;<br>
+ if
(!ThisMBB->hasSuccessorProbabilities() ||<br>
+
!ThisMBB->isSuccessor(NextMBB))<br>
+ break;<br>
+ Prob =
MBPI->getEdgeProbability(ThisMBB,
NextMBB);<br>
+ if (Prob.isUnknown())<br>
+ break;<br>
+ TargetProb = Prob * TargetProb;<br>
+ Prob = Prob - TargetProb;<br>
+ setBranchProb(ThisMBB, NextMBB,
Prob);<br>
+ if (ThisMBB == RootMBB) {<br>
+ setBranchProb(ThisMBB, TargetMBB,
TargetProb);<br>
+ }<br>
+ ThisMBB->normalizeSuccProbs();<br>
+ if (ThisMBB == RootMBB)<br>
+ break;<br>
+ NextMBB = ThisMBB;<br>
+ }<br>
+ return true;<br>
+ };<br>
+ if (CC != X86::COND_E &&
!TargetProb.isUnknown())<br>
+ fixBranchProb(MBBInfo->FBB);<br>
+<br>
+ if (CC != X86::COND_E)<br>
+ RemoveList.push_back(&MBB);<br>
+<br>
+ // Invalidate MBBInfo just in case.<br>
+ MBBInfos[MBB.getNumber()] = nullptr;<br>
+ MBBInfos[RootMBB->getNumber()] =
nullptr;<br>
+<br>
+ LLVM_DEBUG(dbgs() << "After
optimization:\nRootMBB is: " <<
*RootMBB <br>
+<< "\n");<br>
+ if (BranchPath.size() > 1)<br>
+ LLVM_DEBUG(dbgs() << "PredMBB is:
" << *(BranchPath[0]) << "\n");
}<br>
+<br>
+// Driver function for optimization: find
the valid candidate and apply <br>
+// the transformation.<br>
+bool X86CondBrFolding::optimize() {<br>
+ bool Changed = false;<br>
+ LLVM_DEBUG(dbgs() << "*****
X86CondBr Folding on Function: " <<
MF.getName()<br>
+ << " *****\n");<br>
+ // Setup data structures.<br>
+ MBBInfos.resize(MF.getNumBlockIDs());<br>
+ for (auto &MBB : MF)<br>
+ MBBInfos[MBB.getNumber()] =
analyzeMBB(MBB);<br>
+<br>
+ for (auto &MBB : MF) {<br>
+ TargetMBBInfo *MBBInfo =
getMBBInfo(&MBB);<br>
+ if (!MBBInfo || !MBBInfo->CmpBrOnly)<br>
+ continue;<br>
+ if (MBB.pred_size() != 1)<br>
+ continue;<br>
+ LLVM_DEBUG(dbgs() << "Work on
MBB." << MBB.getNumber()<br>
+ << " CmpValue:
" << MBBInfo->CmpValue <<
"\n");<br>
+ SmallVector<MachineBasicBlock *,
4> BranchPath;<br>
+ if (!findPath(&MBB, BranchPath))<br>
+ continue;<br>
+<br>
+#ifndef NDEBUG<br>
+ LLVM_DEBUG(dbgs() << "Found one
path (len=" << BranchPath.size()
<< "):\n");<br>
+ int Index = 1;<br>
+ LLVM_DEBUG(dbgs() << "Target MBB
is: " << MBB << "\n");<br>
+ for (auto I = BranchPath.rbegin(); I !=
BranchPath.rend(); ++I, ++Index) {<br>
+ MachineBasicBlock *PMBB = *I;<br>
+ TargetMBBInfo *PMBBInfo =
getMBBInfo(PMBB);<br>
+ LLVM_DEBUG(dbgs() << "Path MBB
(" << Index << " of " <<
BranchPath.size()<br>
+ << ") is "
<< *PMBB);<br>
+ LLVM_DEBUG(dbgs() << "CC="
<< PMBBInfo->BranchCode<br>
+ << " Val="
<< PMBBInfo->CmpValue<br>
+ << "
CmpBrOnly=" << PMBBInfo->CmpBrOnly
<< "\n\n");<br>
+ }<br>
+#endif<br>
+ optimizeCondBr(MBB, BranchPath);<br>
+ Changed = true;<br>
+ }<br>
+ NumFixedCondBrs += RemoveList.size();<br>
+ for (auto MBBI : RemoveList) {<br>
+ for (auto *Succ :
MBBI->successors())<br>
+ MBBI->removeSuccessor(Succ);<br>
+ MBBI->eraseFromParent();<br>
+ }<br>
+<br>
+ return Changed;<br>
+}<br>
+<br>
+// Analyze instructions that generate
CondCode and extract information.<br>
+bool X86CondBrFolding::analyzeCompare(const
MachineInstr &MI, unsigned &SrcReg,<br>
+ int
&CmpValue) {<br>
+ unsigned SrcRegIndex = 0;<br>
+ unsigned ValueIndex = 0;<br>
+ switch (MI.getOpcode()) {<br>
+ // TODO: handle test instructions.<br>
+ default:<br>
+ return false;<br>
+ case X86::CMP64ri32:<br>
+ case X86::CMP64ri8:<br>
+ case X86::CMP32ri:<br>
+ case X86::CMP32ri8:<br>
+ case X86::CMP16ri:<br>
+ case X86::CMP16ri8:<br>
+ case X86::CMP8ri:<br>
+ SrcRegIndex = 0;<br>
+ ValueIndex = 1;<br>
+ break;<br>
+ case X86::SUB64ri32:<br>
+ case X86::SUB64ri8:<br>
+ case X86::SUB32ri:<br>
+ case X86::SUB32ri8:<br>
+ case X86::SUB16ri:<br>
+ case X86::SUB16ri8:<br>
+ case X86::SUB8ri:<br>
+ SrcRegIndex = 1;<br>
+ ValueIndex = 2;<br>
+ break;<br>
+ }<br>
+ SrcReg =
MI.getOperand(SrcRegIndex).getReg();<br>
+ assert(MI.getOperand(ValueIndex).isImm()
&& "Expecting Imm operand");<br>
+ CmpValue =
MI.getOperand(ValueIndex).getImm();<br>
+ return true;<br>
+}<br>
+<br>
+// Analyze a candidate MBB and set the
extract all the information needed.<br>
+// The valid candidate will have two
successors.<br>
+// It also should have a sequence of<br>
+// Branch_instr,<br>
+// CondBr,<br>
+// UnCondBr.<br>
+// Return TargetMBBInfo if MBB is a valid
candidate and nullptr otherwise.<br>
+std::unique_ptr<TargetMBBInfo><br>
+X86CondBrFolding::analyzeMBB(MachineBasicBlock &MBB) {<br>
+ MachineBasicBlock *TBB;<br>
+ MachineBasicBlock *FBB;<br>
+ MachineInstr *BrInstr;<br>
+ MachineInstr *CmpInstr;<br>
+ X86::CondCode CC;<br>
+ unsigned SrcReg;<br>
+ int CmpValue;<br>
+ bool Modified;<br>
+ bool CmpBrOnly;<br>
+<br>
+ if (MBB.succ_size() != 2)<br>
+ return nullptr;<br>
+<br>
+ CmpBrOnly = true;<br>
+ FBB = TBB = nullptr;<br>
+ CmpInstr = nullptr;<br>
+ MachineBasicBlock::iterator I =
MBB.end(); while (I != MBB.begin()) <br>
+ {<br>
+ --I;<br>
+ if (I->isDebugValue())<br>
+ continue;<br>
+ if (I->getOpcode() == X86::JMP_1) {<br>
+ if (FBB)<br>
+ return nullptr;<br>
+ FBB = I->getOperand(0).getMBB();<br>
+ continue;<br>
+ }<br>
+ if (I->isBranch()) {<br>
+ if (TBB)<br>
+ return nullptr;<br>
+ CC =
X86::getCondFromBranchOpc(I->getOpcode());<br>
+ switch (CC) {<br>
+ default:<br>
+ return nullptr;<br>
+ case X86::COND_E:<br>
+ case X86::COND_L:<br>
+ case X86::COND_G:<br>
+ case X86::COND_NE:<br>
+ case X86::COND_LE:<br>
+ case X86::COND_GE:<br>
+ break;<br>
+ }<br>
+ TBB = I->getOperand(0).getMBB();<br>
+ BrInstr = &*I;<br>
+ continue;<br>
+ }<br>
+ if (analyzeCompare(*I, SrcReg,
CmpValue)) {<br>
+ if (CmpInstr)<br>
+ return nullptr;<br>
+ CmpInstr = &*I;<br>
+ continue;<br>
+ }<br>
+ CmpBrOnly = false;<br>
+ break;<br>
+ }<br>
+<br>
+ if (!TBB || !FBB || !CmpInstr)<br>
+ return nullptr;<br>
+<br>
+ // Simplify CondCode. Note this is only
to simplify the findPath <br>
+logic<br>
+ // and will not change the instruction
here.<br>
+ switch (CC) {<br>
+ case X86::COND_NE:<br>
+ CC = X86::COND_E;<br>
+ std::swap(TBB, FBB);<br>
+ Modified = true;<br>
+ break;<br>
+ case X86::COND_LE:<br>
+ if (CmpValue == INT_MAX)<br>
+ return nullptr;<br>
+ CC = X86::COND_L;<br>
+ CmpValue += 1;<br>
+ Modified = true;<br>
+ break;<br>
+ case X86::COND_GE:<br>
+ if (CmpValue == INT_MIN)<br>
+ return nullptr;<br>
+ CC = X86::COND_G;<br>
+ CmpValue -= 1;<br>
+ Modified = true;<br>
+ break;<br>
+ default:<br>
+ Modified = false;<br>
+ break;<br>
+ }<br>
+ return
llvm::make_unique<TargetMBBInfo>(TargetMBBInfo{<br>
+ TBB, FBB, BrInstr, CmpInstr, CC,
SrcReg, CmpValue, Modified, <br>
+CmpBrOnly}); }<br>
+<br>
+bool
X86CondBrFoldingPass::runOnMachineFunction(MachineFunction
&MF) {<br>
+ const X86Subtarget &ST =
MF.getSubtarget<X86Subtarget>();<br>
+ if (!ST.threewayBranchProfitable())<br>
+ return false;<br>
+ const X86InstrInfo *TII =
ST.getInstrInfo();<br>
+ const MachineBranchProbabilityInfo *MBPI
=<br>
+
&getAnalysis<MachineBranchProbabilityInfo>();<br>
+<br>
+ X86CondBrFolding CondBr(TII, MBPI, MF);<br>
+ return CondBr.optimize();<br>
+}<br>
<br>
Modified:
llvm/trunk/lib/Target/X86/X86Subtarget.h<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=344085&r1=344084&r2=344085&view=diff"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=344085&r1=344084&r2=344085&view=diff</span></a><span
lang="EN-US"><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86Subtarget.h
(original)<br>
+++ llvm/trunk/lib/Target/X86/X86Subtarget.h
Tue Oct 9 15:03:40 2018<br>
@@ -419,6 +419,9 @@ protected:<br>
/// Indicates target prefers 256 bit
instructions.<br>
bool Prefer256Bit = false;<br>
<br>
+ /// Threeway branch is profitable in this
subtarget.<br>
+ bool ThreewayBranchProfitable = false;<br>
+<br>
/// What processor and OS we're
targeting.<br>
Triple TargetTriple;<br>
<br>
@@ -662,6 +665,7 @@ public:<br>
bool hasWAITPKG() const { return
HasWAITPKG; }<br>
bool hasPCONFIG() const { return
HasPCONFIG; }<br>
bool hasSGX() const { return HasSGX; }<br>
+ bool threewayBranchProfitable() const {
return <br>
+ ThreewayBranchProfitable; }<br>
bool hasINVPCID() const { return
HasINVPCID; }<br>
bool useRetpolineIndirectCalls() const {
return UseRetpolineIndirectCalls; }<br>
bool useRetpolineIndirectBranches() const
{<br>
<br>
Modified:
llvm/trunk/lib/Target/X86/X86TargetMachine.cpp<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=344085&r1=344084&r2=344085&view=diff"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=344085&r1=344084&r2=344085&view=diff</span></a><span
lang="EN-US"><br>
==============================================================================<br>
---
llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
(original)<br>
+++
llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
Tue Oct 9 15:03:40 <br>
+++ 2018<br>
@@ -54,6 +54,11 @@ static
cl::opt<bool> EnableMachineCombin<br>
cl::desc("Enable the machine combiner
pass"),<br>
cl::init(true), cl::Hidden);<br>
<br>
+static cl::opt<bool>
EnableCondBrFoldingPass("x86-condbr-folding",<br>
+
cl::desc("Enable the conditional branch "<br>
+
"folding pass"),<br>
+
cl::init(true), cl::Hidden);<br>
+<br>
namespace llvm {<br>
<br>
void
initializeWinEHStatePassPass(PassRegistry
&); @@ -447,6 +452,8 @@ bool
X86PassConfig::addGlobalInstruction<br>
}<br>
<br>
bool X86PassConfig::addILPOpts() {<br>
+ if (EnableCondBrFoldingPass)<br>
+ addPass(createX86CondBrFolding());<br>
addPass(&EarlyIfConverterID);<br>
if (EnableMachineCombinerPass)<br>
addPass(&MachineCombinerID);<br>
<br>
Modified:
llvm/trunk/test/CodeGen/X86/O3-pipeline.ll<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/O3-pipeline.ll?rev=344085&r1=344084&r2=344085&view=diff"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/O3-pipeline.ll?rev=344085&r1=344084&r2=344085&view=diff</span></a><span
lang="EN-US"><br>
==============================================================================<br>
---
llvm/trunk/test/CodeGen/X86/O3-pipeline.ll
(original)<br>
+++
llvm/trunk/test/CodeGen/X86/O3-pipeline.ll
Tue Oct 9 15:03:40 2018<br>
@@ -72,6 +72,7 @@<br>
; CHECK-NEXT: Merge disjoint stack
slots<br>
; CHECK-NEXT: Local Stack Slot
Allocation<br>
; CHECK-NEXT: Remove dead machine
instructions<br>
+; CHECK-NEXT: X86 CondBr Folding<br>
; CHECK-NEXT: MachineDominator Tree
Construction<br>
; CHECK-NEXT: Machine Natural Loop
Construction<br>
; CHECK-NEXT: Machine Trace Metrics<br>
<br>
Added:
llvm/trunk/test/CodeGen/X86/condbr_if.ll<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/condbr_if.ll?rev=344085&view=auto"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/condbr_if.ll?rev=344085&view=auto</span></a><span
lang="EN-US"><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/condbr_if.ll
(added)<br>
+++ llvm/trunk/test/CodeGen/X86/condbr_if.ll
Tue Oct 9 15:03:40 2018<br>
@@ -0,0 +1,178 @@<br>
+; RUN: llc -mtriple=x86_64-linux-gnu
-mcpu=sandybridge %s -o - <br>
+-verify-machineinstrs | FileCheck %s
--check-prefix=MERGE ; RUN: llc <br>
+-mtriple=x86_64-linux-gnu -mcpu=ivybridge
%s -o - -verify-machineinstrs <br>
+| FileCheck %s --check-prefix=MERGE ; RUN:
llc <br>
+-mtriple=x86_64-linux-gnu -mcpu=haswell %s
-o - -verify-machineinstrs | <br>
+FileCheck %s --check-prefix=MERGE ; RUN:
llc -mtriple=x86_64-linux-gnu <br>
+-mcpu=broadwell %s -o -
-verify-machineinstrs | FileCheck %s <br>
+--check-prefix=MERGE ; RUN: llc
-mtriple=x86_64-linux-gnu -mcpu=skylake <br>
+%s -o - -verify-machineinstrs | FileCheck
%s --check-prefix=MERGE ; <br>
+RUN: llc -mtriple=x86_64-linux-gnu
-mcpu=skx %s -o - <br>
+-verify-machineinstrs | FileCheck %s
--check-prefix=MERGE ; RUN: llc <br>
+-mtriple=x86_64-linux-gnu %s -o -
-verify-machineinstrs | FileCheck %s <br>
+--check-prefix=NOTMERGE<br>
+<br>
+define i32 @length2_1(i32) {<br>
+ %2 = icmp slt i32 %0, 3<br>
+ br i1 %2, label %3, label %5<br>
+<br>
+; <label>:3:<br>
+ %4 = tail call i32 (...) @f1()<br>
+ br label %13<br>
+<br>
+; <label>:5:<br>
+ %6 = icmp slt i32 %0, 40<br>
+ br i1 %6, label %7, label %13<br>
+<br>
+; <label>:7:<br>
+ %8 = icmp eq i32 %0, 3<br>
+ br i1 %8, label %9, label %11<br>
+<br>
+; <label>:9:<br>
+ %10 = tail call i32 (...) @f2()<br>
+ br label %11<br>
+<br>
+; <label>:11:<br>
+ %12 = tail call i32 (...) @f3() #2<br>
+ br label %13<br>
+<br>
+; <label>:13:<br>
+ ret i32 0<br>
+}<br>
+; MERGE-LABEL: length2_1<br>
+; MERGE: cmpl $3<br>
+; MERGE-NEXT: jg<br>
+; MERGE-NEXT: jge<br>
+; NOTMERGE-LABEL: length2_1<br>
+; NOTMERGE: cmpl $2<br>
+; NOTMERGE-NEXT: jg<br>
+<br>
+define i32 @length2_2(i32) {<br>
+ %2 = icmp sle i32 %0, 2<br>
+ br i1 %2, label %3, label %5<br>
+<br>
+; <label>:3:<br>
+ %4 = tail call i32 (...) @f1()<br>
+ br label %13<br>
+<br>
+; <label>:5:<br>
+ %6 = icmp slt i32 %0, 40<br>
+ br i1 %6, label %7, label %13<br>
+<br>
+; <label>:7:<br>
+ %8 = icmp eq i32 %0, 3<br>
+ br i1 %8, label %9, label %11<br>
+<br>
+; <label>:9:<br>
+ %10 = tail call i32 (...) @f2()<br>
+ br label %11<br>
+<br>
+; <label>:11:<br>
+ %12 = tail call i32 (...) @f3() #2<br>
+ br label %13<br>
+<br>
+; <label>:13:<br>
+ ret i32 0<br>
+}<br>
+; MERGE-LABEL: length2_2<br>
+; MERGE: cmpl $3<br>
+; MERGE-NEXT: jg<br>
+; MERGE-NEXT: jge<br>
+; NOTMERGE-LABEL: length2_2<br>
+; NOTMERGE: cmpl $2<br>
+; NOTMERGE-NEXT: jg<br>
+<br>
+define i32 @length2_3(i32) {<br>
+ %2 = icmp sgt i32 %0, 3<br>
+ br i1 %2, label %3, label %5<br>
+<br>
+; <label>:3:<br>
+ %4 = tail call i32 (...) @f1()<br>
+ br label %13<br>
+<br>
+; <label>:5:<br>
+ %6 = icmp sgt i32 %0, -40<br>
+ br i1 %6, label %7, label %13<br>
+<br>
+; <label>:7:<br>
+ %8 = icmp eq i32 %0, 3<br>
+ br i1 %8, label %9, label %11<br>
+<br>
+; <label>:9:<br>
+ %10 = tail call i32 (...) @f2()<br>
+ br label %11<br>
+<br>
+; <label>:11:<br>
+ %12 = tail call i32 (...) @f3() #2<br>
+ br label %13<br>
+<br>
+; <label>:13:<br>
+ ret i32 0<br>
+}<br>
+; MERGE-LABEL: length2_3<br>
+; MERGE: cmpl $3<br>
+; MERGE-NEXT: jl<br>
+; MERGE-NEXT: jle<br>
+; NOTMERGE-LABEL: length2_3<br>
+; NOTMERGE: cmpl $4<br>
+; NOTMERGE-NEXT: jl<br>
+<br>
+define i32 @length2_4(i32) {<br>
+ %2 = icmp sge i32 %0, 4<br>
+ br i1 %2, label %3, label %5<br>
+<br>
+; <label>:3:<br>
+ %4 = tail call i32 (...) @f1()<br>
+ br label %13<br>
+<br>
+; <label>:5:<br>
+ %6 = icmp sgt i32 %0, -40<br>
+ br i1 %6, label %7, label %13<br>
+<br>
+; <label>:7:<br>
+ %8 = icmp eq i32 %0, 3<br>
+ br i1 %8, label %9, label %11<br>
+<br>
+; <label>:9:<br>
+ %10 = tail call i32 (...) @f2()<br>
+ br label %11<br>
+<br>
+; <label>:11:<br>
+ %12 = tail call i32 (...) @f3() #2<br>
+ br label %13<br>
+<br>
+; <label>:13:<br>
+ ret i32 0<br>
+}<br>
+; MERGE-LABEL: length2_4<br>
+; MERGE: cmpl $3<br>
+; MERGE-NEXT: jl<br>
+; MERGE-NEXT: jle<br>
+; NOTMERGE-LABEL: length2_4<br>
+; NOTMERGE: cmpl $4<br>
+; NOTMERGE-NEXT: jl<br>
+<br>
+declare i32 @f1(...)<br>
+declare i32 @f2(...)<br>
+declare i32 @f3(...)<br>
+<br>
+define i32 @length1_1(i32) {<br>
+ %2 = icmp sgt i32 %0, 5<br>
+ br i1 %2, label %3, label %5<br>
+<br>
+; <label>:3:<br>
+ %4 = tail call i32 (...) @f1()<br>
+ br label %9<br>
+<br>
+; <label>:5:<br>
+ %6 = icmp eq i32 %0, 5<br>
+ br i1 %6, label %7, label %9<br>
+<br>
+; <label>:7:<br>
+ %8 = tail call i32 (...) @f2()<br>
+ br label %9<br>
+<br>
+; <label>:9:<br>
+ ret i32 0<br>
+}<br>
+; MERGE-LABEL: length1_1<br>
+; MERGE: cmpl $5<br>
+; MERGE-NEXT: jl<br>
+; MERGE-NEXT: jle<br>
+; NOTMERGE-LABEL: length1_1<br>
+; NOTMERGE: cmpl $6<br>
+; NOTMERGE-NEXT: jl<br>
<br>
Added:
llvm/trunk/test/CodeGen/X86/condbr_switch.ll<br>
URL: </span><a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/condbr_switch.ll?rev=344085&view=auto"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/condbr_switch.ll?rev=344085&view=auto</span></a><span
lang="EN-US"><br>
==============================================================================<br>
---
llvm/trunk/test/CodeGen/X86/condbr_switch.ll
(added)<br>
+++
llvm/trunk/test/CodeGen/X86/condbr_switch.ll
Tue Oct 9 15:03:40 <br>
+++ 2018<br>
@@ -0,0 +1,167 @@<br>
+; RUN: llc -mtriple=x86_64-linux-gnu
-mcpu=sandybridge %s -o - <br>
+-verify-machineinstrs | FileCheck %s
--check-prefix=MERGE ; RUN: llc <br>
+-mtriple=x86_64-linux-gnu -mcpu=ivybridge
%s -o - -verify-machineinstrs <br>
+| FileCheck %s --check-prefix=MERGE ; RUN:
llc <br>
+-mtriple=x86_64-linux-gnu -mcpu=haswell %s
-o - -verify-machineinstrs | <br>
+FileCheck %s --check-prefix=MERGE ; RUN:
llc -mtriple=x86_64-linux-gnu <br>
+-mcpu=broadwell %s -o -
-verify-machineinstrs | FileCheck %s <br>
+--check-prefix=MERGE ; RUN: llc
-mtriple=x86_64-linux-gnu -mcpu=skylake <br>
+%s -o - -verify-machineinstrs | FileCheck
%s --check-prefix=MERGE ; <br>
+RUN: llc -mtriple=x86_64-linux-gnu
-mcpu=skx %s -o - <br>
+-verify-machineinstrs | FileCheck %s
--check-prefix=MERGE ; RUN: llc <br>
+-mtriple=x86_64-linux-gnu %s -o -
-verify-machineinstrs | FileCheck %s <br>
+--check-prefix=NOTMERGE<br>
+<br>
+@v1 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v2 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v3 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v4 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v5 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v6 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v7 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v8 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v9 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v10 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v11 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v12 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v13 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v14 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+@v15 = common dso_local local_unnamed_addr
global i32 0, align 4<br>
+<br>
+define dso_local i32 @fourcases(i32 %n) {<br>
+entry:<br>
+ switch i32 %n, label %return [<br>
+ i32 111, label %</span><a
href="http://sw.bb" target="_blank"
moz-do-not-send="true"><span lang="EN-US">sw.bb</span></a><span
lang="EN-US"><br>
+ i32 222, label %sw.bb1<br>
+ i32 3665, label %sw.bb2<br>
+ i32 4444, label %sw.bb4<br>
+ ]<br>
+<br>
+</span><a href="http://sw.bb"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">sw.bb</span></a><span
lang="EN-US">:<br>
+ %0 = load i32, i32* @v1, align 4<br>
+ br label %return<br>
+<br>
+sw.bb1:<br>
+ %1 = load i32, i32* @v2, align 4<br>
+ %add = add nsw i32 %1, 12<br>
+ br label %return<br>
+<br>
+sw.bb2:<br>
+ %2 = load i32, i32* @v3, align 4<br>
+ %add3 = add nsw i32 %2, 13<br>
+ br label %return<br>
+<br>
+sw.bb4:<br>
+ %3 = load i32, i32* @v1, align 4<br>
+ %4 = load i32, i32* @v2, align 4<br>
+ %add5 = add nsw i32 %4, %3<br>
+ br label %return<br>
+<br>
+return:<br>
+ %retval.0 = phi i32 [ %add5, %sw.bb4 ], [
%add3, %sw.bb2 ], [ %add, <br>
+%sw.bb1 ], [ %0, %</span><a
href="http://sw.bb" target="_blank"
moz-do-not-send="true"><span lang="EN-US">sw.bb</span></a>
<span lang="EN-US">], [ 0, %entry ]<br>
+ ret i32 %retval.0<br>
+}<br>
+; MERGE-LABEL: fourcases<br>
+; MERGE: cmpl $3665<br>
+; MERGE-NEXT: jg<br>
+; MERGE-NEXT: jge<br>
+; NOTMERGE: cmpl $3664<br>
+; NOTMERGE-NEXT: jg<br>
+<br>
+define dso_local i32 @fifteencases(i32) {<br>
+ switch i32 %0, label %32 [<br>
+ i32 -111, label %2<br>
+ i32 -13, label %4<br>
+ i32 25, label %6<br>
+ i32 37, label %8<br>
+ i32 89, label %10<br>
+ i32 111, label %12<br>
+ i32 213, label %14<br>
+ i32 271, label %16<br>
+ i32 283, label %18<br>
+ i32 325, label %20<br>
+ i32 327, label %22<br>
+ i32 429, label %24<br>
+ i32 500, label %26<br>
+ i32 603, label %28<br>
+ i32 605, label %30<br>
+ ]<br>
+<br>
+; <label>:2<br>
+ %3 = load i32, i32* @v1, align 4<br>
+ br label %32<br>
+<br>
+; <label>:4<br>
+ %5 = load i32, i32* @v2, align 4<br>
+ br label %32<br>
+<br>
+; <label>:6<br>
+ %7 = load i32, i32* @v3, align 4<br>
+ br label %32<br>
+<br>
+; <label>:8<br>
+ %9 = load i32, i32* @v4, align 4<br>
+ br label %32<br>
+<br>
+; <label>:10<br>
+ %11 = load i32, i32* @v5, align 4<br>
+ br label %32<br>
+<br>
+; <label>:12<br>
+ %13 = load i32, i32* @v6, align 4<br>
+ br label %32<br>
+<br>
+; <label>:14<br>
+ %15 = load i32, i32* @v7, align 4<br>
+ br label %32<br>
+<br>
+; <label>:16<br>
+ %17 = load i32, i32* @v8, align 4<br>
+ br label %32<br>
+<br>
+; <label>:18<br>
+ %19 = load i32, i32* @v9, align 4<br>
+ br label %32<br>
+<br>
+; <label>:20<br>
+ %21 = load i32, i32* @v10, align 4<br>
+ br label %32<br>
+<br>
+; <label>:22<br>
+ %23 = load i32, i32* @v11, align 4<br>
+ br label %32<br>
+<br>
+; <label>:24<br>
+ %25 = load i32, i32* @v12, align 4<br>
+ br label %32<br>
+<br>
+; <label>:26<br>
+ %27 = load i32, i32* @v13, align 4<br>
+ br label %32<br>
+<br>
+; <label>:28:<br>
+ %29 = load i32, i32* @v14, align 4<br>
+ br label %32<br>
+<br>
+; <label>:30:<br>
+ %31 = load i32, i32* @v15, align 4<br>
+ br label %32<br>
+<br>
+; <label>:32:<br>
+ %33 = phi i32 [ %31, %30 ], [ %29, %28 ],
[ %27, %26 ], [ %25, %24 ], <br>
+[ %23, %22 ], [ %21, %20 ], [ %19, %18 ], [
%17, %16 ], [ %15, %14 ], [ <br>
+%13, %12 ], [ %11, %10 ], [ %9, %8 ], [ %7,
%6 ], [ %5, %4 ], [ %3, %2 <br>
+], [ 0, %1 ]<br>
+ ret i32 %33<br>
+}<br>
+; MERGE-LABEL: fifteencases<br>
+; MERGE: cmpl $271<br>
+; MERGE-NEXT: jg<br>
+; MERGE-NEXT: jge<br>
+; MERGE: cmpl $37<br>
+; MERGE-NEXT: jg<br>
+; MERGE-NEXT: jge<br>
+; MERGE: cmpl $429<br>
+; MERGE-NEXT: jg<br>
+; MERGE-NEXT: jge<br>
+; MERGE: cmpl $325<br>
+; MERGE-NEXT: jg<br>
+; MERGE-NEXT: jge<br>
+; MERGE: cmpl $603<br>
+; MERGE-NEXT: jg<br>
+; MERGE-NEXT: jge<br>
+; NOTMERGE-LABEL: fifteencases<br>
+; NOTMERGE: cmpl $270<br>
+; NOTMERGE-NEXT: jle<br>
+<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
</span><a
href="mailto:llvm-commits@lists.llvm.org"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">llvm-commits@lists.llvm.org</span></a><span
lang="EN-US"><br>
</span><a
href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits"
target="_blank" moz-do-not-send="true"><span
lang="EN-US">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</span></a><o:p></o:p></p>
</blockquote>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
llvm-commits mailing list
<a class="moz-txt-link-abbreviated" href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a>
</pre>
</blockquote>
</body>
</html>