<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)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:Helvetica;
        panose-1:2 11 6 4 2 2 2 2 2 4;}
@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;}
@font-face
        {font-family:Menlo;
        panose-1:0 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Monaco;
        panose-1:0 0 0 0 0 0 0 0 0 0;}
/* 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;}
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:11.0pt;
        font-family:"Calibri",sans-serif;}
span.pl-en
        {mso-style-name:pl-en;}
span.apple-converted-space
        {mso-style-name:apple-converted-space;}
span.EmailStyle20
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.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">Have you implemented TargetRegisterInfo::getCrossCopyRegClass?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">-Eli<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></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>From:</b> Joan Lluch <joan.lluch@icloud.com> <br>
<b>Sent:</b> Sunday, June 2, 2019 2:39 AM<br>
<b>To:</b> Eli Friedman <efriedma@quicinc.com><br>
<b>Cc:</b> llvm-dev <llvm-dev@lists.llvm.org><br>
<b>Subject:</b> [EXT] Re: [llvm-dev] Optimizing Compare instruction selection<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Hi Eli,<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Thank  you very much for your response. <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">In fact, I had already tried the X86 approach before, i.e explicitly using the status register. This is the approach that appeals more to me. I left it parked because it also produced some problems (but I left it commented out). So I have
 now re-lived the code, and it works fine in most cases, but there’s a particular case that causes LLVM to stop with an assertion. Apparently LLVM tries to use the SR (Status Register) register as a general purpose one, which is not allowed in my architecture.
 The problem exists even before I added the referred optimisations. The code that causes the problem is this:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif;color:#BA2DA2">int</span><span style="font-size:8.5pt;font-family:"Monaco",serif"> doSmth(
<span style="color:#BA2DA2">int</span> y );<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif;color:#BA2DA2">int</span><span style="font-size:8.5pt;font-family:"Monaco",serif"> test( <span style="color:#BA2DA2">int</span> y )<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif">{<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif"> 
<span style="color:#BA2DA2">int</span> neg = y < <span style="color:#272AD8">0</span>;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif"> 
<span style="color:#BA2DA2">if</span> ( neg )<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif">    y = - y;<o:p></o:p></span></p>
</div>
<p class="MsoNormal" style="background:white;min-height: 15px"><span style="font-size:8.5pt;font-family:"Monaco",serif">  <o:p></o:p></span></p>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif"> 
<span style="color:#BA2DA2">int</span> rv = doSmth( y );<o:p></o:p></span></p>
</div>
<p class="MsoNormal" style="background:white;min-height: 15px"><span style="font-size:8.5pt;font-family:"Monaco",serif">  <o:p></o:p></span></p>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif"> 
<span style="color:#BA2DA2">return</span> neg ? - rv : rv;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:8.5pt;font-family:"Monaco",serif">}<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Apparently, LLVM attempts to physically use the result of a CMP instruction through a function call by storing it on a temporary register. This is found before the doSmth function call, <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif">  t30: i16 = CMPkr16 t4, TargetConstant:i16<0></span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif">    t36: ch,glue = CopyToReg t0, Register:i16 $sr, t30</span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif">  t32: i16 = NEGSETCC TargetConstant:i16<4>, t36:1</span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif"><br>
<br>
</span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
</div>
</div>
</div>
<div>
<p class="MsoNormal">And this is generated after the call<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif">      t35: ch,glue = CopyToReg t0, Register:i16 $sr, t30</span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif">    t31: i16 = SELCC t19, t18, TargetConstant:i16<4>, t35:1</span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif">  t21: ch,glue = CopyToReg t18:1, Register:i16 $r0, t31</span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif"> </span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal">NEGSETCC and SELCC are genuine instructions of my target architecture, they use the SR along with operands to produce a result.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">As you can see ‘t30’ is used both before and after the function call, which is what I think that causes trouble. In particular, the assertion that I get is this:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal"><b><span style="font-size:8.5pt;font-family:"Menlo",serif">Assertion failed: (RegClass->isAllocatable() && "Virtual register RegClass must be allocatable."), function createVirtualRegister, file /Users/joan/LLVM+CLANG/llvm-7.0.1.src/lib/CodeGen/MachineRegisterInfo.cpp,
 line 170.</span></b><span style="font-size:8.5pt;font-family:"Menlo",serif"><o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If I remove the ‘isAllocatable=0’ setting on the SR register, then LLVM will try to spill the SR by calling ‘storeRegToStackSlot’, which then I stop with my own assertion because the SR can’t be spilled.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If I then remove also the ‘let CopCost = -1’ for the SR register, then LLVM attempts to move it to a general purpose register by calling ‘copyPhysRegs’, which again I stop with an assertion because it’s not legal in my architecture.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">So, I’m stuck as well with this approach.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Any ideas, on what I can try?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I think, that at this point I need to stop LLVM from attempting to reuse the result of the CMP instruction before and after the function call, and instead make it generate a new cmp instruction after the call. But how do I achieve that?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">(maybe a difficulty is that I am Custom lowering ’’SELECT_CC’ and ‘BR_CC’, and Expanding ’SELECT’ and ‘BRCOND’, instead of the opposite? Does this make a difference?)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Thanks<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Helvetica",sans-serif;color:black">Joan Lluch<br>
<br>
Tel: 620 28 45 13<o:p></o:p></span></p>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">On 2 Jun 2019, at 03:23, Eli Friedman <<a href="mailto:efriedma@quicinc.com">efriedma@quicinc.com</a>> wrote:<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">There are basically two possible approaches here.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">One approach is to just wait until after isel to handle this: check for an addition instruction immediately followed by an cmp; then erase the cmp. See, for example,<span class="pl-en"> ARMBaseInstrInfo::optimizeCompareInstr</span>.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">Another, you make a dedicated target-specific ISel node that produces two results: essentially, one is the result of the arithmetic, and the other is the status register.  See, for
 example, X86TargetLowering::LowerBRCOND.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">I don't think you'd want to try to do anything in Select(); I mean, you could try to pattern-match (cmp x, (add x, y)) or whatever, but you'd probably run into trouble if the add has
 multiple uses.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">-Eli<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<div class="MsoNormal" align="center" style="text-align:center;background:white">
<span style="font-size:12.0pt">
<hr size="2" width="1072" style="width:804.1pt" align="center">
</span></div>
<div id="divRplyFwdMsg">
<p class="MsoNormal" style="background:white"><b>From:</b><span class="apple-converted-space"> </span>llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org">llvm-dev-bounces@lists.llvm.org</a>> on behalf of Joan Lluch via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>><br>
<b>Sent:</b><span class="apple-converted-space"> </span>Saturday, June 1, 2019 10:09 AM<br>
<b>To:</b><span class="apple-converted-space"> </span>llvm-dev<br>
<b>Subject:</b><span class="apple-converted-space"> </span>[EXT] [llvm-dev] Optimizing Compare instruction selection<span style="font-size:12.0pt"><o:p></o:p></span></p>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"> <o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">I attempt to optimize the use of the ‘CMP’ instruction on my architecture by removing the instruction instances where the Status Register already had the correct status flags.<o:p></o:p></span></p>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">The cmp instruction in my architecture is the typical one that compares two registers, or a register with an immediate, and sets the Status Flags accordingly. I implemented my ‘cmp’
  instruction in LLVM by custom lowering the SETCC, SELECT_CC and BR_CC in the usual way, mostly following the ARM implementation. In particular the target cmp instruction is created and glued to a target conditional instruction, such as a conditional branch,
 or a conditional select. <o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">The generated code may look like this:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">add R0, R1, R2<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">cmp R0, #0<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">breq Label<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">This works fine, but now I would want to go one step further:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">As part of the SETCC and SELECT_CC lowering, I can determine if the conditions are met in my architecture to avoid generating a ‘cmp’ instruction at all. For example, if the left operand
 of the SETCC is an ‘addition', the right operand is constant zero, and the condition is 'ISD::CondCode::SETEQ, I can safely assume that the Status Register in my architecture already has the right condition just before the ‘cmp’, which has been set by the
 target ‘add’ instruction. So at this point I want to avoid generating the ‘cmp’ because it is redundant. <o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">My goal is to replace the assembly code shown above, by just this:<o:p></o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">add R0, R1, R2<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">breq Label<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">The ‘cmp’ was redundant in this case because the add instruction already set the Z (zero) flag<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">I tried several things, but I got stuck in some way in all of them. For example, an approach that I tried is to have a ‘dummy_cmp’ instruction, that I generate instead of the regular
 ‘cmp’ when the comparison is redundant. The ‘dummy_cmp’ must be removed at a latter stage, ideally during the selDAGToDAG phase, but I failed to do so. <o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">- So my first question is. How do I remove the ‘dummy_cmp’ node in the MyTargetISelDAGtoDAG::Select() function?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">Another approach that I tried, which I regard as preferable, is to directly avoid the creation of a ‘cmp’ instruction during ISelLowering. Instead of ‘cmp’, use the LHS operand of
 the SETCC operand if it mets the conditions described above. The problem that I found with this approach is that the ‘cmp’ is just a ‘glue’ to the target branch or select instruction, however, the LHS is an actual operand (for example an ‘add’ node), so I
 need to create a ‘glue’ for it, in order to be attached to the target branch instruction.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt">- My second question is therefore, how do I create a ‘glue’ for an existing ‘add’ node that I can attach to the target conditional instruction as a replacement of the ‘cmp’ instruction?
   <o:p></o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt"> <o:p></o:p></span></p>
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:9.0pt;font-family:"Helvetica",sans-serif">Joan Lluch<o:p></o:p></span></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</body>
</html>