<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">No worries :-). Thanks for fixing it.<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 27 Jun 2017, at 17:40, David Green <<a href="mailto:David.Green@arm.com" class="">David.Green@arm.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div id="divtagdefaultwrapper" dir="ltr" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; font-size: 11pt; font-family: Calibri, Helvetica, sans-serif;" class=""><p style="margin-top: 0px; margin-bottom: 0px;" class=""></p><div class="">Oh hey, sorry about that. Crossed wires, and I already had a build going :)</div><div class=""><br class=""></div><div class="">Went in as r306422, hope it looks OK.</div><div class=""><span style="font-size: 11pt;" class="">Cheers.</span><br class=""></div><div class="">Dave</div><br class=""><p style="margin-top: 0px; margin-bottom: 0px;" class=""></p></div><hr tabindex="-1" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; display: inline-block; width: 917.265625px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""></span><div id="divRplyFwdMsg" dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Calibri, sans-serif" style="font-size: 11pt;" class=""><b class="">From:</b><span class="Apple-converted-space"> </span><a href="mailto:daniel_l_sanders@apple.com" class="">daniel_l_sanders@apple.com</a> <<a href="mailto:daniel_l_sanders@apple.com" class="">daniel_l_sanders@apple.com</a>> on behalf of Daniel Sanders <<a href="mailto:daniel_l_sanders@apple.com" class="">daniel_l_sanders@apple.com</a>><br class=""><b class="">Sent:</b><span class="Apple-converted-space"> </span>27 June 2017 17:37:20<br class=""><b class="">To:</b><span class="Apple-converted-space"> </span>Daniel Sanders<br class=""><b class="">Cc:</b><span class="Apple-converted-space"> </span>David Green; nd; llvm-commits<br class=""><b class="">Subject:</b><span class="Apple-converted-space"> </span>Re: [llvm] r306388 - [globalisel][tablegen] Add support for EXTRACT_SUBREG.</font><div class=""> </div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">It looks like you're a bit quicker than me. After re-running 'ninja check' I went to commit the fix but r306422 has beaten me to it.<br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On 27 Jun 2017, at 17:07, Daniel Sanders via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Hi David,<div class=""><br class=""></div><div class="">Sure, the main thing is that we inspect larger classes first. The order of equal-sized classes shouldn't matter too much.<br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On 27 Jun 2017, at 16:48, David Green <<a href="mailto:David.Green@arm.com" class="">David.Green@arm.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div id="divtagdefaultwrapper" dir="ltr" class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; font-size: 11pt; font-family: Calibri, Helvetica, sans-serif;"><div id="divtagdefaultwrapper" dir="ltr" class="" style="font-size: 11pt; font-family: Calibri, Helvetica, sans-serif, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols;"><div class="" style="margin-top: 0px; margin-bottom: 0px;">Hello,</div><div class="" style="margin-top: 0px; margin-bottom: 0px;"><br class=""></div><div class="" style="margin-top: 0px; margin-bottom: 0px;">We appear to have a windows-debug build error from what I think is this commit, a crash in tblgen:</div><div class="" style="margin-top: 0px; margin-bottom: 0px;"><br class=""></div><p class="" style="margin-top: 0px; margin-bottom: 0px;"></p><div class="">                 0x00007FF9E6CA0806 (0x00007FF735189138 0x00007FF735188DE0 0x000000F300000A52 0xCCCCCCCCCCCCCCCC), ?_Debug_message@std@@YAXPEB_W0I@Z() + 0x46 bytes(s)</div><div class="">                 0x00007FF7345F58E1 (0x000000F3A0A6CA50 0x000000F3A0A6C898 0x000000F3A5BB8570 0x00007FF735188DE0), std::_Debug_lt_pred<<lambda_83a80e87367d92ad251c7c618cd76f21> & __ptr64,std::pair<llvm::CodeGenRegisterClass * __ptr64,llvm::BitVector> & __ptr64,std::pair<llvm::CodeGenRegisterClass * __ptr64,llvm::BitVector> & __ptr64>() + 0x81 bytes(s), c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility, line 896 + 0x54 byte(s)</div><div class="">                 0x00007FF734608251 (0x000000F3A5BB8550 0x000000F3A5BB85F0 0x000000F3A0A6CA50 0xCCCCCCCCCCCCCCCC), std::_Insertion_sort_unchecked<std::pair<llvm::CodeGenRegisterClass * __ptr64,llvm::BitVector> * __ptr64,<lambda_83a80e87367d92ad251c7c618cd76f21> >() + 0x151 bytes(s), c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm, line 2642 + 0x34 byte(s)</div><div class="">                 0x00007FF734611B78 (0x000000F3A5BB8550 0x000000F3A5BB85F0 0x0000000000000005 0x000000F3A0A6CA50), std::_Sort_unchecked1<std::pair<llvm::CodeGenRegisterClass * __ptr64,llvm::BitVector> * __ptr64,__int64,<lambda_83a80e87367d92ad251c7c618cd76f21> >() + 0x198 bytes(s), c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm, line 2770</div><div class="">                 0x00007FF734611E13 (0x000000F3A5BB8550 0x000000F3A5BB85F0 0x000000F3A0A6CA50 0xCCCCCCCC00000ADF), std::_Sort_unchecked<std::pair<llvm::CodeGenRegisterClass * __ptr64,llvm::BitVector> * __ptr64,<lambda_83a80e87367d92ad251c7c618cd76f21> >() + 0x53 bytes(s), c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm, line 2777</div><div class="">                 0x00007FF7346232E2 (0x000000F3A0A6CDF8 0x000000F3A0A6CDD8 0x000000F3A0A6CA64 0xCCCCCCCCCCCCCCCC), std::sort<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::pair<llvm::CodeGenRegisterClass * __ptr64,llvm::BitVector> > > >,<lambda_83a80e87367d92ad251c7c618cd76f21> >() + 0x102 bytes(s), c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm, line 2785</div><div class="">                 0x00007FF7345DA928 (0x000000F3A8B9AAF0 0x000000F3A0A6CF58 0x000000F3A0A6E868 0x000000F3A5BB4150), llvm::CodeGenRegisterClass::getMatchingSubClassWithSubRegs() + 0x428 bytes(s), c:\work\trunk\work\src\llvm\utils\tablegen\codegenregisters.cpp, line 964</div><div class="">                 0x00007FF7348051B8 (0x000000F3A0A6E660 0x000000F3A0A6D848 0x000000F3A0A6D470 0x000000F3A989E3F0), `anonymous namespace'::GlobalISelEmitter::createAndImportInstructionRenderer() + 0x5F8 bytes(s), c:\work\trunk\work\src\llvm\utils\tablegen\globaliselemitter.cpp, line 1674 + 0x2E byte(s)</div><div class="">                 0x00007FF7348071CA (0x000000F3A0A6E660 0x000000F3A0A6DF40 0x000000F3A9BD09A0 0xCCCCCCCCCCCCCCCC), `anonymous namespace'::GlobalISelEmitter::runOnPattern() + 0xDEA bytes(s), c:\work\trunk\work\src\llvm\utils\tablegen\globaliselemitter.cpp, line 1840</div><div class="">                 0x00007FF734802866 (0x000000F3A0A6E660 0x000000F3A0A6F290 0xCCCCCCCCCCCCCCCC 0xCCCCCCCCCCCCCCCC), `anonymous namespace'::GlobalISelEmitter::run() + 0x1D6 bytes(s), c:\work\trunk\work\src\llvm\utils\tablegen\globaliselemitter.cpp, line 1934</div><div class="">                 0x00007FF734807B2D (0x000000F3A0A6EFA8 0x000000F3A0A6F290 0xCCCCCCCCCCCCCCCC 0xCCCCCCCCCCCCCCCC), llvm::EmitGlobalISel() + 0x5D bytes(s), c:\work\trunk\work\src\llvm\utils\tablegen\globaliselemitter.cpp, line 2056 + 0x22 byte(s)</div><div class="">                 0x00007FF73497AA39 (0x000000F3A0A6F290 0x000000F3A0A6EFA8 0x000000F3A0A6F228 0xCCCCCCCC00000004), `anonymous namespace'::LLVMTableGenMain() + 0x739 bytes(s), c:\work\trunk\work\src\llvm\utils\tablegen\tablegen.cpp, line 192</div><div class="">                 0x00007FF734B2A155 (0x000000F3A0C9F210 0x00007FF73497A300 0x000000F3A0A6F670 0x0000000000000000), llvm::TableGenMain() + 0x605 bytes(s), c:\work\trunk\work\src\llvm\lib\tablegen\main.cpp, line 109 + 0x1C byte(s)</div><div class="">                 0x00007FF73497ABFD (0x00007FF70000000B 0x000000F3A0C9F1B0 0x0000000000000000 0x00007FF73516ABD0), main() + 0x10D bytes(s), c:\work\trunk\work\src\llvm\utils\tablegen\tablegen.cpp, line 212 + 0x21 byte(s)</div><div class="">                 0x00007FF734FC4584 (0x00007FF73516A000 0x00007FF73516A670 0x0000000000000000 0x0000000000000000), invoke_main() + 0x34 bytes(s), f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl, line 65</div><div class="">                 0x00007FF734FC4447 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000), __scrt_common_main_seh() + 0x127 bytes(s), f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl, line 253 + 0x5 byte(s)</div><div class="">                 0x00007FF734FC430E (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000), __scrt_common_main() + 0xE bytes(s), f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl, line 296</div><div class="">                 0x00007FF734FC45A9 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000), mainCRTStartup() + 0x9 bytes(s), f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp, line 17</div><div class="">                 0x00007FF9FC9D13D2 (0x00007FF9FC9D13B0 0x0000000000000000 0x0000000000000000 0x0000000000000000), BaseThreadInitThunk() + 0x22 bytes(s)</div><div class="">                 0x00007FF9FCB254E4 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000), RtlUserThreadStart() + 0x34 bytes(s)</div><br class=""><p class="" style="margin-top: 0px; margin-bottom: 0px;"></p>Sorry if that is hard to read. It looks like it's complaining about the <span class="">SizeOrder lambda not being in strict weak ordering. Changing the "<span class="">return A->getMembers().size() >= B->getMembers().size();" to be a ">" seems to get it build.</span></span></div><div id="divtagdefaultwrapper" dir="ltr" class="" style="font-size: 11pt; font-family: Calibri, Helvetica, sans-serif, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols;"><span class=""><span class=""><br class=""></span></span></div><div id="divtagdefaultwrapper" dir="ltr" class="" style="font-size: 11pt; font-family: Calibri, Helvetica, sans-serif, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols;"><span class=""><span class="">Are you happy to make that a ">"?</span></span></div><div id="divtagdefaultwrapper" dir="ltr" class="" style="font-size: 11pt; font-family: Calibri, Helvetica, sans-serif, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols;"><span class=""><span class=""><br class=""></span></span></div><div id="divtagdefaultwrapper" dir="ltr" class="" style="font-size: 11pt; font-family: Calibri, Helvetica, sans-serif, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols;">Cheers</div><div id="divtagdefaultwrapper" dir="ltr" class="" style="font-size: 11pt; font-family: Calibri, Helvetica, sans-serif, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols;"><span class="" style="font-size: 11pt;">Dave</span><br class=""></div><div id="divtagdefaultwrapper" dir="ltr" class="" style="font-size: 11pt; font-family: Calibri, Helvetica, sans-serif, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols;"><br class=""><div class=""><div class=""><hr tabindex="-1" class="" style="display: inline-block; width: 774.1875px;"><div id="x_divRplyFwdMsg" dir="ltr" class=""><font face="Calibri, sans-serif" class="" style="font-size: 11pt;"><b class="">From:</b><span class="Apple-converted-space"> </span>llvm-commits <<a href="mailto:llvm-commits-bounces@lists.llvm.org" class="">llvm-commits-bounces@lists.llvm.org</a>> on behalf of Daniel Sanders via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>><br class=""><b class="">Sent:</b><span class="Apple-converted-space"> </span>27 June 2017 11:11<br class=""><b class="">To:</b><span class="Apple-converted-space"> </span><a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class=""><b class="">Subject:</b><span class="Apple-converted-space"> </span>[llvm] r306388 - [globalisel][tablegen] Add support for EXTRACT_SUBREG.</font><div class=""> </div></div></div><font size="2" class=""><span class="" style="font-size: 10pt;"><div class="PlainText">Author: dsanders<br class="">Date: Tue Jun 27 03:11:39 2017<br class="">New Revision: 306388<br class=""><br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project?rev=306388&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=306388&view=rev</a><br class="">Log:<br class="">[globalisel][tablegen] Add support for EXTRACT_SUBREG.<br class=""><br class="">Summary:<br class="">After this patch, we finally have test cases that require multiple<br class="">instruction emission.<br class=""><br class="">Depends on D33590<br class=""><br class="">Reviewers: ab, qcolombet, t.p.northover, rovka, kristof.beyls<br class=""><br class="">Subscribers: javed.absar, llvm-commits, igorb<br class=""><br class="">Differential Revision:<span class="Apple-converted-space"> </span><a href="https://reviews.llvm.org/D33596" class="">https://reviews.llvm.org/D33596</a><br class=""><br class="">Modified:<br class="">    llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp<br class="">    llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-trunc.mir<br class="">    llvm/trunk/utils/TableGen/CodeGenRegisters.cpp<br class="">    llvm/trunk/utils/TableGen/CodeGenRegisters.h<br class="">    llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp<br class=""><br class="">Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=306388&r1=306387&r2=306388&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=306388&r1=306387&r2=306388&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)<br class="">+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Tue Jun 27 03:11:39 2017<br class="">@@ -947,7 +947,7 @@ bool AArch64InstructionSelector::select(<br class="">     const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);<br class=""> <br class="">     if (DstRB.getID() != SrcRB.getID()) {<br class="">-      DEBUG(dbgs() << "G_TRUNC input/output on different banks\n");<br class="">+      DEBUG(dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n");<br class="">       return false;<br class="">     }<br class=""> <br class="">@@ -964,16 +964,21 @@ bool AArch64InstructionSelector::select(<br class=""> <br class="">       if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||<br class="">           !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {<br class="">-        DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");<br class="">+        DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n");<br class="">         return false;<br class="">       }<br class=""> <br class="">       if (DstRC == SrcRC) {<br class="">         // Nothing to be done<br class="">+      } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) &&<br class="">+                 SrcTy == LLT::scalar(64)) {<br class="">+        llvm_unreachable("TableGen can import this case");<br class="">+        return false;<br class="">       } else if (DstRC == &AArch64::GPR32RegClass &&<br class="">                  SrcRC == &AArch64::GPR64RegClass) {<br class="">         I.getOperand(1).setSubReg(AArch64::sub_32);<br class="">       } else {<br class="">+        DEBUG(dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n");<br class="">         return false;<br class="">       }<br class=""> <br class=""><br class="">Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-trunc.mir<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-trunc.mir?rev=306388&r1=306387&r2=306388&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-trunc.mir?rev=306388&r1=306387&r2=306388&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-trunc.mir (original)<br class="">+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-trunc.mir Tue Jun 27 03:11:39 2017<br class="">@@ -15,8 +15,8 @@ legalized:       true<br class=""> regBankSelected: true<br class=""> <br class=""> # CHECK:      registers:<br class="">-# CHECK-NEXT:  - { id: 0, class: gpr64, preferred-register: '' }<br class="">-# CHECK-NEXT:  - { id: 1, class: gpr32, preferred-register: '' }<br class="">+# CHECK-NEXT:  - { id: 0, class: gpr64sp, preferred-register: '' }<br class="">+# CHECK-NEXT:  - { id: 1, class: gpr32sp, preferred-register: '' }<br class=""> registers:<br class="">   - { id: 0, class: gpr }<br class="">   - { id: 1, class: gpr }<br class=""><br class="">Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.cpp?rev=306388&r1=306387&r2=306388&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.cpp?rev=306388&r1=306387&r2=306388&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/utils/TableGen/CodeGenRegisters.cpp (original)<br class="">+++ llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Tue Jun 27 03:11:39 2017<br class="">@@ -915,6 +915,84 @@ void CodeGenRegisterClass::computeSubCla<br class="">       RC.inheritProperties(RegBank);<br class=""> }<br class=""> <br class="">+Optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>><br class="">+CodeGenRegisterClass::getMatchingSubClassWithSubRegs(<br class="">+    CodeGenRegBank &RegBank, const CodeGenSubRegIndex *SubIdx) const {<br class="">+  auto SizeOrder = [](const CodeGenRegisterClass *A,<br class="">+                      const CodeGenRegisterClass *B) {<br class="">+    return A->getMembers().size() >= B->getMembers().size();<br class="">+  };<br class="">+<br class="">+  auto &RegClasses = RegBank.getRegClasses();<br class="">+<br class="">+  // Find all the subclasses of this one that fully support the sub-register<br class="">+  // index and order them by size. BiggestSuperRC should always be first.<br class="">+  CodeGenRegisterClass *BiggestSuperRegRC = getSubClassWithSubReg(SubIdx);<br class="">+  if (!BiggestSuperRegRC)<br class="">+    return None;<br class="">+  BitVector SuperRegRCsBV = BiggestSuperRegRC->getSubClasses();<br class="">+  std::vector<CodeGenRegisterClass *> SuperRegRCs;<br class="">+  for (auto &RC : RegClasses)<br class="">+    if (SuperRegRCsBV[RC.EnumValue])<br class="">+      SuperRegRCs.emplace_back(&RC);<br class="">+  std::sort(SuperRegRCs.begin(), SuperRegRCs.end(), SizeOrder);<br class="">+  assert(SuperRegRCs.front() == BiggestSuperRegRC && "Biggest class wasn't first");<br class="">+<br class="">+  // Find all the subreg classes and order them by size too.<br class="">+  std::vector<std::pair<CodeGenRegisterClass *, BitVector>> SuperRegClasses;<br class="">+  for (auto &RC: RegClasses) {<br class="">+    BitVector SuperRegClassesBV(RegClasses.size());<br class="">+    RC.getSuperRegClasses(SubIdx, SuperRegClassesBV);<br class="">+    if (SuperRegClassesBV.any())<br class="">+      SuperRegClasses.push_back(std::make_pair(&RC, SuperRegClassesBV));<br class="">+  }<br class="">+  std::sort(SuperRegClasses.begin(), SuperRegClasses.end(),<br class="">+            [&](const std::pair<CodeGenRegisterClass *, BitVector> &A,<br class="">+                const std::pair<CodeGenRegisterClass *, BitVector> &B) {<br class="">+              return SizeOrder(A.first, B.first);<br class="">+            });<br class="">+<br class="">+  // Find the biggest subclass and subreg class such that R:subidx is in the<br class="">+  // subreg class for all R in subclass.<br class="">+  //<br class="">+  // For example:<br class="">+  // All registers in X86's GR64 have a sub_32bit subregister but no class<br class="">+  // exists that contains all the 32-bit subregisters because GR64 contains RIP<br class="">+  // but GR32 does not contain EIP. Instead, we constrain SuperRegRC to<br class="">+  // GR32_with_sub_8bit (which is identical to GR32_with_sub_32bit) and then,<br class="">+  // having excluded RIP, we are able to find a SubRegRC (GR32).<br class="">+  CodeGenRegisterClass *ChosenSuperRegClass = nullptr;<br class="">+  CodeGenRegisterClass *SubRegRC = nullptr;<br class="">+  for (auto *SuperRegRC : SuperRegRCs) {<br class="">+    for (const auto &SuperRegClassPair : SuperRegClasses) {<br class="">+      const BitVector &SuperRegClassBV = SuperRegClassPair.second;<br class="">+      if (SuperRegClassBV[SuperRegRC->EnumValue]) {<br class="">+        SubRegRC = SuperRegClassPair.first;<br class="">+        ChosenSuperRegClass = SuperRegRC;<br class="">+<br class="">+        // If SubRegRC is bigger than SuperRegRC then there are members of<br class="">+        // SubRegRC that don't have super registers via SubIdx. Keep looking to<br class="">+        // find a better fit and fall back on this one if there isn't one.<br class="">+        //<br class="">+        // This is intended to prevent X86 from making odd choices such as<br class="">+        // picking LOW32_ADDR_ACCESS_RBP instead of GR32 in the example above.<br class="">+        // LOW32_ADDR_ACCESS_RBP is a valid choice but contains registers that<br class="">+        // aren't subregisters of SuperRegRC whereas GR32 has a direct 1:1<br class="">+        // mapping.<br class="">+        if (SuperRegRC->getMembers().size() >= SubRegRC->getMembers().size())<br class="">+          return std::make_pair(ChosenSuperRegClass, SubRegRC);<br class="">+      }<br class="">+    }<br class="">+<br class="">+    // If we found a fit but it wasn't quite ideal because SubRegRC had excess<br class="">+    // registers, then we're done.<br class="">+    if (ChosenSuperRegClass)<br class="">+      return std::make_pair(ChosenSuperRegClass, SubRegRC);<br class="">+  }<br class="">+<br class="">+  return None;<br class="">+}<br class="">+<br class=""> void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,<br class="">                                               BitVector &Out) const {<br class="">   auto FindI = SuperRegClasses.find(SubIdx);<br class=""><br class="">Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.h<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.h?rev=306388&r1=306387&r2=306388&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.h?rev=306388&r1=306387&r2=306388&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/utils/TableGen/CodeGenRegisters.h (original)<br class="">+++ llvm/trunk/utils/TableGen/CodeGenRegisters.h Tue Jun 27 03:11:39 2017<br class="">@@ -329,6 +329,9 @@ namespace llvm {<br class="">     const std::string &getName() const { return Name; }<br class="">     std::string getQualifiedName() const;<br class="">     ArrayRef<MVT::SimpleValueType> getValueTypes() const {return VTs;}<br class="">+    bool hasValueType(MVT::SimpleValueType VT) const {<br class="">+      return std::find(VTs.begin(), VTs.end(), VT) != VTs.end();<br class="">+    }<br class="">     unsigned getNumValueTypes() const { return VTs.size(); }<br class=""> <br class="">     MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const {<br class="">@@ -360,6 +363,18 @@ namespace llvm {<br class="">       return SubClassWithSubReg.lookup(SubIdx);<br class="">     }<br class=""> <br class="">+    /// Find largest subclass where all registers have SubIdx subregisters in<br class="">+    /// SubRegClass and the largest subregister class that contains those<br class="">+    /// subregisters without (as far as possible) also containing additional registers.<br class="">+    ///<br class="">+    /// This can be used to find a suitable pair of classes for subregister copies.<br class="">+    /// \return std::pair<SubClass, SubRegClass> where SubClass is a SubClass is<br class="">+    /// a class where every register has SubIdx and SubRegClass is a class where<br class="">+    /// every register is covered by the SubIdx subregister of SubClass.<br class="">+    Optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>><br class="">+    getMatchingSubClassWithSubRegs(CodeGenRegBank &RegBank,<br class="">+                                   const CodeGenSubRegIndex *SubIdx) const;<br class="">+<br class="">     void setSubClassWithSubReg(const CodeGenSubRegIndex *SubIdx,<br class="">                                CodeGenRegisterClass *SubRC) {<br class="">       SubClassWithSubReg[SubIdx] = SubRC;<br class="">@@ -370,7 +385,7 @@ namespace llvm {<br class="">     void getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,<br class="">                             BitVector &Out) const;<br class=""> <br class="">-    // addSuperRegClass - Add a class containing only SudIdx super-registers.<br class="">+    // addSuperRegClass - Add a class containing only SubIdx super-registers.<br class="">     void addSuperRegClass(CodeGenSubRegIndex *SubIdx,<br class="">                           CodeGenRegisterClass *SuperRC) {<br class="">       SuperRegClasses[SubIdx].insert(SuperRC);<br class=""><br class="">Modified: llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=306388&r1=306387&r2=306388&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=306388&r1=306387&r2=306388&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp (original)<br class="">+++ llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp Tue Jun 27 03:11:39 2017<br class="">@@ -832,7 +832,13 @@ public:<br class=""> //===- Actions ------------------------------------------------------------===//<br class=""> class OperandRenderer {<br class=""> public:<br class="">-  enum RendererKind { OR_Copy, OR_Imm, OR_Register, OR_ComplexPattern };<br class="">+  enum RendererKind {<br class="">+    OR_Copy,<br class="">+    OR_CopySubReg,<br class="">+    OR_Imm,<br class="">+    OR_Register,<br class="">+    OR_ComplexPattern<br class="">+  };<br class=""> <br class=""> protected:<br class="">   RendererKind Kind;<br class="">@@ -877,6 +883,42 @@ public:<br class="">   }<br class=""> };<br class=""> <br class="">+/// A CopySubRegRenderer emits code to copy a single register operand from an<br class="">+/// existing instruction to the one being built and indicate that only a<br class="">+/// subregister should be copied.<br class="">+class CopySubRegRenderer : public OperandRenderer {<br class="">+protected:<br class="">+  /// The matcher for the instruction that this operand is copied from.<br class="">+  /// This provides the facility for looking up an a operand by it's name so<br class="">+  /// that it can be used as a source for the instruction being built.<br class="">+  const InstructionMatcher &Matched;<br class="">+  /// The name of the operand.<br class="">+  const StringRef SymbolicName;<br class="">+  /// The subregister to extract.<br class="">+  const CodeGenSubRegIndex *SubReg;<br class="">+<br class="">+public:<br class="">+  CopySubRegRenderer(const InstructionMatcher &Matched, StringRef SymbolicName,<br class="">+                     const CodeGenSubRegIndex *SubReg)<br class="">+      : OperandRenderer(OR_CopySubReg), Matched(Matched),<br class="">+        SymbolicName(SymbolicName), SubReg(SubReg) {}<br class="">+<br class="">+  static bool classof(const OperandRenderer *R) {<br class="">+    return R->getKind() == OR_CopySubReg;<br class="">+  }<br class="">+<br class="">+  const StringRef getSymbolicName() const { return SymbolicName; }<br class="">+<br class="">+  void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {<br class="">+    const OperandMatcher &Operand = Matched.getOperand(SymbolicName);<br class="">+    StringRef InsnVarName =<br class="">+        Rule.getInsnVarName(Operand.getInstructionMatcher());<br class="">+    std::string OperandExpr = Operand.getOperandExpr(InsnVarName);<br class="">+    OS << "    MIB.addReg(" << OperandExpr << ".getReg() /*" << SymbolicName<br class="">+       << "*/, 0, " << SubReg->EnumValue << ");\n";<br class="">+  }<br class="">+};<br class="">+<br class=""> /// Adds a specific physical register to the instruction being built.<br class=""> /// This is typically useful for WZR/XZR on AArch64.<br class=""> class AddRegisterRenderer : public OperandRenderer {<br class="">@@ -1292,6 +1334,7 @@ private:<br class="">   const RecordKeeper &RK;<br class="">   const CodeGenDAGPatterns CGP;<br class="">   const CodeGenTarget &Target;<br class="">+  CodeGenRegBank CGRegs;<br class=""> <br class="">   /// Keep track of the equivalence between SDNodes and Instruction.<br class="">   /// This is defined using 'GINodeEquiv' in the target description.<br class="">@@ -1315,9 +1358,9 @@ private:<br class="">   Error importChildMatcher(InstructionMatcher &InsnMatcher,<br class="">                            const TreePatternNode *SrcChild, unsigned OpIdx,<br class="">                            unsigned &TempOpIdx) const;<br class="">-  Expected<BuildMIAction &> createAndImportInstructionRenderer(<br class="">-      RuleMatcher &M, const TreePatternNode *Dst,<br class="">-      const InstructionMatcher &InsnMatcher) const;<br class="">+  Expected<BuildMIAction &><br class="">+  createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst,<br class="">+                                     const InstructionMatcher &InsnMatcher);<br class="">   Error importExplicitUseRenderer(BuildMIAction &DstMIBuilder,<br class="">                                   TreePatternNode *DstChild,<br class="">                                   const InstructionMatcher &InsnMatcher) const;<br class="">@@ -1354,7 +1397,7 @@ const CodeGenInstruction *GlobalISelEmit<br class=""> }<br class=""> <br class=""> GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)<br class="">-    : RK(RK), CGP(RK), Target(CGP.getTargetInfo()) {}<br class="">+    : RK(RK), CGP(RK), Target(CGP.getTargetInfo()), CGRegs(RK) {}<br class=""> <br class=""> //===- Emitter ------------------------------------------------------------===//<br class=""> <br class="">@@ -1585,7 +1628,7 @@ Error GlobalISelEmitter::importExplicitU<br class=""> <br class=""> Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(<br class="">     RuleMatcher &M, const TreePatternNode *Dst,<br class="">-    const InstructionMatcher &InsnMatcher) const {<br class="">+    const InstructionMatcher &InsnMatcher) {<br class="">   Record *DstOp = Dst->getOperator();<br class="">   if (!DstOp->isSubClassOf("Instruction")) {<br class="">     if (DstOp->isSubClassOf("ValueType"))<br class="">@@ -1597,13 +1640,17 @@ Expected<BuildMIAction &> GlobalISelEmit<br class=""> <br class="">   unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs;<br class="">   unsigned ExpectedDstINumUses = Dst->getNumChildren();<br class="">+  bool IsExtractSubReg = false;<br class=""> <br class="">   // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction<br class="">-  // attached.<br class="">+  // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.<br class="">   if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") {<br class="">     DstI = &Target.getInstruction(RK.getDef("COPY"));<br class="">     DstINumUses--; // Ignore the class constraint.<br class="">     ExpectedDstINumUses--;<br class="">+  } else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") {<br class="">+    DstI = &Target.getInstruction(RK.getDef("COPY"));<br class="">+    IsExtractSubReg = true;<br class="">   }<br class=""> <br class="">   auto &DstMIBuilder = M.addAction<BuildMIAction>("NewI", DstI, InsnMatcher);<br class="">@@ -1614,6 +1661,32 @@ Expected<BuildMIAction &> GlobalISelEmit<br class="">     DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, DstIOperand.Name);<br class="">   }<br class=""> <br class="">+  // EXTRACT_SUBREG needs to use a subregister COPY.<br class="">+  if (IsExtractSubReg) {<br class="">+    if (!Dst->getChild(0)->isLeaf())<br class="">+      return failedImport("EXTRACT_SUBREG child #1 is not a leaf");<br class="">+<br class="">+    if (DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {<br class="">+      CodeGenRegisterClass *RC = CGRegs.getRegClass(<br class="">+          getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()));<br class="">+      CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());<br class="">+<br class="">+      const auto &SrcRCDstRCPair =<br class="">+          RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);<br class="">+      if (SrcRCDstRCPair.hasValue()) {<br class="">+        assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");<br class="">+        if (SrcRCDstRCPair->first != RC)<br class="">+          return failedImport("EXTRACT_SUBREG requires an additional COPY");<br class="">+      }<br class="">+<br class="">+      DstMIBuilder.addRenderer<CopySubRegRenderer>(<br class="">+          InsnMatcher, Dst->getChild(0)->getName(), SubIdx);<br class="">+      return DstMIBuilder;<br class="">+    }<br class="">+<br class="">+    return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");<br class="">+  }<br class="">+<br class="">   // Render the explicit uses.<br class="">   unsigned Child = 0;<br class="">   unsigned NumDefaultOps = 0;<br class="">@@ -1740,6 +1813,16 @@ Expected<RuleMatcher> GlobalISelEmitter:<br class="">       if (DstIOpRec == nullptr)<br class="">         return failedImport(<br class="">             "COPY_TO_REGCLASS operand #1 isn't a register class");<br class="">+    } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {<br class="">+      if (!Dst->getChild(0)->isLeaf())<br class="">+        return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");<br class="">+<br class="">+      // We can assume that a subregister is in the same bank as it's super register.<br class="">+      DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());<br class="">+<br class="">+      if (DstIOpRec == nullptr)<br class="">+        return failedImport(<br class="">+            "EXTRACT_SUBREG operand #0 isn't a register class");<br class="">     } else if (DstIOpRec->isSubClassOf("RegisterOperand"))<br class="">       DstIOpRec = DstIOpRec->getValueAsDef("RegClass");<br class="">     else if (!DstIOpRec->isSubClassOf("RegisterClass"))<br class="">@@ -1776,8 +1859,58 @@ Expected<RuleMatcher> GlobalISelEmitter:<br class=""> <br class="">     M.addAction<ConstrainOperandToRegClassAction>(<br class="">         "NewI", 0, Target.getRegisterClass(DstIOpRec));<br class="">-  } else<br class="">-    M.addAction<ConstrainOperandsToDefinitionAction>("NewI");<br class="">+<br class="">+    // We're done with this pattern!  It's eligible for GISel emission; return<br class="">+    // it.<br class="">+    ++NumPatternImported;<br class="">+    return std::move(M);<br class="">+  }<br class="">+<br class="">+  if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {<br class="">+    // EXTRACT_SUBREG selects into a subregister COPY but unlike most<br class="">+    // instructions, the result register class is controlled by the<br class="">+    // subregisters of the operand. As a result, we must constrain the result<br class="">+    // class rather than check that it's already the right one.<br class="">+    if (!Dst->getChild(0)->isLeaf())<br class="">+      return failedImport("EXTRACT_SUBREG child #1 is not a leaf");<br class="">+<br class="">+    if (DefInit *SubRegInit =<br class="">+            dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {<br class="">+      // Constrain the result to the same register bank as the operand.<br class="">+      Record *DstIOpRec =<br class="">+          getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());<br class="">+<br class="">+      if (DstIOpRec == nullptr)<br class="">+        return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");<br class="">+<br class="">+      CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());<br class="">+      CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(<br class="">+          getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()));<br class="">+<br class="">+      // It would be nice to leave this constraint implicit but we're required<br class="">+      // to pick a register class so constrain the result to a register class<br class="">+      // that can hold the correct MVT.<br class="">+      //<br class="">+      // FIXME: This may introduce an extra copy if the chosen class doesn't<br class="">+      //        actually contain the subregisters.<br class="">+      assert(Src->getExtTypes().size() == 1);<br class="">+<br class="">+      const auto &SrcRCDstRCPair =<br class="">+          SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);<br class="">+      assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");<br class="">+      M.addAction<ConstrainOperandToRegClassAction>("NewI", 0, *SrcRCDstRCPair->second);<br class="">+      M.addAction<ConstrainOperandToRegClassAction>("NewI", 1, *SrcRCDstRCPair->first);<br class="">+<br class="">+      // We're done with this pattern!  It's eligible for GISel emission; return<br class="">+      // it.<br class="">+      ++NumPatternImported;<br class="">+      return std::move(M);<br class="">+    }<br class="">+<br class="">+    return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");<br class="">+  }<br class="">+<br class="">+  M.addAction<ConstrainOperandsToDefinitionAction>("NewI");<br class=""> <br class="">   // We're done with this pattern!  It's eligible for GISel emission; return it.<br class="">   ++NumPatternImported;<br class=""><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a></div></span></font></div></div></div></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a></div></blockquote></div></div></div></blockquote></div><br class=""></body></html>