<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=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.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"><span style="color:#1F497D">OK, to follow up to my own post, I made a fix in firstCommonClass (copied below for reference). I’m not convinced about the fix, but I am convinced that the code as written is at least partially wrong. The function
 is looping through the subclass bitvectors of two register classes, looking for the first common subclass. The main loop is looping through the bitvectors word by word. It’s possible that in any given word there is more than one common bit. The code checks
 the first (rightmost bit). If that class is disqualified by the type check, it loops to the next word rather than checking other bits in the current word.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">So my fix has two parts. First: add isAllocatable() to the qualification check. Second: add an inner loop so that if the qualification check fails, we’ll iterate on the other common bits in the current word.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">I’m looking for a little confirmation that this seems sensible, since I’m new to LLVM.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">-Alan<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">static inline<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">const TargetRegisterClass *firstCommonClass(const uint32_t *A,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                                            const uint32_t *B,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                                            const TargetRegisterInfo *TRI,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                                            const MVT::SimpleValueType SVT =<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                                            MVT::SimpleValueType::Any) {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">  const MVT VT(SVT);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">  for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; I += 32)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">    if (unsigned Common = *A++ & *B++) {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">      const TargetRegisterClass *RC =<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">          TRI->getRegClass(I + countTrailingZeros(Common));<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">      if (SVT == MVT::SimpleValueType::Any || RC->hasType(VT))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        return RC;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">  return nullptr;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> Davis, Alan
<br>
<b>Sent:</b> Thursday, May 04, 2017 9:35 PM<br>
<b>To:</b> llvm-dev@lists.llvm.org<br>
<b>Subject:</b> problem with non-allocatable register classes<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I am using some non-allocatable RegisterClasses to define lists of registers that are used for various non-allocation-related processing in the back end. For example, we have a post-allocation functional unit selection pass that is guided
 by the register assignment, which does things like ‘myRegClass.contains(Reg)’ to see if a register is in the set of registers accessible by a given unit.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">These sets contain lists of both allocatable and non-allocatable registers (for example, GPRs plus PC and SP). So I defined them as non-allocatable, and defined separate classes for use in the allocator.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The problem is that tablegen does all kinds of clever analysis of the register classes, determining subsets and supersets and such, which are used to answer methods like getCommonSubClass(). In some cases it synthesizes new classes, which
 may or may not be allocatable depending on how the non-allocatable classes get mixed in. If a function like getCommonSubClass() returns a non-allocatable class, bad things happen (e.g. assertion failures from setRegClass()).
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">It seems to me that functions like getCommonSubClass() should never return non-allocatable classes. But there seems to be no provision in tablegen to keep that from happening. It seems likely that no one has encountered this because for
 most targets non-allocatable classes contain registers that don’t overlap much with the allocatable classes.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Does anyone have any guidance as far as fixing or working around this?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">-Alan<o:p></o:p></p>
</div>
</body>
</html>