<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:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        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">If you want to investigate extending inline asm capabilities, I’d start by looking at InstrEmitter::EmitSpecialNode.  It already understands inline asm operands that don’t fit in a single register; it just isn’t handling them the way you
 want it to.  Basically, the idea would be that you emit a REG_SEQUENCE pseudo-instruction to merge the register operands into one big register, and EXTRACT_SUBREG to split the register result into multiple registers.<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> Nemanja Ivanovic <nemanja.i.ibm@gmail.com> <br>
<b>Sent:</b> Wednesday, January 29, 2020 12:19 PM<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] Limited use types in the back end<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">Well, frankly the issue is mainly the inline asm.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Say the instruction has the form<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><opcode> RT, RA, RB<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Where all of RT/RA/RB have to be multiples of 4. The instruction does a binary operation: RA/RA+1/RA+2/RA+3 <op> RB/RB+1/RB+2/RB+3. Namely, the operation is performed on 4 vector registers at a time, producing a 4 vector register result.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">This can be modeled in a rather straightforward way with the right number of operands and results to the SDAG node for the operation.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">However, to let the register allocator select a register for an inline asm constraint, I need to say that variable X goes into register R. I have a constraint that says give me one of these registers that are composed of 4 other registers.
 And the variable has a type that is as wide as 4 vectors (say v8i64). Then when the DAG builder tries to build the INLINEASM node for that directive, it wants to split the illegal type into 4 vectors to create the CopyToReg nodes.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">This is really an issue with any type that is wider than the widest register.<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Mon, Jan 27, 2020 at 3:26 PM Eli Friedman <<a href="mailto:efriedma@quicinc.com">efriedma@quicinc.com</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">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I’m not sure I understand the difficulty here.  Normally, if you have an instruction which has multiple operand/result registers, you just make the SelectionDAG node have multiple
 operand/result values.  If there are weird register allocation constraints, you can handle that in ISelDAGToDAG.  (There are a few ARM instructions that expect multiple registers in ascending order, like vtbl and vld4/vst4.)<o:p></o:p></p>
<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">If you need inline asm operands/results with an illegal type, that’s sort of an independent issue.  x86 uses a fake register class to handle the “A” constraint, which refers to
 the register pair RAX/RDX. (See X86TargetLowering::getRegForInlineAsmConstraint).  If that doesn’t work in your case, not sure what I’d do off the top of my head; maybe the code for lowering inline asm could be extended.<o:p></o:p></p>
<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">-Eli<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div style="border:none;border-left:solid windowtext 1.5pt;padding:0in 0in 0in 4.0pt;border-color:currentcolor currentcolor currentcolor blue">
<div>
<div style="border:none;border-top:solid windowtext 1.0pt;padding:3.0pt 0in 0in 0in;border-color:currentcolor currentcolor">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b>From:</b> llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>>
<b>On Behalf Of </b>Nemanja Ivanovic via llvm-dev<br>
<b>Sent:</b> Monday, January 27, 2020 8:59 AM<br>
<b>To:</b> llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> [EXT] [llvm-dev] Limited use types in the back end<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>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I am hoping that someone can offer advice on a somewhat unusual issue that I am facing with the SDAG. Namely, I am trying to implement some custom operations that do very specific
 things on multiple registers at a time. The operations themselves will simply be intrinsics since there are no equivalent operations in IR/SDAG. However, handling the types seems rather tricky.<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>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">One approach I tried is to create a register class that has the wide registers with proper sub registers and then telling the SDAG that the correspondingly wide type can go into
 those registers. While this works, it has a very unfortunate side effect that the type legalizer leaves any node with such a type untouched and I have to mark all operations as non-legal (mostly Expand).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">For example, I could say that the type v8i64 can go into these registers and then I can use the type for my intrinsics. However, the type legalizer will leave all nodes with this
 result/operand type alone which is not at all what I want.<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>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Then I tried the opposite approach - just custom lower only specific nodes that have this result type and let the type legalizer handle all the others normally. This works quite
 well except if I want to expose those custom instructions through inline asm. The DAG builder complains if I am trying to assign one of these wide registers to a value with the wide type because it assumes that the wide value will need to be broken up.<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>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I suppose I could define a new type for the IR/SDAG and use it, but that seems like a super pervasive approach.<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>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">So either direction I go in seems to have a major drawback.<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</body>
</html>