<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">
Good to hear the porting wasn’t difficult. :)
<div class="">Ultimately, I don’t think it makes much sense to keep on supporting 2 APIs, and with the main users of GlobalISel ported over to the new API, I think there’s even less reason to try and support the old API, which has fundamental problems with
 not supporting non-power-of-2-sized-types.</div>
<div class=""><br class="">
<div>
<blockquote type="cite" class="">
<div class="">On 8 Nov 2017, at 19:49, Puyan Lotfi <<a href="mailto:puyan.lotfi.llvm@gmail.com" class="">puyan.lotfi.llvm@gmail.com</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div dir="ltr" class="">
<div class="">We've done our porting, so everything is ok now. You're right it wasn't that difficult.</div>
<div class="">I was just curious if there could be a way to make legalization like this optional in the future, but I understand if its too core a part of GISel to opt out of.<br class="">
</div>
<div class=""><br class="">
</div>
<div class="">PL<br class="">
</div>
</div>
<div class="gmail_extra"><br class="">
<div class="gmail_quote">On Wed, Nov 8, 2017 at 10:33 AM, Kristof Beyls <span dir="ltr" class="">
<<a href="mailto:Kristof.Beyls@arm.com" target="_blank" class="">Kristof.Beyls@arm.com</a>></span> wrote:<br class="">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word" class="">Hi Puyan,
<div class=""><br class="">
</div>
<div class="">Given this changes the core of GlobalISel legalization, I don’t think there is a straightforward way to support both the old API and the new API.</div>
<div class="">FWIW, the target-specific diff in the open source backends isn’t that big, and I didn’t find it too hard to move over the open source backends.</div>
<div class="">So I’d expect that it shouldn’t be too hard to port your out-of-tree backend to this new API too. I hope that the diffs for the 4 existing open source backends should give you enough examples of how your backend could be ported over?</div>
<div class=""><br class="">
</div>
<div class="">Thanks,</div>
<div class=""><br class="">
</div>
<div class="">Kristof</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
<div class="">
<blockquote type="cite" class="">
<div class="">On 8 Nov 2017, at 19:16, Puyan Lotfi <<a href="mailto:puyan.lotfi.llvm@gmail.com" target="_blank" class="">puyan.lotfi.llvm@gmail.com</a>> wrote:</div>
<br class="m_833714972736334896Apple-interchange-newline">
<div class="">
<div dir="ltr" class="">
<div class="">I have a question: Could there be a way for this legalization to be deployed in a way so that the individual targets can opt out?</div>
<div class=""><br class="">
</div>
<div class="">The legalization code for the open source targets seems non-trivial and out of tree targets that aren't doing the legalization yet will break.<br class="">
</div>
<div class="">Would be nice if there were a way to still be up to date on the latest top of tree without implementing the legalization while not breaking.<br class="">
</div>
<div class=""><br class="">
</div>
<div class="">PL<br class="">
</div>
<div class=""><br class="">
</div>
</div>
<div class="gmail_extra"><br class="">
<div class="gmail_quote">On Wed, Nov 8, 2017 at 8:38 AM, Kristof Beyls via llvm-commits
<span dir="ltr" class=""><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a>></span> wrote:<br class="">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="">
> On 7 Nov 2017, at 19:05, Amara Emerson <<a href="mailto:aemerson@apple.com" target="_blank" class="">aemerson@apple.com</a>> wrote:<br class="">
><br class="">
> Thanks Kristof, nice to see this go in. We have a non power of 2 section in the GISel docs (<a href="https://llvm.org/docs/GlobalISel.html#non-power-of-2-types" rel="noreferrer" target="_blank" class="">https://llvm.org/docs/GlobalI<wbr class="">Sel.html#non-power-of-2-types</a>)
 that need expanding, could you update that when you get a chance? Looks like this commit message is a good explanation.<br class="">
><br class="">
> Cheers,<br class="">
> Amara<br class="">
<br class="">
Thanks for the suggestion, Amara.<br class="">
I was planning to do that and am hoping to find a bit of time in the next couple of days for it.<br class="">
<br class="">
>> On 7 Nov 2017, at 10:34, Kristof Beyls via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a>> wrote:<br class="">
>><br class="">
>> Author: kbeyls<br class="">
>> Date: Tue Nov  7 02:34:34 2017<br class="">
>> New Revision: 317560<br class="">
>><br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=317560&view=rev" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject?rev=317560&view=rev</a><br class="">
>> Log:<br class="">
>> [GlobalISel] Enable legalizing non-power-of-2 sized types.<br class="">
>><br class="">
>> This changes the interface of how targets describe how to legalize, see<br class="">
>> the below description.<br class="">
>><br class="">
>> 1. Interface for targets to describe how to legalize.<br class="">
>><br class="">
>> In GlobalISel, the API in the LegalizerInfo class is the main interface<br class="">
>> for targets to specify which types are legal for which operations, and<br class="">
>> what to do to turn illegal type/operation combinations into legal ones.<br class="">
>><br class="">
>> For each operation the type sizes that can be legalized without having<br class="">
>> to change the size of the type are specified with a call to setAction.<br class="">
>> This isn't different to how GlobalISel worked before. For example, for a<br class="">
>> target that supports 32 and 64 bit adds natively:<br class="">
>><br class="">
>> for (auto Ty : {s32, s64})<br class="">
>>   setAction({G_ADD, 0, s32}, Legal);<br class="">
>><br class="">
>> or for a target that needs a library call for a 32 bit division:<br class="">
>><br class="">
>> setAction({G_SDIV, s32}, Libcall);<br class="">
>><br class="">
>> The main conceptual change to the LegalizerInfo API, is in specifying<br class="">
>> how to legalize the type sizes for which a change of size is needed. For<br class="">
>> example, in the above example, how to specify how all types from i1 to<br class="">
>> i8388607 (apart from s32 and s64 which are legal) need to be legalized<br class="">
>> and expressed in terms of operations on the available legal sizes<br class="">
>> (again, i32 and i64 in this case). Before, the implementation only<br class="">
>> allowed specifying power-of-2-sized types (e.g. setAction({G_ADD, 0,<br class="">
>> s128}, NarrowScalar).  A worse limitation was that if you'd wanted to<br class="">
>> specify how to legalize all the sized types as allowed by the LLVM-IR<br class="">
>> LangRef, i1 to i8388607, you'd have to call setAction 8388607-3 times<br class="">
>> and probably would need a lot of memory to store all of these<br class="">
>> specifications.<br class="">
>><br class="">
>> Instead, the legalization actions that need to change the size of the<br class="">
>> type are specified now using a "SizeChangeStrategy".  For example:<br class="">
>><br class="">
>>  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>>      G_ADD, 0, widenToLargerAndNarrowToLarges<wbr class="">t);<br class="">
>><br class="">
>> This example indicates that for type sizes for which there is a larger<br class="">
>> size that can be legalized towards, do it by Widening the size.<br class="">
>> For example, G_ADD on s17 will be legalized by first doing WidenScalar<br class="">
>> to make it s32, after which it's legal.<br class="">
>> The "NarrowToLargest" indicates what to do if there is no larger size<br class="">
>> that can be legalized towards. E.g. G_ADD on s92 will be legalized by<br class="">
>> doing NarrowScalar to s64.<br class="">
>><br class="">
>> Another example, taken from the ARM backend is:<br class="">
>>  for (unsigned Op : {G_SDIV, G_UDIV}) {<br class="">
>>    setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(Op, 0,<br class="">
>>        widenToLargerTypesUnsupportedO<wbr class="">therwise);<br class="">
>>    if (ST.hasDivideInARMMode())<br class="">
>>      setAction({Op, s32}, Legal);<br class="">
>>    else<br class="">
>>      setAction({Op, s32}, Libcall);<br class="">
>>  }<br class="">
>><br class="">
>> For this example, G_SDIV on s8, on a target without a divide<br class="">
>> instruction, would be legalized by first doing action (WidenScalar,<br class="">
>> s32), followed by (Libcall, s32).<br class="">
>><br class="">
>> The same principle is also followed for when the number of vector lanes<br class="">
>> on vector data types need to be changed, e.g.:<br class="">
>><br class="">
>>  setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal);<br class="">
>>  setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal);<br class="">
>>  setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal);<br class="">
>>  setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal);<br class="">
>>  setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal);<br class="">
>>  setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal);<br class="">
>>  setLegalizeVectorElementToDiff<wbr class="">erentSizeStrategy(<br class="">
>>      G_ADD, 0, widenToLargerTypesUnsupportedO<wbr class="">therwise);<br class="">
>><br class="">
>> As currently implemented here, vector types are legalized by first<br class="">
>> making the vector element size legal, followed by then making the number<br class="">
>> of lanes legal. The strategy to follow in the first step is set by a<br class="">
>> call to setLegalizeVectorElementToDiff<wbr class="">erentSizeStrategy, see example<br class="">
>> above.  The strategy followed in the second step<br class="">
>> "moreToWiderTypesAndLessToWide<wbr class="">st" (see code for its definition),<br class="">
>> indicating that vectors are widened to more elements so they map to<br class="">
>> natively supported vector widths, or when there isn't a legal wider<br class="">
>> vector, split the vector to map it to the widest vector supported.<br class="">
>><br class="">
>> Therefore, for the above specification, some example legalizations are:<br class="">
>> * getAction({G_ADD, LLT::vector(3, 3)})<br class="">
>>   returns {WidenScalar, LLT::vector(3, 8)}<br class="">
>> * getAction({G_ADD, LLT::vector(3, 8)})<br class="">
>>   then returns {MoreElements, LLT::vector(8, 8)}<br class="">
>> * getAction({G_ADD, LLT::vector(20, 8)})<br class="">
>>   returns {FewerElements, LLT::vector(16, 8)}<br class="">
>><br class="">
>><br class="">
>> 2. Key implementation aspects.<br class="">
>><br class="">
>> How to legalize a specific (operation, type index, size) tuple is<br class="">
>> represented by mapping intervals of integers representing a range of<br class="">
>> size types to an action to take, e.g.:<br class="">
>><br class="">
>>      setScalarAction({G_ADD, LLT:scalar(1)},<br class="">
>>                      {{1, WidenScalar},  // bit sizes [ 1, 31[<br class="">
>>                       {32, Legal},       // bit sizes [32, 33[<br class="">
>>                       {33, WidenScalar}, // bit sizes [33, 64[<br class="">
>>                       {64, Legal},       // bit sizes [64, 65[<br class="">
>>                       {65, NarrowScalar} // bit sizes [65, +inf[<br class="">
>>                      });<br class="">
>><br class="">
>> Please note that most of the code to do the actual lowering of<br class="">
>> non-power-of-2 sized types is currently missing, this is just trying to<br class="">
>> make it possible for targets to specify what is legal, and how non-legal<br class="">
>> types should be legalized.  Probably quite a bit of further work is<br class="">
>> needed in the actual legalizing and the other passes in GlobalISel to<br class="">
>> support non-power-of-2 sized types.<br class="">
>><br class="">
>> I hope the documentation in LegalizerInfo.h and the examples provided in the<br class="">
>> various {Target}LegalizerInfo.cpp and LegalizerInfoTest.cpp explains well<br class="">
>> enough how this is meant to be used.<br class="">
>><br class="">
>> This drops the need for LLT::{half,double}...Size().<br class="">
>><br class="">
>><br class="">
>> Differential Revision: <a href="https://reviews.llvm.org/D30529" rel="noreferrer" target="_blank" class="">
https://reviews.llvm.org/D3052<wbr class="">9</a><br class="">
>><br class="">
>><br class="">
>> Modified:<br class="">
>>   llvm/trunk/include/llvm/CodeG<wbr class="">en/GlobalISel/LegalizerInfo.h<br class="">
>>   llvm/trunk/include/llvm/Suppo<wbr class="">rt/LowLevelTypeImpl.h<br class="">
>>   llvm/trunk/lib/CodeGen/Global<wbr class="">ISel/LegalizerHelper.cpp<br class="">
>>   llvm/trunk/lib/CodeGen/Global<wbr class="">ISel/LegalizerInfo.cpp<br class="">
>>   llvm/trunk/lib/Support/LowLev<wbr class="">elType.cpp<br class="">
>>   llvm/trunk/lib/Target/<wbr class="">AArch64/AArch64LegalizerInfo.<wbr class="">cpp<br class="">
>>   llvm/trunk/lib/Target/ARM/ARM<wbr class="">LegalizerInfo.cpp<br class="">
>>   llvm/trunk/lib/Target/X86/X86<wbr class="">LegalizerInfo.cpp<br class="">
>>   llvm/trunk/test/CodeGen/AArch<wbr class="">64/GlobalISel/arm64-fallback.<wbr class="">ll<br class="">
>>   llvm/trunk/test/CodeGen/AArch<wbr class="">64/GlobalISel/legalize-add.mir<br class="">
>>   llvm/trunk/test/CodeGen/AArch<wbr class="">64/GlobalISel/legalize-inserts<wbr class="">.mir<br class="">
>>   llvm/trunk/test/CodeGen/ARM/G<wbr class="">lobalISel/arm-instruction-sele<wbr class="">ct.mir<br class="">
>>   llvm/trunk/unittests/CodeGen/<wbr class="">GlobalISel/LegalizerInfoTest.c<wbr class="">pp<br class="">
>>   llvm/trunk/unittests/CodeGen/<wbr class="">LowLevelTypeTest.cpp<br class="">
>><br class="">
>> Modified: llvm/trunk/include/llvm/CodeGe<wbr class="">n/GlobalISel/LegalizerInfo.h<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/include/llvm/<wbr class="">CodeGen/GlobalISel/LegalizerIn<wbr class="">fo.h?rev=317560&r1=317559&r2=<wbr class="">317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/include/llvm/CodeGe<wbr class="">n/GlobalISel/LegalizerInfo.h (original)<br class="">
>> +++ llvm/trunk/include/llvm/CodeGe<wbr class="">n/GlobalISel/LegalizerInfo.h Tue Nov  7 02:34:34 2017<br class="">
>> @@ -26,6 +26,7 @@<br class="">
>> #include <cassert><br class="">
>> #include <tuple><br class="">
>> #include <utility><br class="">
>> +#include <unordered_map><br class="">
>><br class="">
>> namespace llvm {<br class="">
>><br class="">
>> @@ -120,27 +121,144 @@ public:<br class="">
>>    }<br class="">
>>  }<br class="">
>><br class="">
>> +  typedef std::pair<uint16_t, LegalizeAction> SizeAndAction;<br class="">
>> +  typedef std::vector<SizeAndAction> SizeAndActionsVec;<br class="">
>> +  using SizeChangeStrategy =<br class="">
>> +      std::function<SizeAndActionsVe<wbr class="">c(const SizeAndActionsVec &v)>;<br class="">
>> +<br class="">
>>  /// More friendly way to set an action for common types that have an LLT<br class="">
>>  /// representation.<br class="">
>> +  /// The LegalizeAction must be one for which NeedsLegalizingToDifferentSize<br class="">
>> +  /// returns false.<br class="">
>>  void setAction(const InstrAspect &Aspect, LegalizeAction Action) {<br class="">
>> +    assert(!needsLegalizingToDiffe<wbr class="">rentSize(Action));<br class="">
>>    TablesInitialized = false;<br class="">
>> -    unsigned Opcode = Aspect.Opcode - FirstOp;<br class="">
>> -    if (Actions[Opcode].size() <= Aspect.Idx)<br class="">
>> -      Actions[Opcode].resize(Aspect.<wbr class="">Idx + 1);<br class="">
>> -    Actions[Aspect.Opcode - FirstOp][Aspect.Idx][Aspect.Ty<wbr class="">pe] = Action;<br class="">
>> +    const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;<br class="">
>> +    if (SpecifiedActions[OpcodeIdx].s<wbr class="">ize() <= Aspect.Idx)<br class="">
>> +      SpecifiedActions[OpcodeIdx].re<wbr class="">size(Aspect.Idx + 1);<br class="">
>> +    SpecifiedActions[OpcodeIdx][As<wbr class="">pect.Idx][Aspect.Type] = Action;<br class="">
>>  }<br class="">
>><br class="">
>> -  /// If an operation on a given vector type (say <M x iN>) isn't explicitly<br class="">
>> -  /// specified, we proceed in 2 stages. First we legalize the underlying scalar<br class="">
>> -  /// (so that there's at least one legal vector with that scalar), then we<br class="">
>> -  /// adjust the number of elements in the vector so that it is legal. The<br class="">
>> -  /// desired action in the first step is controlled by this function.<br class="">
>> -  void setScalarInVectorAction(unsign<wbr class="">ed Opcode, LLT ScalarTy,<br class="">
>> -                               LegalizeAction Action) {<br class="">
>> -    assert(!ScalarTy.isVector());<br class="">
>> -    ScalarInVectorActions[std::mak<wbr class="">e_pair(Opcode, ScalarTy)] = Action;<br class="">
>> +  /// The setAction calls record the non-size-changing legalization actions<br class="">
>> +  /// to take on specificly-sized types. The SizeChangeStrategy defines what<br class="">
>> +  /// to do when the size of the type needs to be changed to reach a legally<br class="">
>> +  /// sized type (i.e., one that was defined through a setAction call).<br class="">
>> +  /// e.g.<br class="">
>> +  /// setAction ({G_ADD, 0, LLT::scalar(32)}, Legal);<br class="">
>> +  /// setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +  ///   G_ADD, 0, widenToLargerTypesAndNarrowToL<wbr class="">argest);<br class="">
>> +  /// will end up defining getAction({G_ADD, 0, T}) to return the following<br class="">
>> +  /// actions for different scalar types T:<br class="">
>> +  ///  LLT::scalar(1)..LLT::scalar(31<wbr class="">): {WidenScalar, 0, LLT::scalar(32)}<br class="">
>> +  ///  LLT::scalar(32):                 {Legal, 0, LLT::scalar(32)}<br class="">
>> +  ///  LLT::scalar(33)..:               {NarrowScalar, 0, LLT::scalar(32)}<br class="">
>> +  ///<br class="">
>> +  /// If no SizeChangeAction gets defined, through this function,<br class="">
>> +  /// the default is unsupportedForDifferentSizes.<br class="">
>> +  void setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(const unsigned Opcode,<br class="">
>> +                                                const unsigned TypeIdx,<br class="">
>> +                                                SizeChangeStrategy S) {<br class="">
>> +    const unsigned OpcodeIdx = Opcode - FirstOp;<br class="">
>> +    if (ScalarSizeChangeStrategies[Op<wbr class="">codeIdx].size() <= TypeIdx)<br class="">
>> +      ScalarSizeChangeStrategies[Opc<wbr class="">odeIdx].resize(TypeIdx + 1);<br class="">
>> +    ScalarSizeChangeStrategies[Opc<wbr class="">odeIdx][TypeIdx] = S;<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  /// See also setLegalizeScalarToDifferentSi<wbr class="">zeStrategy.<br class="">
>> +  /// This function allows to set the SizeChangeStrategy for vector elements.<br class="">
>> +  void setLegalizeVectorElementToDiff<wbr class="">erentSizeStrategy(const unsigned Opcode,<br class="">
>> +                                                       const unsigned TypeIdx,<br class="">
>> +                                                       SizeChangeStrategy S) {<br class="">
>> +    const unsigned OpcodeIdx = Opcode - FirstOp;<br class="">
>> +    if (VectorElementSizeChangeStrate<wbr class="">gies[OpcodeIdx].size() <= TypeIdx)<br class="">
>> +      VectorElementSizeChangeStrateg<wbr class="">ies[OpcodeIdx].resize(TypeIdx + 1);<br class="">
>> +    VectorElementSizeChangeStrateg<wbr class="">ies[OpcodeIdx][TypeIdx] = S;<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  /// A SizeChangeStrategy for the common case where legalization for a<br class="">
>> +  /// particular operation consists of only supporting a specific set of type<br class="">
>> +  /// sizes. E.g.<br class="">
>> +  ///   setAction ({G_DIV, 0, LLT::scalar(32)}, Legal);<br class="">
>> +  ///   setAction ({G_DIV, 0, LLT::scalar(64)}, Legal);<br class="">
>> +  ///   <wbr class="">setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +  ///     G_DIV, 0, unsupportedForDifferentSizes);<br class="">
>> +  /// will result in getAction({G_DIV, 0, T}) to return Legal for s32 and s64,<br class="">
>> +  /// and Unsupported for all other scalar types T.<br class="">
>> +  static SizeAndActionsVec<br class="">
>> +  unsupportedForDifferentSizes(c<wbr class="">onst SizeAndActionsVec &v) {<br class="">
>> +    return increaseToLargerTypesAndDecrea<wbr class="">seToLargest(v, Unsupported,<br class="">
>> +                                                        Unsupported);<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  /// A SizeChangeStrategy for the common case where legalization for a<br class="">
>> +  /// particular operation consists of widening the type to a large legal type,<br class="">
>> +  /// unless there is no such type and then instead it should be narrowed to the<br class="">
>> +  /// largest legal type.<br class="">
>> +  static SizeAndActionsVec<br class="">
>> +  widenToLargerTypesAndNarrowToL<wbr class="">argest(const SizeAndActionsVec &v) {<br class="">
>> +    assert(v.size() > 0 &&<br class="">
>> +           "At least one size that can be legalized towards is needed"<br class="">
>> +           " for this SizeChangeStrategy");<br class="">
>> +    return increaseToLargerTypesAndDecrea<wbr class="">seToLargest(v, WidenScalar,<br class="">
>> +                                                        NarrowScalar);<br class="">
>>  }<br class="">
>><br class="">
>> +  static SizeAndActionsVec<br class="">
>> +  widenToLargerTypesUnsupportedO<wbr class="">therwise(const SizeAndActionsVec &v) {<br class="">
>> +    return increaseToLargerTypesAndDecrea<wbr class="">seToLargest(v, WidenScalar,<br class="">
>> +                                                        Unsupported);<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  static SizeAndActionsVec<br class="">
>> +  narrowToSmallerAndUnsupportedI<wbr class="">fTooSmall(const SizeAndActionsVec &v) {<br class="">
>> +    return decreaseToSmallerTypesAndIncre<wbr class="">aseToSmallest(v, NarrowScalar,<br class="">
>> +                                                          Unsupported);<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  static SizeAndActionsVec<br class="">
>> +  narrowToSmallerAndWidenToSmall<wbr class="">est(const SizeAndActionsVec &v) {<br class="">
>> +    assert(v.size() > 0 &&<br class="">
>> +           "At least one size that can be legalized towards is needed"<br class="">
>> +           " for this SizeChangeStrategy");<br class="">
>> +    return decreaseToSmallerTypesAndIncre<wbr class="">aseToSmallest(v, NarrowScalar,<br class="">
>> +                                                          WidenScalar);<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  /// A SizeChangeStrategy for the common case where legalization for a<br class="">
>> +  /// particular vector operation consists of having more elements in the<br class="">
>> +  /// vector, to a type that is legal. Unless there is no such type and then<br class="">
>> +  /// instead it should be legalized towards the widest vector that's still<br class="">
>> +  /// legal. E.g.<br class="">
>> +  ///   setAction({G_ADD, LLT::vector(8, 8)}, Legal);<br class="">
>> +  ///   setAction({G_ADD, LLT::vector(16, 8)}, Legal);<br class="">
>> +  ///   setAction({G_ADD, LLT::vector(2, 32)}, Legal);<br class="">
>> +  ///   setAction({G_ADD, LLT::vector(4, 32)}, Legal);<br class="">
>> +  ///   <wbr class="">setLegalizeVectorElementToDiff<wbr class="">erentSizeStrategy(<br class="">
>> +  ///     G_ADD, 0, moreToWiderTypesAndLessToWides<wbr class="">t);<br class="">
>> +  /// will result in the following getAction results:<br class="">
>> +  ///   * getAction({G_ADD, LLT::vector(8,8)}) returns<br class="">
>> +  ///       (Legal, vector(8,8)).<br class="">
>> +  ///   * getAction({G_ADD, LLT::vector(9,8)}) returns<br class="">
>> +  ///       (MoreElements, vector(16,8)).<br class="">
>> +  ///   * getAction({G_ADD, LLT::vector(8,32)}) returns<br class="">
>> +  ///       (FewerElements, vector(4,32)).<br class="">
>> +  static SizeAndActionsVec<br class="">
>> +  moreToWiderTypesAndLessToWides<wbr class="">t(const SizeAndActionsVec &v) {<br class="">
>> +    return increaseToLargerTypesAndDecrea<wbr class="">seToLargest(v, MoreElements,<br class="">
>> +                                                        FewerElements);<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  /// Helper function to implement many typical SizeChangeStrategy functions.<br class="">
>> +  static SizeAndActionsVec<br class="">
>> +  increaseToLargerTypesAndDecrea<wbr class="">seToLargest(const SizeAndActionsVec &v,<br class="">
>> +                                            LegalizeAction IncreaseAction,<br class="">
>> +                                            LegalizeAction DecreaseAction);<br class="">
>> +  /// Helper function to implement many typical SizeChangeStrategy functions.<br class="">
>> +  static SizeAndActionsVec<br class="">
>> +  decreaseToSmallerTypesAndIncre<wbr class="">aseToSmallest(const SizeAndActionsVec &v,<br class="">
>> +                                              LegalizeAction DecreaseAction,<br class="">
>> +                                              LegalizeAction IncreaseAction);<br class="">
>> +<br class="">
>>  /// Determine what action should be taken to legalize the given generic<br class="">
>>  /// instruction opcode, type-index and type. Requires computeTables to have<br class="">
>>  /// been called.<br class="">
>> @@ -158,58 +276,6 @@ public:<br class="">
>>  std::tuple<LegalizeAction, unsigned, LLT><br class="">
>>  getAction(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;<br class="">
>><br class="">
>> -  /// Iterate the given function (typically something like doubling the width)<br class="">
>> -  /// on Ty until we find a legal type for this operation.<br class="">
>> -  Optional<LLT> findLegalizableSize(const InstrAspect &Aspect,<br class="">
>> -                                    function_ref<LLT(LLT)> NextType) const {<br class="">
>> -    if (Aspect.Idx >= Actions[Aspect.Opcode - FirstOp].size())<br class="">
>> -      return None;<br class="">
>> -<br class="">
>> -    LegalizeAction Action;<br class="">
>> -    const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];<br class="">
>> -    LLT Ty = Aspect.Type;<br class="">
>> -    do {<br class="">
>> -      Ty = NextType(Ty);<br class="">
>> -      auto ActionIt = Map.find(Ty);<br class="">
>> -      if (ActionIt == Map.end()) {<br class="">
>> -        auto DefaultIt = DefaultActions.find(Aspect.Opc<wbr class="">ode);<br class="">
>> -        if (DefaultIt == DefaultActions.end())<br class="">
>> -          return None;<br class="">
>> -        Action = DefaultIt->second;<br class="">
>> -      } else<br class="">
>> -        Action = ActionIt->second;<br class="">
>> -    } while (needsLegalizingToDifferentSiz<wbr class="">e(Action));<br class="">
>> -    return Ty;<br class="">
>> -  }<br class="">
>> -<br class="">
>> -  /// Find what type it's actually OK to perform the given operation on, given<br class="">
>> -  /// the general approach we've decided to take.<br class="">
>> -  Optional<LLT> findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const;<br class="">
>> -<br class="">
>> -  std::pair<LegalizeAction, LLT> findLegalAction(const InstrAspect &Aspect,<br class="">
>> -                                                 LegalizeAction Action) const {<br class="">
>> -    auto LegalType = findLegalType(Aspect, Action);<br class="">
>> -    if (!LegalType)<br class="">
>> -      return std::make_pair(LegalizeAction:<wbr class="">:Unsupported, LLT());<br class="">
>> -    return std::make_pair(Action, *LegalType);<br class="">
>> -  }<br class="">
>> -<br class="">
>> -  /// Find the specified \p Aspect in the primary (explicitly set) Actions<br class="">
>> -  /// table. Returns either the action the target requested or NotFound if there<br class="">
>> -  /// was no setAction call.<br class="">
>> -  LegalizeAction findInActions(const InstrAspect &Aspect) const {<br class="">
>> -    if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)<br class="">
>> -      return NotFound;<br class="">
>> -    if (Aspect.Idx >= Actions[Aspect.Opcode - FirstOp].size())<br class="">
>> -      return NotFound;<br class="">
>> -    const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];<br class="">
>> -    auto ActionIt =  Map.find(Aspect.Type);<br class="">
>> -    if (ActionIt == Map.end())<br class="">
>> -      return NotFound;<br class="">
>> -<br class="">
>> -    return ActionIt->second;<br class="">
>> -  }<br class="">
>> -<br class="">
>>  bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;<br class="">
>><br class="">
>>  virtual bool legalizeCustom(MachineInstr &MI,<br class="">
>> @@ -217,20 +283,181 @@ public:<br class="">
>>                              MachineIRBuilder &MIRBuilder) const;<br class="">
>><br class="">
>> private:<br class="">
>> -  static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC<wbr class="">_OPCODE_START;<br class="">
>> -  static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC<wbr class="">_OPCODE_END;<br class="">
>> +  /// The SizeAndActionsVec is a representation mapping between all natural<br class="">
>> +  /// numbers and an Action. The natural number represents the bit size of<br class="">
>> +  /// the InstrAspect. For example, for a target with native support for 32-bit<br class="">
>> +  /// and 64-bit additions, you'd express that as:<br class="">
>> +  /// setScalarAction(G_ADD, 0,<br class="">
>> +  ///           {{1, WidenScalar},  // bit sizes [ 1, 31[<br class="">
>> +  ///            {32, Legal},       // bit sizes [32, 33[<br class="">
>> +  ///            {33, WidenScalar}, // bit sizes [33, 64[<br class="">
>> +  ///            {64, Legal},       // bit sizes [64, 65[<br class="">
>> +  ///            {65, NarrowScalar} // bit sizes [65, +inf[<br class="">
>> +  ///           });<br class="">
>> +  /// It may be that only 64-bit pointers are supported on your target:<br class="">
>> +  /// setPointerAction(G_GEP, 0, LLT:pointer(1),<br class="">
>> +  ///           {{1, Unsupported},  // bit sizes [ 1, 63[<br class="">
>> +  ///            {64, Legal},       // bit sizes [64, 65[<br class="">
>> +  ///            {65, Unsupported}, // bit sizes [65, +inf[<br class="">
>> +  ///           });<br class="">
>> +  void setScalarAction(const unsigned Opcode, const unsigned TypeIndex,<br class="">
>> +                       const SizeAndActionsVec &SizeAndActions) {<br class="">
>> +    const unsigned OpcodeIdx = Opcode - FirstOp;<br class="">
>> +    SmallVector<SizeAndActionsVec, 1> &Actions = ScalarActions[OpcodeIdx];<br class="">
>> +    setActions(TypeIndex, Actions, SizeAndActions);<br class="">
>> +  }<br class="">
>> +  void setPointerAction(const unsigned Opcode, const unsigned TypeIndex,<br class="">
>> +                        const unsigned AddressSpace,<br class="">
>> +                        const SizeAndActionsVec &SizeAndActions) {<br class="">
>> +    const unsigned OpcodeIdx = Opcode - FirstOp;<br class="">
>> +    if (AddrSpace2PointerActions[Opco<wbr class="">deIdx].find(AddressSpace) ==<br class="">
>> +        AddrSpace2PointerActions[Opcod<wbr class="">eIdx].end())<br class="">
>> +      AddrSpace2PointerActions[Opcod<wbr class="">eIdx][AddressSpace] = {{}};<br class="">
>> +    SmallVector<SizeAndActionsVec, 1> &Actions =<br class="">
>> +        AddrSpace2PointerActions[Opcod<wbr class="">eIdx].find(AddressSpace)-><wbr class="">second;<br class="">
>> +    setActions(TypeIndex, Actions, SizeAndActions);<br class="">
>> +  }<br class="">
>><br class="">
>> -  using TypeMap = DenseMap<LLT, LegalizeAction>;<br class="">
>> -  using SIVActionMap = DenseMap<std::pair<unsigned, LLT>, LegalizeAction>;<br class="">
>> +  /// If an operation on a given vector type (say <M x iN>) isn't explicitly<br class="">
>> +  /// specified, we proceed in 2 stages. First we legalize the underlying scalar<br class="">
>> +  /// (so that there's at least one legal vector with that scalar), then we<br class="">
>> +  /// adjust the number of elements in the vector so that it is legal. The<br class="">
>> +  /// desired action in the first step is controlled by this function.<br class="">
>> +  void setScalarInVectorAction(const unsigned Opcode, const unsigned TypeIndex,<br class="">
>> +                               const SizeAndActionsVec &SizeAndActions) {<br class="">
>> +    unsigned OpcodeIdx = Opcode - FirstOp;<br class="">
>> +    SmallVector<SizeAndActionsVec, 1> &Actions =<br class="">
>> +        ScalarInVectorActions[OpcodeId<wbr class="">x];<br class="">
>> +    setActions(TypeIndex, Actions, SizeAndActions);<br class="">
>> +  }<br class="">
>><br class="">
>> -  SmallVector<TypeMap, 1> Actions[LastOp - FirstOp + 1];<br class="">
>> -  SIVActionMap ScalarInVectorActions;<br class="">
>> -  DenseMap<std::pair<unsigned, LLT>, uint16_t> MaxLegalVectorElts;<br class="">
>> -  DenseMap<unsigned, LegalizeAction> DefaultActions;<br class="">
>> +  /// See also setScalarInVectorAction.<br class="">
>> +  /// This function let's you specify the number of elements in a vector that<br class="">
>> +  /// are legal for a legal element size.<br class="">
>> +  void setVectorNumElementAction(cons<wbr class="">t unsigned Opcode,<br class="">
>> +                                 const unsigned TypeIndex,<br class="">
>> +                                 const unsigned ElementSize,<br class="">
>> +                                 const SizeAndActionsVec &SizeAndActions) {<br class="">
>> +    const unsigned OpcodeIdx = Opcode - FirstOp;<br class="">
>> +    if (NumElements2Actions[OpcodeIdx<wbr class="">].find(ElementSize) ==<br class="">
>> +        NumElements2Actions[OpcodeIdx]<wbr class="">.end())<br class="">
>> +      NumElements2Actions[OpcodeIdx]<wbr class="">[ElementSize] = {{}};<br class="">
>> +    SmallVector<SizeAndActionsVec, 1> &Actions =<br class="">
>> +        NumElements2Actions[OpcodeIdx]<wbr class="">.find(ElementSize)->second;<br class="">
>> +    setActions(TypeIndex, Actions, SizeAndActions);<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,<br class="">
>> +  /// i.e. it's OK if it doesn't start from size 1.<br class="">
>> +  static void checkPartialSizeAndActionsVect<wbr class="">or(const SizeAndActionsVec& v) {<br class="">
>> +#ifndef NDEBUG<br class="">
>> +    // The sizes should be in increasing order<br class="">
>> +    int prev_size = -1;<br class="">
>> +    for(auto SizeAndAction: v) {<br class="">
>> +      assert(SizeAndAction.first > prev_size);<br class="">
>> +      prev_size = SizeAndAction.first;<br class="">
>> +    }<br class="">
>> +    // - for every Widen action, there should be a larger bitsize that<br class="">
>> +    //   can be legalized towards (e.g. Legal, Lower, Libcall or Custom<br class="">
>> +    //   action).<br class="">
>> +    // - for every Narrow action, there should be a smaller bitsize that<br class="">
>> +    //   can be legalized towards.<br class="">
>> +    int SmallestNarrowIdx = -1;<br class="">
>> +    int LargestWidenIdx = -1;<br class="">
>> +    int SmallestLegalizableToSameSizeI<wbr class="">dx = -1;<br class="">
>> +    int LargestLegalizableToSameSizeId<wbr class="">x = -1;<br class="">
>> +    for(size_t i=0; i<v.size(); ++i) {<br class="">
>> +      switch (v[i].second) {<br class="">
>> +        case FewerElements:<br class="">
>> +        case NarrowScalar:<br class="">
>> +          if (SmallestNarrowIdx == -1)<br class="">
>> +            SmallestNarrowIdx = i;<br class="">
>> +          break;<br class="">
>> +        case WidenScalar:<br class="">
>> +        case MoreElements:<br class="">
>> +          LargestWidenIdx = i;<br class="">
>> +          break;<br class="">
>> +        case Unsupported:<br class="">
>> +          break;<br class="">
>> +        default:<br class="">
>> +          if (SmallestLegalizableToSameSize<wbr class="">Idx == -1)<br class="">
>> +            SmallestLegalizableToSameSizeI<wbr class="">dx = i;<br class="">
>> +          LargestLegalizableToSameSizeId<wbr class="">x = i;<br class="">
>> +      }<br class="">
>> +    }<br class="">
>> +    if (SmallestNarrowIdx != -1) {<br class="">
>> +      assert(SmallestLegalizableToSa<wbr class="">meSizeIdx != -1);<br class="">
>> +      assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeI<wbr class="">dx);<br class="">
>> +    }<br class="">
>> +    if (LargestWidenIdx != -1)<br class="">
>> +      assert(LargestWidenIdx < LargestLegalizableToSameSizeId<wbr class="">x);<br class="">
>> +#endif<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  /// A full SizeAndActionsVec must cover all bit sizes, i.e. must start with<br class="">
>> +  /// from size 1.<br class="">
>> +  static void checkFullSizeAndActionsVector(<wbr class="">const SizeAndActionsVec& v) {<br class="">
>> +#ifndef NDEBUG<br class="">
>> +    // Data structure invariant: The first bit size must be size 1.<br class="">
>> +    assert(v.size() >= 1);<br class="">
>> +    assert(v[0].first == 1);<br class="">
>> +    checkPartialSizeAndActionsVect<wbr class="">or(v);<br class="">
>> +#endif<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  /// Sets actions for all bit sizes on a particular generic opcode, type<br class="">
>> +  /// index and scalar or pointer type.<br class="">
>> +  void setActions(unsigned TypeIndex,<br class="">
>> +                  SmallVector<SizeAndActionsVec, 1> &Actions,<br class="">
>> +                  const SizeAndActionsVec &SizeAndActions) {<br class="">
>> +    checkFullSizeAndActionsVector(<wbr class="">SizeAndActions);<br class="">
>> +    if (Actions.size() <= TypeIndex)<br class="">
>> +      Actions.resize(TypeIndex + 1);<br class="">
>> +    Actions[TypeIndex] = SizeAndActions;<br class="">
>> +  }<br class="">
>> +<br class="">
>> +  static SizeAndAction findAction(const SizeAndActionsVec &Vec,<br class="">
>> +                                  const uint32_t Size);<br class="">
>> +<br class="">
>> +  /// Returns the next action needed to get the scalar or pointer type closer<br class="">
>> +  /// to being legal<br class="">
>> +  /// E.g. findLegalAction({G_REM, 13}) should return<br class="">
>> +  /// (WidenScalar, 32). After that, findLegalAction({G_REM, 32}) will<br class="">
>> +  /// probably be called, which should return (Lower, 32).<br class="">
>> +  /// This is assuming the setScalarAction on G_REM was something like:<br class="">
>> +  /// setScalarAction(G_REM, 0,<br class="">
>> +  ///           {{1, WidenScalar},  // bit sizes [ 1, 31[<br class="">
>> +  ///            {32, Lower},       // bit sizes [32, 33[<br class="">
>> +  ///            {33, NarrowScalar} // bit sizes [65, +inf[<br class="">
>> +  ///           });<br class="">
>> +  std::pair<LegalizeAction, LLT><br class="">
>> +  findScalarLegalAction(const InstrAspect &Aspect) const;<br class="">
>> +<br class="">
>> +  /// Returns the next action needed towards legalizing the vector type.<br class="">
>> +  std::pair<LegalizeAction, LLT><br class="">
>> +  findVectorLegalAction(const InstrAspect &Aspect) const;<br class="">
>> +<br class="">
>> +  static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC<wbr class="">_OPCODE_START;<br class="">
>> +  static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC<wbr class="">_OPCODE_END;<br class="">
>><br class="">
>> -  bool TablesInitialized = false;<br class="">
>> +  // Data structures used temporarily during construction of legality data:<br class="">
>> +  typedef DenseMap<LLT, LegalizeAction> TypeMap;<br class="">
>> +  SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];<br class="">
>> +  SmallVector<SizeChangeStrategy<wbr class="">, 1><br class="">
>> +      ScalarSizeChangeStrategies[Las<wbr class="">tOp - FirstOp + 1];<br class="">
>> +  SmallVector<SizeChangeStrategy<wbr class="">, 1><br class="">
>> +      VectorElementSizeChangeStrateg<wbr class="">ies[LastOp - FirstOp + 1];<br class="">
>> +  bool TablesInitialized;<br class="">
>> +<br class="">
>> +  // Data structures used by getAction:<br class="">
>> +  SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];<br class="">
>> +  SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];<br class="">
>> +  std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>><br class="">
>> +      AddrSpace2PointerActions[LastO<wbr class="">p - FirstOp + 1];<br class="">
>> +  std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>><br class="">
>> +      NumElements2Actions[LastOp - FirstOp + 1];<br class="">
>> };<br class="">
>><br class="">
>> -} // end namespace llvm<br class="">
>> +} // end namespace llvm.<br class="">
>><br class="">
>> #endif // LLVM_CODEGEN_GLOBALISEL_LEGALI<wbr class="">ZERINFO_H<br class="">
>><br class="">
>> Modified: llvm/trunk/include/llvm/Suppor<wbr class="">t/LowLevelTypeImpl.h<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/LowLevelTypeImpl.h?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/include/llvm/<wbr class="">Support/LowLevelTypeImpl.h?<wbr class="">rev=317560&r1=317559&r2=317560<wbr class="">&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/include/llvm/Suppor<wbr class="">t/LowLevelTypeImpl.h (original)<br class="">
>> +++ llvm/trunk/include/llvm/Suppor<wbr class="">t/LowLevelTypeImpl.h Tue Nov  7 02:34:34 2017<br class="">
>> @@ -137,51 +137,6 @@ public:<br class="">
>>      return scalar(getScalarSizeInBits());<br class="">
>>  }<br class="">
>><br class="">
>> -  /// Get a low-level type with half the size of the original, by halving the<br class="">
>> -  /// size of the scalar type involved. For example `s32` will become `s16`,<br class="">
>> -  /// `<2 x s32>` will become `<2 x s16>`.<br class="">
>> -  LLT halfScalarSize() const {<br class="">
>> -    assert(!IsPointer && getScalarSizeInBits() > 1 &&<br class="">
>> -           getScalarSizeInBits() % 2 == 0 && "cannot half size of this type");<br class="">
>> -    return LLT{/*isPointer=*/false, IsVector ? true : false,<br class="">
>> -               IsVector ? getNumElements() : (uint16_t)0,<br class="">
>> -               getScalarSizeInBits() / 2, /*AddressSpace=*/0};<br class="">
>> -  }<br class="">
>> -<br class="">
>> -  /// Get a low-level type with twice the size of the original, by doubling the<br class="">
>> -  /// size of the scalar type involved. For example `s32` will become `s64`,<br class="">
>> -  /// `<2 x s32>` will become `<2 x s64>`.<br class="">
>> -  LLT doubleScalarSize() const {<br class="">
>> -    assert(!IsPointer && "cannot change size of this type");<br class="">
>> -    return LLT{/*isPointer=*/false, IsVector ? true : false,<br class="">
>> -               IsVector ? getNumElements() : (uint16_t)0,<br class="">
>> -               getScalarSizeInBits() * 2, /*AddressSpace=*/0};<br class="">
>> -  }<br class="">
>> -<br class="">
>> -  /// Get a low-level type with half the size of the original, by halving the<br class="">
>> -  /// number of vector elements of the scalar type involved. The source must be<br class="">
>> -  /// a vector type with an even number of elements. For example `<4 x s32>`<br class="">
>> -  /// will become `<2 x s32>`, `<2 x s32>` will become `s32`.<br class="">
>> -  LLT halfElements() const {<br class="">
>> -    assert(isVector() && getNumElements() % 2 == 0 && "cannot half odd vector");<br class="">
>> -    if (getNumElements() == 2)<br class="">
>> -      return scalar(getScalarSizeInBits());<br class="">
>> -<br class="">
>> -    return LLT{/*isPointer=*/false, /*isVector=*/true,<br class="">
>> -               (uint16_t)(getNumElements() / 2), getScalarSizeInBits(),<br class="">
>> -               /*AddressSpace=*/0};<br class="">
>> -  }<br class="">
>> -<br class="">
>> -  /// Get a low-level type with twice the size of the original, by doubling the<br class="">
>> -  /// number of vector elements of the scalar type involved. The source must be<br class="">
>> -  /// a vector type. For example `<2 x s32>` will become `<4 x s32>`. Doubling<br class="">
>> -  /// the number of elements in sN produces <2 x sN>.<br class="">
>> -  LLT doubleElements() const {<br class="">
>> -    return LLT{IsPointer ? true : false, /*isVector=*/true,<br class="">
>> -               (uint16_t)(getNumElements() * 2), getScalarSizeInBits(),<br class="">
>> -               IsPointer ? getAddressSpace() : 0};<br class="">
>> -  }<br class="">
>> -<br class="">
>>  void print(raw_ostream &OS) const;<br class="">
>><br class="">
>>  bool operator==(const LLT &RHS) const {<br class="">
>><br class="">
>> Modified: llvm/trunk/lib/CodeGen/GlobalI<wbr class="">Sel/LegalizerHelper.cpp<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/lib/CodeGen/<wbr class="">GlobalISel/LegalizerHelper.<wbr class="">cpp?rev=317560&r1=317559&r2=<wbr class="">317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/lib/CodeGen/GlobalI<wbr class="">Sel/LegalizerHelper.cpp (original)<br class="">
>> +++ llvm/trunk/lib/CodeGen/GlobalI<wbr class="">Sel/LegalizerHelper.cpp Tue Nov  7 02:34:34 2017<br class="">
>> @@ -173,12 +173,18 @@ LegalizerHelper::LegalizeResul<wbr class="">t Legalize<br class="">
>><br class="">
>>  MIRBuilder.setInstr(MI);<br class="">
>><br class="">
>> +  int64_t SizeOp0 = MRI.getType(MI.getOperand(0).g<wbr class="">etReg()).getSizeInBits();<br class="">
>> +  int64_t NarrowSize = NarrowTy.getSizeInBits();<br class="">
>> +<br class="">
>>  switch (MI.getOpcode()) {<br class="">
>>  default:<br class="">
>>    return UnableToLegalize;<br class="">
>>  case TargetOpcode::G_IMPLICIT_DEF: {<br class="">
>> -    int NumParts = MRI.getType(MI.getOperand(0).g<wbr class="">etReg()).getSizeInBits() /<br class="">
>> -                   NarrowTy.getSizeInBits();<br class="">
>> +    // FIXME: add support for when SizeOp0 isn't an exact multiple of<br class="">
>> +    // NarrowSize.<br class="">
>> +    if (SizeOp0 % NarrowSize != 0)<br class="">
>> +      return UnableToLegalize;<br class="">
>> +    int NumParts = SizeOp0 / NarrowSize;<br class="">
>><br class="">
>>    SmallVector<unsigned, 2> DstRegs;<br class="">
>>    for (int i = 0; i < NumParts; ++i) {<br class="">
>> @@ -191,9 +197,12 @@ LegalizerHelper::LegalizeResul<wbr class="">t Legalize<br class="">
>>    return Legalized;<br class="">
>>  }<br class="">
>>  case TargetOpcode::G_ADD: {<br class="">
>> +    // FIXME: add support for when SizeOp0 isn't an exact multiple of<br class="">
>> +    // NarrowSize.<br class="">
>> +    if (SizeOp0 % NarrowSize != 0)<br class="">
>> +      return UnableToLegalize;<br class="">
>>    // Expand in terms of carry-setting/consuming G_ADDE instructions.<br class="">
>> -    int NumParts = MRI.getType(MI.getOperand(0).g<wbr class="">etReg()).getSizeInBits() /<br class="">
>> -                   NarrowTy.getSizeInBits();<br class="">
>> +    int NumParts = SizeOp0 / NarrowTy.getSizeInBits();<br class="">
>><br class="">
>>    SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;<br class="">
>>    extractParts(MI.getOperand(1).<wbr class="">getReg(), NarrowTy, NumParts, Src1Regs);<br class="">
>> @@ -221,9 +230,12 @@ LegalizerHelper::LegalizeResul<wbr class="">t Legalize<br class="">
>>    if (TypeIdx != 1)<br class="">
>>      return UnableToLegalize;<br class="">
>><br class="">
>> -    int64_t NarrowSize = NarrowTy.getSizeInBits();<br class="">
>> -    int NumParts =<br class="">
>> -        MRI.getType(MI.getOperand(1).g<wbr class="">etReg()).getSizeInBits() / NarrowSize;<br class="">
>> +    int64_t SizeOp1 = MRI.getType(MI.getOperand(1).g<wbr class="">etReg()).getSizeInBits();<br class="">
>> +    // FIXME: add support for when SizeOp1 isn't an exact multiple of<br class="">
>> +    // NarrowSize.<br class="">
>> +    if (SizeOp1 % NarrowSize != 0)<br class="">
>> +      return UnableToLegalize;<br class="">
>> +    int NumParts = SizeOp1 / NarrowSize;<br class="">
>><br class="">
>>    SmallVector<unsigned, 2> SrcRegs, DstRegs;<br class="">
>>    SmallVector<uint64_t, 2> Indexes;<br class="">
>> @@ -270,12 +282,12 @@ LegalizerHelper::LegalizeResul<wbr class="">t Legalize<br class="">
>>    return Legalized;<br class="">
>>  }<br class="">
>>  case TargetOpcode::G_INSERT: {<br class="">
>> -    if (TypeIdx != 0)<br class="">
>> +    // FIXME: add support for when SizeOp0 isn't an exact multiple of<br class="">
>> +    // NarrowSize.<br class="">
>> +    if (SizeOp0 % NarrowSize != 0)<br class="">
>>      return UnableToLegalize;<br class="">
>><br class="">
>> -    int64_t NarrowSize = NarrowTy.getSizeInBits();<br class="">
>> -    int NumParts =<br class="">
>> -        MRI.getType(MI.getOperand(0).g<wbr class="">etReg()).getSizeInBits() / NarrowSize;<br class="">
>> +    int NumParts = SizeOp0 / NarrowSize;<br class="">
>><br class="">
>>    SmallVector<unsigned, 2> SrcRegs, DstRegs;<br class="">
>>    SmallVector<uint64_t, 2> Indexes;<br class="">
>> @@ -330,9 +342,11 @@ LegalizerHelper::LegalizeResul<wbr class="">t Legalize<br class="">
>>    return Legalized;<br class="">
>>  }<br class="">
>>  case TargetOpcode::G_LOAD: {<br class="">
>> -    unsigned NarrowSize = NarrowTy.getSizeInBits();<br class="">
>> -    int NumParts =<br class="">
>> -        MRI.getType(MI.getOperand(0).g<wbr class="">etReg()).getSizeInBits() / NarrowSize;<br class="">
>> +    // FIXME: add support for when SizeOp0 isn't an exact multiple of<br class="">
>> +    // NarrowSize.<br class="">
>> +    if (SizeOp0 % NarrowSize != 0)<br class="">
>> +      return UnableToLegalize;<br class="">
>> +    int NumParts = SizeOp0 / NarrowSize;<br class="">
>>    LLT OffsetTy = LLT::scalar(<br class="">
>>        MRI.getType(MI.getOperand(1).g<wbr class="">etReg()).getScalarSizeInBits()<wbr class="">);<br class="">
>><br class="">
>> @@ -357,9 +371,11 @@ LegalizerHelper::LegalizeResul<wbr class="">t Legalize<br class="">
>>    return Legalized;<br class="">
>>  }<br class="">
>>  case TargetOpcode::G_STORE: {<br class="">
>> -    unsigned NarrowSize = NarrowTy.getSizeInBits();<br class="">
>> -    int NumParts =<br class="">
>> -        MRI.getType(MI.getOperand(0).g<wbr class="">etReg()).getSizeInBits() / NarrowSize;<br class="">
>> +    // FIXME: add support for when SizeOp0 isn't an exact multiple of<br class="">
>> +    // NarrowSize.<br class="">
>> +    if (SizeOp0 % NarrowSize != 0)<br class="">
>> +      return UnableToLegalize;<br class="">
>> +    int NumParts = SizeOp0 / NarrowSize;<br class="">
>>    LLT OffsetTy = LLT::scalar(<br class="">
>>        MRI.getType(MI.getOperand(1).g<wbr class="">etReg()).getScalarSizeInBits()<wbr class="">);<br class="">
>><br class="">
>> @@ -381,9 +397,11 @@ LegalizerHelper::LegalizeResul<wbr class="">t Legalize<br class="">
>>    return Legalized;<br class="">
>>  }<br class="">
>>  case TargetOpcode::G_CONSTANT: {<br class="">
>> -    unsigned NarrowSize = NarrowTy.getSizeInBits();<br class="">
>> -    int NumParts =<br class="">
>> -        MRI.getType(MI.getOperand(0).g<wbr class="">etReg()).getSizeInBits() / NarrowSize;<br class="">
>> +    // FIXME: add support for when SizeOp0 isn't an exact multiple of<br class="">
>> +    // NarrowSize.<br class="">
>> +    if (SizeOp0 % NarrowSize != 0)<br class="">
>> +      return UnableToLegalize;<br class="">
>> +    int NumParts = SizeOp0 / NarrowSize;<br class="">
>>    const APInt &Cst = MI.getOperand(1).getCImm()->ge<wbr class="">tValue();<br class="">
>>    LLVMContext &Ctx = MIRBuilder.getMF().getFunction<wbr class="">()->getContext();<br class="">
>><br class="">
>> @@ -410,9 +428,12 @@ LegalizerHelper::LegalizeResul<wbr class="">t Legalize<br class="">
>>    // ...<br class="">
>>    // AN = BinOp<Ty/N> BN, CN<br class="">
>>    // A = G_MERGE_VALUES A1, ..., AN<br class="">
>> -    unsigned NarrowSize = NarrowTy.getSizeInBits();<br class="">
>> -    int NumParts =<br class="">
>> -        MRI.getType(MI.getOperand(0).g<wbr class="">etReg()).getSizeInBits() / NarrowSize;<br class="">
>> +<br class="">
>> +    // FIXME: add support for when SizeOp0 isn't an exact multiple of<br class="">
>> +    // NarrowSize.<br class="">
>> +    if (SizeOp0 % NarrowSize != 0)<br class="">
>> +      return UnableToLegalize;<br class="">
>> +    int NumParts = SizeOp0 / NarrowSize;<br class="">
>><br class="">
>>    // List the registers where the destination will be scattered.<br class="">
>>    SmallVector<unsigned, 2> DstRegs;<br class="">
>> @@ -854,7 +875,12 @@ LegalizerHelper::fewerElements<wbr class="">Vector(Mac<br class="">
>>  case TargetOpcode::G_ADD: {<br class="">
>>    unsigned NarrowSize = NarrowTy.getSizeInBits();<br class="">
>>    unsigned DstReg = MI.getOperand(0).getReg();<br class="">
>> -    int NumParts = MRI.getType(DstReg).getSizeInB<wbr class="">its() / NarrowSize;<br class="">
>> +    unsigned Size = MRI.getType(DstReg).getSizeInB<wbr class="">its();<br class="">
>> +    int NumParts = Size / NarrowSize;<br class="">
>> +    // FIXME: Don't know how to handle the situation where the small vectors<br class="">
>> +    // aren't all the same size yet.<br class="">
>> +    if (Size % NarrowSize != 0)<br class="">
>> +      return UnableToLegalize;<br class="">
>><br class="">
>>    MIRBuilder.setInstr(MI);<br class="">
>><br class="">
>><br class="">
>> Modified: llvm/trunk/lib/CodeGen/GlobalI<wbr class="">Sel/LegalizerInfo.cpp<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/lib/CodeGen/<wbr class="">GlobalISel/LegalizerInfo.cpp?<wbr class="">rev=317560&r1=317559&r2=<wbr class="">317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/lib/CodeGen/GlobalI<wbr class="">Sel/LegalizerInfo.cpp (original)<br class="">
>> +++ llvm/trunk/lib/CodeGen/GlobalI<wbr class="">Sel/LegalizerInfo.cpp Tue Nov  7 02:34:34 2017<br class="">
>> @@ -28,46 +28,130 @@<br class="">
>> #include "llvm/Support/MathExtras.h"<br class="">
>> #include "llvm/Target/TargetOpcodes.h"<br class="">
>> #include <algorithm><br class="">
>> -#include <cassert><br class="">
>> -#include <tuple><br class="">
>> -#include <utility><br class="">
>> -<br class="">
>> +#include <map><br class="">
>> using namespace llvm;<br class="">
>><br class="">
>> -LegalizerInfo::LegalizerInfo(<wbr class="">) {<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_IMPLICIT_DEF] = NarrowScalar;<br class="">
>> -<br class="">
>> -  // FIXME: these two can be legalized to the fundamental load/store Jakob<br class="">
>> -  // proposed. Once loads & stores are supported.<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_ANYEXT] = Legal;<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_TRUNC] = Legal;<br class="">
>> -<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_INTRINSIC] = Legal;<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_INTRINSIC_W_SIDE_EFFECTS] = Legal;<br class="">
>> -<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_ADD] = NarrowScalar;<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_LOAD] = NarrowScalar;<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_STORE] = NarrowScalar;<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_OR] = NarrowScalar;<br class="">
>> -<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_BRCOND] = WidenScalar;<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_INSERT] = NarrowScalar;<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_EXTRACT] = NarrowScalar;<br class="">
>> -  DefaultActions[TargetOpcode::G<wbr class="">_FNEG] = Lower;<br class="">
>> +LegalizerInfo::LegalizerInfo(<wbr class="">) : TablesInitialized(false) {<br class="">
>> +  // Set defaults.<br class="">
>> +  // FIXME: these two (G_ANYEXT and G_TRUNC?) can be legalized to the<br class="">
>> +  // fundamental load/store Jakob proposed. Once loads & stores are supported.<br class="">
>> +  setScalarAction(TargetOpcode::<wbr class="">G_ANYEXT, 1, {{1, Legal}});<br class="">
>> +  setScalarAction(TargetOpcode::<wbr class="">G_ZEXT, 1, {{1, Legal}});<br class="">
>> +  setScalarAction(TargetOpcode::<wbr class="">G_SEXT, 1, {{1, Legal}});<br class="">
>> +  setScalarAction(TargetOpcode::<wbr class="">G_TRUNC, 0, {{1, Legal}});<br class="">
>> +  setScalarAction(TargetOpcode::<wbr class="">G_TRUNC, 1, {{1, Legal}});<br class="">
>> +<br class="">
>> +  setScalarAction(TargetOpcode::<wbr class="">G_INTRINSIC, 0, {{1, Legal}});<br class="">
>> +  setScalarAction(TargetOpcode::<wbr class="">G_INTRINSIC_W_SIDE_EFFECTS, 0, {{1, Legal}});<br class="">
>> +<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_IMPLICIT_DEF, 0, narrowToSmallerAndUnsupportedI<wbr class="">fTooSmall);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_ADD, 0, widenToLargerTypesAndNarrowToL<wbr class="">argest);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_OR, 0, widenToLargerTypesAndNarrowToL<wbr class="">argest);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_LOAD, 0, narrowToSmallerAndUnsupportedI<wbr class="">fTooSmall);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_STORE, 0, narrowToSmallerAndUnsupportedI<wbr class="">fTooSmall);<br class="">
>> +<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_BRCOND, 0, widenToLargerTypesUnsupportedO<wbr class="">therwise);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_INSERT, 0, narrowToSmallerAndUnsupportedI<wbr class="">fTooSmall);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_EXTRACT, 0, narrowToSmallerAndUnsupportedI<wbr class="">fTooSmall);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      TargetOpcode::G_EXTRACT, 1, narrowToSmallerAndUnsupportedI<wbr class="">fTooSmall);<br class="">
>> +  setScalarAction(TargetOpcode::<wbr class="">G_FNEG, 0, {{1, Lower}});<br class="">
>> }<br class="">
>><br class="">
>> void LegalizerInfo::computeTables() {<br class="">
>> -  for (unsigned Opcode = 0; Opcode <= LastOp - FirstOp; ++Opcode) {<br class="">
>> -    for (unsigned Idx = 0, End = Actions[Opcode].size(); Idx != End; ++Idx) {<br class="">
>> -      for (auto &Action : Actions[Opcode][Idx]) {<br class="">
>> -        LLT Ty = Action.first;<br class="">
>> -        if (!Ty.isVector())<br class="">
>> -          continue;<br class="">
>> -<br class="">
>> -        auto &Entry = MaxLegalVectorElts[std::make_p<wbr class="">air(Opcode + FirstOp,<br class="">
>> -                                                        Ty.getElementType())];<br class="">
>> -        Entry = std::max(Entry, Ty.getNumElements());<br class="">
>> +  assert(TablesInitialized == false);<br class="">
>> +<br class="">
>> +  for (unsigned OpcodeIdx = 0; OpcodeIdx <= LastOp - FirstOp; ++OpcodeIdx) {<br class="">
>> +    const unsigned Opcode = FirstOp + OpcodeIdx;<br class="">
>> +    for (unsigned TypeIdx = 0; TypeIdx != SpecifiedActions[OpcodeIdx].si<wbr class="">ze();<br class="">
>> +         ++TypeIdx) {<br class="">
>> +      // 0. Collect information specified through the setAction API, i.e.<br class="">
>> +      // for specific bit sizes.<br class="">
>> +      // For scalar types:<br class="">
>> +      SizeAndActionsVec ScalarSpecifiedActions;<br class="">
>> +      // For pointer types:<br class="">
>> +      std::map<uint16_t, SizeAndActionsVec> AddressSpace2SpecifiedActions;<br class="">
>> +      // For vector types:<br class="">
>> +      std::map<uint16_t, SizeAndActionsVec> ElemSize2SpecifiedActions;<br class="">
>> +      for (auto LLT2Action : SpecifiedActions[OpcodeIdx][Ty<wbr class="">peIdx]) {<br class="">
>> +        const LLT Type = LLT2Action.first;<br class="">
>> +        const LegalizeAction Action = LLT2Action.second;<br class="">
>> +<br class="">
>> +        auto SizeAction = std::make_pair(Type.getSizeInB<wbr class="">its(), Action);<br class="">
>> +        if (Type.isPointer())<br class="">
>> +          AddressSpace2SpecifiedActions[<wbr class="">Type.getAddressSpace()].push_b<wbr class="">ack(<br class="">
>> +              SizeAction);<br class="">
>> +        else if (Type.isVector())<br class="">
>> +          ElemSize2SpecifiedActions[Type<wbr class="">.getElementType().getSizeInBit<wbr class="">s()]<br class="">
>> +              .push_back(SizeAction);<br class="">
>> +        else<br class="">
>> +          ScalarSpecifiedActions.push_ba<wbr class="">ck(SizeAction);<br class="">
>> +      }<br class="">
>> +<br class="">
>> +      // 1. Handle scalar types<br class="">
>> +      {<br class="">
>> +        // Decide how to handle bit sizes for which no explicit specification<br class="">
>> +        // was given.<br class="">
>> +        SizeChangeStrategy S = &unsupportedForDifferentSizes;<br class="">
>> +        if (TypeIdx < ScalarSizeChangeStrategies[Opc<wbr class="">odeIdx].size() &&<br class="">
>> +            ScalarSizeChangeStrategies[Opc<wbr class="">odeIdx][TypeIdx] != nullptr)<br class="">
>> +          S = ScalarSizeChangeStrategies[Opc<wbr class="">odeIdx][TypeIdx];<br class="">
>> +        std::sort(ScalarSpecifiedActio<wbr class="">ns.begin(), ScalarSpecifiedActions.end());<br class="">
>> +        checkPartialSizeAndActionsVect<wbr class="">or(ScalarSpecifiedActions);<br class="">
>> +        setScalarAction(Opcode, TypeIdx, S(ScalarSpecifiedActions));<br class="">
>> +      }<br class="">
>> +<br class="">
>> +      // 2. Handle pointer types<br class="">
>> +      for (auto PointerSpecifiedActions : AddressSpace2SpecifiedActions) {<br class="">
>> +        std::sort(PointerSpecifiedActi<wbr class="">ons.second.begin(),<br class="">
>> +                  PointerSpecifiedActions.second<wbr class="">.end());<br class="">
>> +        checkPartialSizeAndActionsVect<wbr class="">or(PointerSpecifiedActions.sec<wbr class="">ond);<br class="">
>> +        // For pointer types, we assume that there isn't a meaningfull way<br class="">
>> +        // to change the number of bits used in the pointer.<br class="">
>> +        setPointerAction(<br class="">
>> +            Opcode, TypeIdx, PointerSpecifiedActions.first,<br class="">
>> +            unsupportedForDifferentSizes(P<wbr class="">ointerSpecifiedActions.second)<wbr class="">);<br class="">
>> +      }<br class="">
>> +<br class="">
>> +      // 3. Handle vector types<br class="">
>> +      SizeAndActionsVec ElementSizesSeen;<br class="">
>> +      for (auto VectorSpecifiedActions : ElemSize2SpecifiedActions) {<br class="">
>> +        std::sort(VectorSpecifiedActio<wbr class="">ns.second.begin(),<br class="">
>> +                  VectorSpecifiedActions.second.<wbr class="">end());<br class="">
>> +        const uint16_t ElementSize = VectorSpecifiedActions.first;<br class="">
>> +        ElementSizesSeen.push_back({El<wbr class="">ementSize, Legal});<br class="">
>> +        checkPartialSizeAndActionsVect<wbr class="">or(VectorSpecifiedActions.seco<wbr class="">nd);<br class="">
>> +        // For vector types, we assume that the best way to adapt the number<br class="">
>> +        // of elements is to the next larger number of elements type for which<br class="">
>> +        // the vector type is legal, unless there is no such type. In that case,<br class="">
>> +        // legalize towards a vector type with a smaller number of elements.<br class="">
>> +        SizeAndActionsVec NumElementsActions;<br class="">
>> +        for (SizeAndAction BitsizeAndAction : VectorSpecifiedActions.second) {<br class="">
>> +          assert(BitsizeAndAction.first % ElementSize == 0);<br class="">
>> +          const uint16_t NumElements = BitsizeAndAction.first / ElementSize;<br class="">
>> +          NumElementsActions.push_back({<wbr class="">NumElements, BitsizeAndAction.second});<br class="">
>> +        }<br class="">
>> +        setVectorNumElementAction(<br class="">
>> +            Opcode, TypeIdx, ElementSize,<br class="">
>> +            moreToWiderTypesAndLessToWides<wbr class="">t(NumElementsActions));<br class="">
>>      }<br class="">
>> +      std::sort(ElementSizesSeen.beg<wbr class="">in(), ElementSizesSeen.end());<br class="">
>> +      SizeChangeStrategy VectorElementSizeChangeStrateg<wbr class="">y =<br class="">
>> +          &unsupportedForDifferentSizes;<br class="">
>> +      if (TypeIdx < VectorElementSizeChangeStrateg<wbr class="">ies[OpcodeIdx].size() &&<br class="">
>> +          VectorElementSizeChangeStrateg<wbr class="">ies[OpcodeIdx][TypeIdx] != nullptr)<br class="">
>> +        VectorElementSizeChangeStrateg<wbr class="">y =<br class="">
>> +            VectorElementSizeChangeStrateg<wbr class="">ies[OpcodeIdx][TypeIdx];<br class="">
>> +      setScalarInVectorAction(<br class="">
>> +          Opcode, TypeIdx, VectorElementSizeChangeStrateg<wbr class="">y(ElementSizesSeen));<br class="">
>>    }<br class="">
>>  }<br class="">
>><br class="">
>> @@ -90,69 +174,24 @@ LegalizerInfo::getAction(const InstrAspe<br class="">
>>      Aspect.Opcode == TargetOpcode::G_UNMERGE_VALUES<wbr class="">)<br class="">
>>    return std::make_pair(Legal, Aspect.Type);<br class="">
>><br class="">
>> -  LLT Ty = Aspect.Type;<br class="">
>> -  LegalizeAction Action = findInActions(Aspect);<br class="">
>> -  // LegalizerHelper is not able to handle non-power-of-2 types right now, so do<br class="">
>> -  // not try to legalize them unless they are marked as Legal or Custom.<br class="">
>> -  // FIXME: This is a temporary hack until the general non-power-of-2<br class="">
>> -  // legalization works.<br class="">
>> -  if (!isPowerOf2_64(Ty.getSizeInBi<wbr class="">ts()) &&<br class="">
>> -      !(Action == Legal || Action == Custom))<br class="">
>> -    return std::make_pair(Unsupported, LLT());<br class="">
>> -<br class="">
>> -  if (Action != NotFound)<br class="">
>> -    return findLegalAction(Aspect, Action);<br class="">
>> -<br class="">
>> -  unsigned Opcode = Aspect.Opcode;<br class="">
>> -  if (!Ty.isVector()) {<br class="">
>> -    auto DefaultAction = DefaultActions.find(Aspect.Opc<wbr class="">ode);<br class="">
>> -    if (DefaultAction != DefaultActions.end() && DefaultAction->second == Legal)<br class="">
>> -      return std::make_pair(Legal, Ty);<br class="">
>> -<br class="">
>> -    if (DefaultAction != DefaultActions.end() && DefaultAction->second == Lower)<br class="">
>> -      return std::make_pair(Lower, Ty);<br class="">
>> -<br class="">
>> -    if (DefaultAction == DefaultActions.end() ||<br class="">
>> -        DefaultAction->second != NarrowScalar)<br class="">
>> -      return std::make_pair(Unsupported, LLT());<br class="">
>> -    return findLegalAction(Aspect, NarrowScalar);<br class="">
>> -  }<br class="">
>> -<br class="">
>> -  LLT EltTy = Ty.getElementType();<br class="">
>> -  int NumElts = Ty.getNumElements();<br class="">
>> -<br class="">
>> -  auto ScalarAction = ScalarInVectorActions.find(std<wbr class="">::make_pair(Opcode, EltTy));<br class="">
>> -  if (ScalarAction != ScalarInVectorActions.end() &&<br class="">
>> -      ScalarAction->second != Legal)<br class="">
>> -    return findLegalAction(Aspect, ScalarAction->second);<br class="">
>> -<br class="">
>> -  // The element type is legal in principle, but the number of elements is<br class="">
>> -  // wrong.<br class="">
>> -  auto MaxLegalElts = MaxLegalVectorElts.lookup(std:<wbr class="">:make_pair(Opcode, EltTy));<br class="">
>> -  if (MaxLegalElts > NumElts)<br class="">
>> -    return findLegalAction(Aspect, MoreElements);<br class="">
>> -<br class="">
>> -  if (MaxLegalElts == 0) {<br class="">
>> -    // Scalarize if there's no legal vector type, which is just a special case<br class="">
>> -    // of FewerElements.<br class="">
>> -    return std::make_pair(FewerElements, EltTy);<br class="">
>> -  }<br class="">
>> -<br class="">
>> -  return findLegalAction(Aspect, FewerElements);<br class="">
>> +  if (Aspect.Type.isScalar() || Aspect.Type.isPointer())<br class="">
>> +    return findScalarLegalAction(Aspect);<br class="">
>> +  assert(Aspect.Type.isVector())<wbr class="">;<br class="">
>> +  return findVectorLegalAction(Aspect);<br class="">
>> }<br class="">
>><br class="">
>> std::tuple<LegalizerInfo::Lega<wbr class="">lizeAction, unsigned, LLT><br class="">
>> LegalizerInfo::getAction(const MachineInstr &MI,<br class="">
>>                         const MachineRegisterInfo &MRI) const {<br class="">
>>  SmallBitVector SeenTypes(8);<br class="">
>> -  const MCInstrDesc &MCID = MI.getDesc();<br class="">
>> -  const MCOperandInfo *OpInfo = MCID.OpInfo;<br class="">
>> -  for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i) {<br class="">
>> +  const MCOperandInfo *OpInfo = MI.getDesc().OpInfo;<br class="">
>> +  // FIXME: probably we'll need to cache the results here somehow?<br class="">
>> +  for (unsigned i = 0; i < MI.getDesc().getNumOperands(); ++i) {<br class="">
>>    if (!OpInfo[i].isGenericType())<br class="">
>>      continue;<br class="">
>><br class="">
>> -    // We don't want to repeatedly check the same operand index, that<br class="">
>> -    // could get expensive.<br class="">
>> +    // We must only record actions once for each TypeIdx; otherwise we'd<br class="">
>> +    // try to legalize operands multiple times down the line.<br class="">
>>    unsigned TypeIdx = OpInfo[i].getGenericTypeIndex(<wbr class="">);<br class="">
>>    if (SeenTypes[TypeIdx])<br class="">
>>      continue;<br class="">
>> @@ -172,38 +211,164 @@ bool LegalizerInfo::isLegal(const Machin<br class="">
>>  return std::get<0>(getAction(MI, MRI)) == Legal;<br class="">
>> }<br class="">
>><br class="">
>> -Optional<LLT> LegalizerInfo::findLegalType(c<wbr class="">onst InstrAspect &Aspect,<br class="">
>> -                                 LegalizeAction Action) const {<br class="">
>> -  switch(Action) {<br class="">
>> -  default:<br class="">
>> -    llvm_unreachable("Cannot find legal type");<br class="">
>> +bool LegalizerInfo::legalizeCustom(<wbr class="">MachineInstr &MI, MachineRegisterInfo &MRI,<br class="">
>> +                                   MachineIRBuilder &MIRBuilder) const {<br class="">
>> +  return false;<br class="">
>> +}<br class="">
>> +<br class="">
>> +LegalizerInfo::SizeAndActions<wbr class="">Vec<br class="">
>> +LegalizerInfo::increaseToLarg<wbr class="">erTypesAndDecreaseToLargest(<br class="">
>> +    const SizeAndActionsVec &v, LegalizeAction IncreaseAction,<br class="">
>> +    LegalizeAction DecreaseAction) {<br class="">
>> +  SizeAndActionsVec result;<br class="">
>> +  unsigned LargestSizeSoFar = 0;<br class="">
>> +  if (v.size() >= 1 && v[0].first != 1)<br class="">
>> +    result.push_back({1, IncreaseAction});<br class="">
>> +  for (size_t i = 0; i < v.size(); ++i) {<br class="">
>> +    result.push_back(v[i]);<br class="">
>> +    LargestSizeSoFar = v[i].first;<br class="">
>> +    if (i + 1 < v.size() && v[i + 1].first != v[i].first + 1) {<br class="">
>> +      result.push_back({LargestSizeS<wbr class="">oFar + 1, IncreaseAction});<br class="">
>> +      LargestSizeSoFar = v[i].first + 1;<br class="">
>> +    }<br class="">
>> +  }<br class="">
>> +  result.push_back({LargestSizeS<wbr class="">oFar + 1, DecreaseAction});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> +LegalizerInfo::SizeAndActions<wbr class="">Vec<br class="">
>> +LegalizerInfo::decreaseToSmal<wbr class="">lerTypesAndIncreaseToSmallest(<br class="">
>> +    const SizeAndActionsVec &v, LegalizeAction DecreaseAction,<br class="">
>> +    LegalizeAction IncreaseAction) {<br class="">
>> +  SizeAndActionsVec result;<br class="">
>> +  if (v.size() == 0 || v[0].first != 1)<br class="">
>> +    result.push_back({1, IncreaseAction});<br class="">
>> +  for (size_t i = 0; i < v.size(); ++i) {<br class="">
>> +    result.push_back(v[i]);<br class="">
>> +    if (i + 1 == v.size() || v[i + 1].first != v[i].first + 1) {<br class="">
>> +      result.push_back({v[i].first + 1, DecreaseAction});<br class="">
>> +    }<br class="">
>> +  }<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> +LegalizerInfo::SizeAndAction<br class="">
>> +LegalizerInfo::findAction(con<wbr class="">st SizeAndActionsVec &Vec, const uint32_t Size) {<br class="">
>> +  assert(Size >= 1);<br class="">
>> +  // Find the last element in Vec that has a bitsize equal to or smaller than<br class="">
>> +  // the requested bit size.<br class="">
>> +  // That is the element just before the first element that is bigger than Size.<br class="">
>> +  auto VecIt = std::upper_bound(<br class="">
>> +      Vec.begin(), Vec.end(), Size,<br class="">
>> +      [](const uint32_t Size, const SizeAndAction lhs) -> bool {<br class="">
>> +        return Size < lhs.first;<br class="">
>> +      });<br class="">
>> +  assert(VecIt != Vec.begin() && "Does Vec not start with size 1?");<br class="">
>> +  --VecIt;<br class="">
>> +  int VecIdx = VecIt - Vec.begin();<br class="">
>> +<br class="">
>> +  LegalizeAction Action = Vec[VecIdx].second;<br class="">
>> +  switch (Action) {<br class="">
>>  case Legal:<br class="">
>>  case Lower:<br class="">
>>  case Libcall:<br class="">
>>  case Custom:<br class="">
>> -    return Aspect.Type;<br class="">
>> +    return {Size, Action};<br class="">
>> +  case FewerElements:<br class="">
>> +    // FIXME: is this special case still needed and correct?<br class="">
>> +    // Special case for scalarization:<br class="">
>> +    if (Vec == SizeAndActionsVec({{1, FewerElements}}))<br class="">
>> +      return {1, FewerElements};<br class="">
>>  case NarrowScalar: {<br class="">
>> -    return findLegalizableSize(<br class="">
>> -        Aspect, [&](LLT Ty) -> LLT { return Ty.halfScalarSize(); });<br class="">
>> -  }<br class="">
>> -  case WidenScalar: {<br class="">
>> -    return findLegalizableSize(Aspect, [&](LLT Ty) -> LLT {<br class="">
>> -      return Ty.getSizeInBits() < 8 ? LLT::scalar(8) : Ty.doubleScalarSize();<br class="">
>> -    });<br class="">
>> -  }<br class="">
>> -  case FewerElements: {<br class="">
>> -    return findLegalizableSize(<br class="">
>> -        Aspect, [&](LLT Ty) -> LLT { return Ty.halfElements(); });<br class="">
>> +    // The following needs to be a loop, as for now, we do allow needing to<br class="">
>> +    // go over "Unsupported" bit sizes before finding a legalizable bit size.<br class="">
>> +    // e.g. (s8, WidenScalar), (s9, Unsupported), (s32, Legal). if Size==8,<br class="">
>> +    // we need to iterate over s9, and then to s32 to return (s32, Legal).<br class="">
>> +    // If we want to get rid of the below loop, we should have stronger asserts<br class="">
>> +    // when building the SizeAndActionsVecs, probably not allowing<br class="">
>> +    // "Unsupported" unless at the ends of the vector.<br class="">
>> +    for (int i = VecIdx - 1; i >= 0; --i)<br class="">
>> +      if (!needsLegalizingToDifferentSi<wbr class="">ze(Vec[i].second) &&<br class="">
>> +          Vec[i].second != Unsupported)<br class="">
>> +        return {Vec[i].first, Action};<br class="">
>> +    llvm_unreachable("");<br class="">
>>  }<br class="">
>> +  case WidenScalar:<br class="">
>>  case MoreElements: {<br class="">
>> -    return findLegalizableSize(<br class="">
>> -        Aspect, [&](LLT Ty) -> LLT { return Ty.doubleElements(); });<br class="">
>> +    // See above, the following needs to be a loop, at least for now.<br class="">
>> +    for (std::size_t i = VecIdx + 1; i < Vec.size(); ++i)<br class="">
>> +      if (!needsLegalizingToDifferentSi<wbr class="">ze(Vec[i].second) &&<br class="">
>> +          Vec[i].second != Unsupported)<br class="">
>> +        return {Vec[i].first, Action};<br class="">
>> +    llvm_unreachable("");<br class="">
>>  }<br class="">
>> +  case Unsupported:<br class="">
>> +    return {Size, Unsupported};<br class="">
>> +  case NotFound:<br class="">
>> +    llvm_unreachable("NotFound");<br class="">
>>  }<br class="">
>> }<br class="">
>><br class="">
>> -bool LegalizerInfo::legalizeCustom(<wbr class="">MachineInstr &MI,<br class="">
>> -                                   MachineRegisterInfo &MRI,<br class="">
>> -                                   MachineIRBuilder &MIRBuilder) const {<br class="">
>> -  return false;<br class="">
>> +std::pair<LegalizerInfo::Lega<wbr class="">lizeAction, LLT><br class="">
>> +LegalizerInfo::findScalarLega<wbr class="">lAction(const InstrAspect &Aspect) const {<br class="">
>> +  assert(Aspect.Type.isScalar() || Aspect.Type.isPointer());<br class="">
>> +  if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)<br class="">
>> +    return {NotFound, LLT()};<br class="">
>> +  const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;<br class="">
>> +  if (Aspect.Type.isPointer() &&<br class="">
>> +      AddrSpace2PointerActions[Opcod<wbr class="">eIdx].find(Aspect.Type.getAddr<wbr class="">essSpace()) ==<br class="">
>> +          AddrSpace2PointerActions[Opcod<wbr class="">eIdx].end()) {<br class="">
>> +    return {NotFound, LLT()};<br class="">
>> +  }<br class="">
>> +  const SmallVector<SizeAndActionsVec, 1> &Actions =<br class="">
>> +      Aspect.Type.isPointer()<br class="">
>> +          ? AddrSpace2PointerActions[Opcod<wbr class="">eIdx]<br class="">
>> +                .find(Aspect.Type.getAddressSp<wbr class="">ace())<br class="">
>> +                ->second<br class="">
>> +          : ScalarActions[OpcodeIdx];<br class="">
>> +  if (Aspect.Idx >= Actions.size())<br class="">
>> +    return {NotFound, LLT()};<br class="">
>> +  const SizeAndActionsVec &Vec = Actions[Aspect.Idx];<br class="">
>> +  // FIXME: speed up this search, e.g. by using a results cache for repeated<br class="">
>> +  // queries?<br class="">
>> +  auto SizeAndAction = findAction(Vec, Aspect.Type.getSizeInBits());<br class="">
>> +  return {SizeAndAction.second,<br class="">
>> +          Aspect.Type.isScalar() ? LLT::scalar(SizeAndAction.firs<wbr class="">t)<br class="">
>> +                                 : LLT::pointer(Aspect.Type.getAd<wbr class="">dressSpace(),<br class="">
>> +                                                SizeAndAction.first)};<br class="">
>> +}<br class="">
>> +<br class="">
>> +std::pair<LegalizerInfo::Lega<wbr class="">lizeAction, LLT><br class="">
>> +LegalizerInfo::findVectorLega<wbr class="">lAction(const InstrAspect &Aspect) const {<br class="">
>> +  assert(Aspect.Type.isVector())<wbr class="">;<br class="">
>> +  // First legalize the vector element size, then legalize the number of<br class="">
>> +  // lanes in the vector.<br class="">
>> +  if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)<br class="">
>> +    return {NotFound, Aspect.Type};<br class="">
>> +  const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;<br class="">
>> +  const unsigned TypeIdx = Aspect.Idx;<br class="">
>> +  if (TypeIdx >= ScalarInVectorActions[OpcodeId<wbr class="">x].size())<br class="">
>> +    return {NotFound, Aspect.Type};<br class="">
>> +  const SizeAndActionsVec &ElemSizeVec =<br class="">
>> +      ScalarInVectorActions[OpcodeId<wbr class="">x][TypeIdx];<br class="">
>> +<br class="">
>> +  LLT IntermediateType;<br class="">
>> +  auto ElementSizeAndAction =<br class="">
>> +      findAction(ElemSizeVec, Aspect.Type.getScalarSizeInBit<wbr class="">s());<br class="">
>> +  IntermediateType =<br class="">
>> +      LLT::vector(Aspect.Type.getNum<wbr class="">Elements(), ElementSizeAndAction.first);<br class="">
>> +  if (ElementSizeAndAction.second != Legal)<br class="">
>> +    return {ElementSizeAndAction.second, IntermediateType};<br class="">
>> +<br class="">
>> +  auto i = NumElements2Actions[OpcodeIdx]<wbr class="">.find(<br class="">
>> +      IntermediateType.getScalarSize<wbr class="">InBits());<br class="">
>> +  if (i == NumElements2Actions[OpcodeIdx]<wbr class="">.end()) {<br class="">
>> +    return {NotFound, IntermediateType};<br class="">
>> +  }<br class="">
>> +  const SizeAndActionsVec &NumElementsVec = (*i).second[TypeIdx];<br class="">
>> +  auto NumElementsAndAction =<br class="">
>> +      findAction(NumElementsVec, IntermediateType.getNumElement<wbr class="">s());<br class="">
>> +  return {NumElementsAndAction.second,<br class="">
>> +          LLT::vector(NumElementsAndActi<wbr class="">on.first,<br class="">
>> +                      IntermediateType.getScalarSize<wbr class="">InBits())};<br class="">
>> }<br class="">
>><br class="">
>> Modified: llvm/trunk/lib/Support/LowLeve<wbr class="">lType.cpp<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/LowLevelType.cpp?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/lib/Support/<wbr class="">LowLevelType.cpp?rev=317560&<wbr class="">r1=317559&r2=317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/lib/Support/LowLeve<wbr class="">lType.cpp (original)<br class="">
>> +++ llvm/trunk/lib/Support/LowLeve<wbr class="">lType.cpp Tue Nov  7 02:34:34 2017<br class="">
>> @@ -43,7 +43,7 @@ void LLT::print(raw_ostream &OS) const {<br class="">
>>    assert(isScalar() && "unexpected type");<br class="">
>>    OS << "s" << getScalarSizeInBits();<br class="">
>>  } else<br class="">
>> -    llvm_unreachable("trying to print an invalid type");<br class="">
>> +    OS << "LLT_invalid";<br class="">
>> }<br class="">
>><br class="">
>> const constexpr LLT::BitFieldInfo LLT::ScalarSizeFieldInfo;<br class="">
>><br class="">
>> Modified: llvm/trunk/lib/Target/AArch64/<wbr class="">AArch64LegalizerInfo.cpp<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/lib/Target/AA<wbr class="">rch64/AArch64LegalizerInfo.cpp<wbr class="">?rev=317560&r1=317559&r2=31756<wbr class="">0&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/lib/Target/AArch64/<wbr class="">AArch64LegalizerInfo.cpp (original)<br class="">
>> +++ llvm/trunk/lib/Target/AArch64/<wbr class="">AArch64LegalizerInfo.cpp Tue Nov  7 02:34:34 2017<br class="">
>> @@ -23,6 +23,110 @@<br class="">
>><br class="">
>> using namespace llvm;<br class="">
>><br class="">
>> +/// FIXME: The following static functions are SizeChangeStrategy functions<br class="">
>> +/// that are meant to temporarily mimic the behaviour of the old legalization<br class="">
>> +/// based on doubling/halving non-legal types as closely as possible. This is<br class="">
>> +/// not entirly possible as only legalizing the types that are exactly a power<br class="">
>> +/// of 2 times the size of the legal types would require specifying all those<br class="">
>> +/// sizes explicitly.<br class="">
>> +/// In practice, not specifying those isn't a problem, and the below functions<br class="">
>> +/// should disappear quickly as we add support for legalizing non-power-of-2<br class="">
>> +/// sized types further.<br class="">
>> +static void<br class="">
>> +addAndInterleaveWithUnsupport<wbr class="">ed(LegalizerInfo::SizeAndActio<wbr class="">nsVec &result,<br class="">
>> +                                const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  for (unsigned i = 0; i < v.size(); ++i) {<br class="">
>> +    result.push_back(v[i]);<br class="">
>> +    if (i + 1 < v[i].first && i + 1 < v.size() &&<br class="">
>> +        v[i + 1].first != v[i].first + 1)<br class="">
>> +      result.push_back({v[i].first + 1, LegalizerInfo::Unsupported});<br class="">
>> +  }<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_1_narrow_128_ToLargest(<wbr class="">const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 2);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {{1, LegalizerInfo::WidenScalar},<br class="">
>> +                                             {2, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  assert(Largest + 1 < 128);<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::Unsupported});<br class="">
>> +  result.push_back({128, LegalizerInfo::NarrowScalar});<br class="">
>> +  result.push_back({129, LegalizerInfo::Unsupported});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_16(const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 17);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {{1, LegalizerInfo::Unsupported},<br class="">
>> +                                             {16, LegalizerInfo::WidenScalar},<br class="">
>> +                                             {17, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::Unsupported});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_1_8(const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 9);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {<br class="">
>> +      {1, LegalizerInfo::WidenScalar},  {2, LegalizerInfo::Unsupported},<br class="">
>> +      {8, LegalizerInfo::WidenScalar},  {9, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::Unsupported});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_1_8_16(const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 17);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {<br class="">
>> +      {1, LegalizerInfo::WidenScalar},  {2, LegalizerInfo::Unsupported},<br class="">
>> +      {8, LegalizerInfo::WidenScalar},  {9, LegalizerInfo::Unsupported},<br class="">
>> +      {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::Unsupported});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_1_8_16_narrowToLargest(<wbr class="">const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 17);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {<br class="">
>> +      {1, LegalizerInfo::WidenScalar},  {2, LegalizerInfo::Unsupported},<br class="">
>> +      {8, LegalizerInfo::WidenScalar},  {9, LegalizerInfo::Unsupported},<br class="">
>> +      {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::NarrowScalar});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_1_8_16_32(const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 33);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {<br class="">
>> +      {1, LegalizerInfo::WidenScalar},  {2, LegalizerInfo::Unsupported},<br class="">
>> +      {8, LegalizerInfo::WidenScalar},  {9, LegalizerInfo::Unsupported},<br class="">
>> +      {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported},<br class="">
>> +      {32, LegalizerInfo::WidenScalar}, {33, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::Unsupported});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> AArch64LegalizerInfo::AArch64L<wbr class="">egalizerInfo() {<br class="">
>>  using namespace TargetOpcode;<br class="">
>>  const LLT p0 = LLT::pointer(0, 64);<br class="">
>> @@ -42,8 +146,7 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>  for (auto Ty : {s16, s32, s64, p0})<br class="">
>>    setAction({G_PHI, Ty}, Legal);<br class="">
>><br class="">
>> -  for (auto Ty : {s1, s8})<br class="">
>> -    setAction({G_PHI, Ty}, WidenScalar);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_PHI, 0, widen_1_8);<br class="">
>><br class="">
>>  for (auto Ty : { s32, s64 })<br class="">
>>    setAction({G_BSWAP, Ty}, Legal);<br class="">
>> @@ -54,15 +157,15 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>    for (auto Ty : {s32, s64, v2s32, v4s32, v2s64})<br class="">
>>      setAction({BinOp, Ty}, Legal);<br class="">
>><br class="">
>> -    for (auto Ty : {s1, s8, s16})<br class="">
>> -      setAction({BinOp, Ty}, WidenScalar);<br class="">
>> +    if (BinOp != G_ADD)<br class="">
>> +      setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(BinOp, 0,<br class="">
>> +                                               widen_1_8_16_narrowToLargest)<wbr class="">;<br class="">
>>  }<br class="">
>><br class="">
>>  setAction({G_GEP, p0}, Legal);<br class="">
>>  setAction({G_GEP, 1, s64}, Legal);<br class="">
>><br class="">
>> -  for (auto Ty : {s1, s8, s16, s32})<br class="">
>> -    setAction({G_GEP, 1, Ty}, WidenScalar);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_GEP, 1, widen_1_8_16_32);<br class="">
>><br class="">
>>  setAction({G_PTR_MASK, p0}, Legal);<br class="">
>><br class="">
>> @@ -70,16 +173,17 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>    for (auto Ty : {s32, s64})<br class="">
>>      setAction({BinOp, Ty}, Legal);<br class="">
>><br class="">
>> -    for (auto Ty : {s1, s8, s16})<br class="">
>> -      setAction({BinOp, Ty}, WidenScalar);<br class="">
>> +    setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(BinOp, 0, widen_1_8_16);<br class="">
>>  }<br class="">
>><br class="">
>>  for (unsigned BinOp : {G_SREM, G_UREM})<br class="">
>>    for (auto Ty : { s1, s8, s16, s32, s64 })<br class="">
>>      setAction({BinOp, Ty}, Lower);<br class="">
>><br class="">
>> -  for (unsigned Op : {G_SMULO, G_UMULO})<br class="">
>> -      setAction({Op, s64}, Lower);<br class="">
>> +  for (unsigned Op : {G_SMULO, G_UMULO}) {<br class="">
>> +    setAction({Op, 0, s64}, Lower);<br class="">
>> +    setAction({Op, 1, s1}, Legal);<br class="">
>> +  }<br class="">
>><br class="">
>>  for (unsigned Op : {G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_SMULH, G_UMULH}) {<br class="">
>>    for (auto Ty : { s32, s64 })<br class="">
>> @@ -101,8 +205,9 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>    setAction({G_INSERT, Ty}, Legal);<br class="">
>>    setAction({G_INSERT, 1, Ty}, Legal);<br class="">
>>  }<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_INSERT, 0,<br class="">
>> +                                           widen_1_8_16_narrowToLargest)<wbr class="">;<br class="">
>>  for (auto Ty : {s1, s8, s16}) {<br class="">
>> -    setAction({G_INSERT, Ty}, WidenScalar);<br class="">
>>    setAction({G_INSERT, 1, Ty}, Legal);<br class="">
>>    // FIXME: Can't widen the sources because that violates the constraints on<br class="">
>>    // G_INSERT (It seems entirely reasonable that inputs shouldn't overlap).<br class="">
>> @@ -118,7 +223,8 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>    for (auto Ty : {s8, s16, s32, s64, p0, v2s32})<br class="">
>>      setAction({MemOp, Ty}, Legal);<br class="">
>><br class="">
>> -    setAction({MemOp, s1}, WidenScalar);<br class="">
>> +    setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(MemOp, 0,<br class="">
>> +                                             widen_1_narrow_128_ToLargest)<wbr class="">;<br class="">
>><br class="">
>>    // And everything's fine in addrspace 0.<br class="">
>>    setAction({MemOp, 1, p0}, Legal);<br class="">
>> @@ -132,20 +238,16 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>><br class="">
>>  setAction({G_CONSTANT, p0}, Legal);<br class="">
>><br class="">
>> -  for (auto Ty : {s1, s8, s16})<br class="">
>> -    setAction({TargetOpcode::G_CON<wbr class="">STANT, Ty}, WidenScalar);<br class="">
>> -<br class="">
>> -  setAction({TargetOpcode::G_FCO<wbr class="">NSTANT, s16}, WidenScalar);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_CONSTANT, 0, widen_1_8_16);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_FCONSTANT, 0, widen_16);<br class="">
>><br class="">
>>  setAction({G_ICMP, 1, s32}, Legal);<br class="">
>>  setAction({G_ICMP, 1, s64}, Legal);<br class="">
>>  setAction({G_ICMP, 1, p0}, Legal);<br class="">
>><br class="">
>> -  for (auto Ty : {s1, s8, s16}) {<br class="">
>> -    setAction({G_ICMP, Ty}, WidenScalar);<br class="">
>> -    setAction({G_FCMP, Ty}, WidenScalar);<br class="">
>> -    setAction({G_ICMP, 1, Ty}, WidenScalar);<br class="">
>> -  }<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_ICMP, 0, widen_1_8_16);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_FCMP, 0, widen_1_8_16);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_ICMP, 1, widen_1_8_16);<br class="">
>><br class="">
>>  setAction({G_ICMP, s32}, Legal);<br class="">
>>  setAction({G_FCMP, s32}, Legal);<br class="">
>> @@ -159,12 +261,6 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>    setAction({G_ANYEXT, Ty}, Legal);<br class="">
>>  }<br class="">
>><br class="">
>> -  for (auto Ty : { s1, s8, s16, s32 }) {<br class="">
>> -    setAction({G_ZEXT, 1, Ty}, Legal);<br class="">
>> -    setAction({G_SEXT, 1, Ty}, Legal);<br class="">
>> -    setAction({G_ANYEXT, 1, Ty}, Legal);<br class="">
>> -  }<br class="">
>> -<br class="">
>>  // FP conversions<br class="">
>>  for (auto Ty : { s16, s32 }) {<br class="">
>>    setAction({G_FPTRUNC, Ty}, Legal);<br class="">
>> @@ -176,12 +272,6 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>    setAction({G_FPEXT, Ty}, Legal);<br class="">
>>  }<br class="">
>><br class="">
>> -  for (auto Ty : { s1, s8, s16, s32 })<br class="">
>> -    setAction({G_TRUNC, Ty}, Legal);<br class="">
>> -<br class="">
>> -  for (auto Ty : { s8, s16, s32, s64 })<br class="">
>> -    setAction({G_TRUNC, 1, Ty}, Legal);<br class="">
>> -<br class="">
>>  // Conversions<br class="">
>>  for (auto Ty : { s32, s64 }) {<br class="">
>>    setAction({G_FPTOSI, 0, Ty}, Legal);<br class="">
>> @@ -189,12 +279,10 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>    setAction({G_SITOFP, 1, Ty}, Legal);<br class="">
>>    setAction({G_UITOFP, 1, Ty}, Legal);<br class="">
>>  }<br class="">
>> -  for (auto Ty : { s1, s8, s16 }) {<br class="">
>> -    setAction({G_FPTOSI, 0, Ty}, WidenScalar);<br class="">
>> -    setAction({G_FPTOUI, 0, Ty}, WidenScalar);<br class="">
>> -    setAction({G_SITOFP, 1, Ty}, WidenScalar);<br class="">
>> -    setAction({G_UITOFP, 1, Ty}, WidenScalar);<br class="">
>> -  }<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_FPTOSI, 0, widen_1_8_16);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_FPTOUI, 0, widen_1_8_16);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_SITOFP, 1, widen_1_8_16);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_UITOFP, 1, widen_1_8_16);<br class="">
>><br class="">
>>  for (auto Ty : { s32, s64 }) {<br class="">
>>    setAction({G_FPTOSI, 1, Ty}, Legal);<br class="">
>> @@ -209,8 +297,7 @@ AArch64LegalizerInfo::AArch64L<wbr class="">egalizerIn<br class="">
>>  setAction({G_BRINDIRECT, p0}, Legal);<br class="">
>><br class="">
>>  // Select<br class="">
>> -  for (auto Ty : {s1, s8, s16})<br class="">
>> -    setAction({G_SELECT, Ty}, WidenScalar);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_SELECT, 0, widen_1_8_16);<br class="">
>><br class="">
>>  for (auto Ty : {s32, s64, p0})<br class="">
>>    setAction({G_SELECT, Ty}, Legal);<br class="">
>><br class="">
>> Modified: llvm/trunk/lib/Target/ARM/ARML<wbr class="">egalizerInfo.cpp<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/lib/Target/AR<wbr class="">M/ARMLegalizerInfo.cpp?rev=317<wbr class="">560&r1=317559&r2=317560&view=<wbr class="">diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/lib/Target/ARM/ARML<wbr class="">egalizerInfo.cpp (original)<br class="">
>> +++ llvm/trunk/lib/Target/ARM/ARML<wbr class="">egalizerInfo.cpp Tue Nov  7 02:34:34 2017<br class="">
>> @@ -24,6 +24,54 @@<br class="">
>><br class="">
>> using namespace llvm;<br class="">
>><br class="">
>> +/// FIXME: The following static functions are SizeChangeStrategy functions<br class="">
>> +/// that are meant to temporarily mimic the behaviour of the old legalization<br class="">
>> +/// based on doubling/halving non-legal types as closely as possible. This is<br class="">
>> +/// not entirly possible as only legalizing the types that are exactly a power<br class="">
>> +/// of 2 times the size of the legal types would require specifying all those<br class="">
>> +/// sizes explicitly.<br class="">
>> +/// In practice, not specifying those isn't a problem, and the below functions<br class="">
>> +/// should disappear quickly as we add support for legalizing non-power-of-2<br class="">
>> +/// sized types further.<br class="">
>> +static void<br class="">
>> +addAndInterleaveWithUnsupport<wbr class="">ed(LegalizerInfo::SizeAndActio<wbr class="">nsVec &result,<br class="">
>> +                                const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  for (unsigned i = 0; i < v.size(); ++i) {<br class="">
>> +    result.push_back(v[i]);<br class="">
>> +    if (i + 1 < v[i].first && i + 1 < v.size() &&<br class="">
>> +        v[i + 1].first != v[i].first + 1)<br class="">
>> +      result.push_back({v[i].first + 1, LegalizerInfo::Unsupported});<br class="">
>> +  }<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_8_16(const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 17);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {<br class="">
>> +      {1, LegalizerInfo::Unsupported},<br class="">
>> +      {8, LegalizerInfo::WidenScalar},  {9, LegalizerInfo::Unsupported},<br class="">
>> +      {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::Unsupported});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_1_8_16(const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 17);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {<br class="">
>> +      {1, LegalizerInfo::WidenScalar},  {2, LegalizerInfo::Unsupported},<br class="">
>> +      {8, LegalizerInfo::WidenScalar},  {9, LegalizerInfo::Unsupported},<br class="">
>> +      {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::Unsupported});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> static bool AEABI(const ARMSubtarget &ST) {<br class="">
>>  return ST.isTargetAEABI() || ST.isTargetGNUAEABI() || ST.isTargetMuslAEABI();<br class="">
>> }<br class="">
>> @@ -49,14 +97,15 @@ ARMLegalizerInfo::ARMLegalizer<wbr class="">Info(const<br class="">
>>  }<br class="">
>><br class="">
>>  for (unsigned Op : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) {<br class="">
>> -    for (auto Ty : {s1, s8, s16})<br class="">
>> -      setAction({Op, Ty}, WidenScalar);<br class="">
>> +    if (Op != G_ADD)<br class="">
>> +      setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +          Op, 0, widenToLargerTypesUnsupportedO<wbr class="">therwise);<br class="">
>>    setAction({Op, s32}, Legal);<br class="">
>>  }<br class="">
>><br class="">
>>  for (unsigned Op : {G_SDIV, G_UDIV}) {<br class="">
>> -    for (auto Ty : {s8, s16})<br class="">
>> -      setAction({Op, Ty}, WidenScalar);<br class="">
>> +    setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(Op, 0,<br class="">
>> +        widenToLargerTypesUnsupportedO<wbr class="">therwise);<br class="">
>>    if (ST.hasDivideInARMMode())<br class="">
>>      setAction({Op, s32}, Legal);<br class="">
>>    else<br class="">
>> @@ -64,8 +113,7 @@ ARMLegalizerInfo::ARMLegalizer<wbr class="">Info(const<br class="">
>>  }<br class="">
>><br class="">
>>  for (unsigned Op : {G_SREM, G_UREM}) {<br class="">
>> -    for (auto Ty : {s8, s16})<br class="">
>> -      setAction({Op, Ty}, WidenScalar);<br class="">
>> +    setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(Op, 0, widen_8_16);<br class="">
>>    if (ST.hasDivideInARMMode())<br class="">
>>      setAction({Op, s32}, Lower);<br class="">
>>    else if (AEABI(ST))<br class="">
>> @@ -74,10 +122,8 @@ ARMLegalizerInfo::ARMLegalizer<wbr class="">Info(const<br class="">
>>      setAction({Op, s32}, Libcall);<br class="">
>>  }<br class="">
>><br class="">
>> -  for (unsigned Op : {G_SEXT, G_ZEXT}) {<br class="">
>> +  for (unsigned Op : {G_SEXT, G_ZEXT, G_ANYEXT}) {<br class="">
>>    setAction({Op, s32}, Legal);<br class="">
>> -    for (auto Ty : {s1, s8, s16})<br class="">
>> -      setAction({Op, 1, Ty}, Legal);<br class="">
>>  }<br class="">
>><br class="">
>>  for (unsigned Op : {G_ASHR, G_LSHR, G_SHL})<br class="">
>> @@ -93,12 +139,11 @@ ARMLegalizerInfo::ARMLegalizer<wbr class="">Info(const<br class="">
>>  setAction({G_BRCOND, s1}, Legal);<br class="">
>><br class="">
>>  setAction({G_CONSTANT, s32}, Legal);<br class="">
>> -  for (auto Ty : {s1, s8, s16})<br class="">
>> -    setAction({G_CONSTANT, Ty}, WidenScalar);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_CONSTANT, 0, widen_1_8_16);<br class="">
>><br class="">
>>  setAction({G_ICMP, s1}, Legal);<br class="">
>> -  for (auto Ty : {s8, s16})<br class="">
>> -    setAction({G_ICMP, 1, Ty}, WidenScalar);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_ICMP, 1,<br class="">
>> +      widenToLargerTypesUnsupportedO<wbr class="">therwise);<br class="">
>>  for (auto Ty : {s32, p0})<br class="">
>>    setAction({G_ICMP, 1, Ty}, Legal);<br class="">
>><br class="">
>><br class="">
>> Modified: llvm/trunk/lib/Target/X86/X86L<wbr class="">egalizerInfo.cpp<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/lib/Target/X8<wbr class="">6/X86LegalizerInfo.cpp?rev=317<wbr class="">560&r1=317559&r2=317560&view=<wbr class="">diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/lib/Target/X86/X86L<wbr class="">egalizerInfo.cpp (original)<br class="">
>> +++ llvm/trunk/lib/Target/X86/X86L<wbr class="">egalizerInfo.cpp Tue Nov  7 02:34:34 2017<br class="">
>> @@ -22,6 +22,38 @@<br class="">
>> using namespace llvm;<br class="">
>> using namespace TargetOpcode;<br class="">
>><br class="">
>> +/// FIXME: The following static functions are SizeChangeStrategy functions<br class="">
>> +/// that are meant to temporarily mimic the behaviour of the old legalization<br class="">
>> +/// based on doubling/halving non-legal types as closely as possible. This is<br class="">
>> +/// not entirly possible as only legalizing the types that are exactly a power<br class="">
>> +/// of 2 times the size of the legal types would require specifying all those<br class="">
>> +/// sizes explicitly.<br class="">
>> +/// In practice, not specifying those isn't a problem, and the below functions<br class="">
>> +/// should disappear quickly as we add support for legalizing non-power-of-2<br class="">
>> +/// sized types further.<br class="">
>> +static void<br class="">
>> +addAndInterleaveWithUnsupport<wbr class="">ed(LegalizerInfo::SizeAndActio<wbr class="">nsVec &result,<br class="">
>> +                                const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  for (unsigned i = 0; i < v.size(); ++i) {<br class="">
>> +    result.push_back(v[i]);<br class="">
>> +    if (i + 1 < v[i].first && i + 1 < v.size() &&<br class="">
>> +        v[i + 1].first != v[i].first + 1)<br class="">
>> +      result.push_back({v[i].first + 1, LegalizerInfo::Unsupported});<br class="">
>> +  }<br class="">
>> +}<br class="">
>> +<br class="">
>> +static LegalizerInfo::SizeAndActionsV<wbr class="">ec<br class="">
>> +widen_1(const LegalizerInfo::SizeAndActionsV<wbr class="">ec &v) {<br class="">
>> +  assert(v.size() >= 1);<br class="">
>> +  assert(v[0].first > 1);<br class="">
>> +  LegalizerInfo::SizeAndActionsV<wbr class="">ec result = {{1, LegalizerInfo::WidenScalar},<br class="">
>> +                                             {2, LegalizerInfo::Unsupported}};<br class="">
>> +  addAndInterleaveWithUnsupporte<wbr class="">d(result, v);<br class="">
>> +  auto Largest = result.back().first;<br class="">
>> +  result.push_back({Largest + 1, LegalizerInfo::Unsupported});<br class="">
>> +  return result;<br class="">
>> +}<br class="">
>> +<br class="">
>> X86LegalizerInfo::X86Legalizer<wbr class="">Info(const X86Subtarget &STI,<br class="">
>>                                   const X86TargetMachine &TM)<br class="">
>>    : Subtarget(STI), TM(TM) {<br class="">
>> @@ -37,6 +69,17 @@ X86LegalizerInfo::X86Legalizer<wbr class="">Info(const<br class="">
>>  setLegalizerInfoAVX512DQ();<br class="">
>>  setLegalizerInfoAVX512BW();<br class="">
>><br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(G_PHI, 0, widen_1);<br class="">
>> +  for (unsigned BinOp : {G_SUB, G_MUL, G_AND, G_OR, G_XOR})<br class="">
>> +    setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(BinOp, 0, widen_1);<br class="">
>> +  for (unsigned MemOp : {G_LOAD, G_STORE})<br class="">
>> +    setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(MemOp, 0,<br class="">
>> +       <wbr class="">narrowToSmallerAndWidenToSmall<wbr class="">est);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      G_GEP, 1, widenToLargerTypesUnsupportedO<wbr class="">therwise);<br class="">
>> +  setLegalizeScalarToDifferentSi<wbr class="">zeStrategy(<br class="">
>> +      G_CONSTANT, 0, widenToLargerTypesAndNarrowToL<wbr class="">argest);<br class="">
>> +<br class="">
>>  computeTables();<br class="">
>> }<br class="">
>><br class="">
>> @@ -47,7 +90,6 @@ void X86LegalizerInfo::setLegalizer<wbr class="">Info3<br class="">
>>  const LLT s8 = LLT::scalar(8);<br class="">
>>  const LLT s16 = LLT::scalar(16);<br class="">
>>  const LLT s32 = LLT::scalar(32);<br class="">
>> -  const LLT s64 = LLT::scalar(64);<br class="">
>><br class="">
>>  for (auto Ty : {p0, s1, s8, s16, s32})<br class="">
>>    setAction({G_IMPLICIT_DEF, Ty}, Legal);<br class="">
>> @@ -55,15 +97,10 @@ void X86LegalizerInfo::setLegalizer<wbr class="">Info3<br class="">
>>  for (auto Ty : {s8, s16, s32, p0})<br class="">
>>    setAction({G_PHI, Ty}, Legal);<br class="">
>><br class="">
>> -  setAction({G_PHI, s1}, WidenScalar);<br class="">
>> -<br class="">
>> -  for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) {<br class="">
>> +  for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR})<br class="">
>>    for (auto Ty : {s8, s16, s32})<br class="">
>>      setAction({BinOp, Ty}, Legal);<br class="">
>><br class="">
>> -    setAction({BinOp, s1}, WidenScalar);<br class="">
>> -  }<br class="">
>> -<br class="">
>>  for (unsigned Op : {G_UADDE}) {<br class="">
>>    setAction({Op, s32}, Legal);<br class="">
>>    setAction({Op, 1, s1}, Legal);<br class="">
>> @@ -73,7 +110,6 @@ void X86LegalizerInfo::setLegalizer<wbr class="">Info3<br class="">
>>    for (auto Ty : {s8, s16, s32, p0})<br class="">
>>      setAction({MemOp, Ty}, Legal);<br class="">
>><br class="">
>> -    setAction({MemOp, s1}, WidenScalar);<br class="">
>>    // And everything's fine in addrspace 0.<br class="">
>>    setAction({MemOp, 1, p0}, Legal);<br class="">
>>  }<br class="">
>> @@ -85,9 +121,6 @@ void X86LegalizerInfo::setLegalizer<wbr class="">Info3<br class="">
>>  setAction({G_GEP, p0}, Legal);<br class="">
>>  setAction({G_GEP, 1, s32}, Legal);<br class="">
>><br class="">
>> -  for (auto Ty : {s1, s8, s16})<br class="">
>> -    setAction({G_GEP, 1, Ty}, WidenScalar);<br class="">
>> -<br class="">
>>  // Control-flow<br class="">
>>  setAction({G_BRCOND, s1}, Legal);<br class="">
>><br class="">
>> @@ -95,9 +128,6 @@ void X86LegalizerInfo::setLegalizer<wbr class="">Info3<br class="">
>>  for (auto Ty : {s8, s16, s32, p0})<br class="">
>>    setAction({TargetOpcode::G_CON<wbr class="">STANT, Ty}, Legal);<br class="">
>><br class="">
>> -  setAction({TargetOpcode::G_CON<wbr class="">STANT, s1}, WidenScalar);<br class="">
>> -  setAction({TargetOpcode::G_CON<wbr class="">STANT, s64}, NarrowScalar);<br class="">
>> -<br class="">
>>  // Extensions<br class="">
>>  for (auto Ty : {s8, s16, s32}) {<br class="">
>>    setAction({G_ZEXT, Ty}, Legal);<br class="">
>> @@ -105,12 +135,6 @@ void X86LegalizerInfo::setLegalizer<wbr class="">Info3<br class="">
>>    setAction({G_ANYEXT, Ty}, Legal);<br class="">
>>  }<br class="">
>><br class="">
>> -  for (auto Ty : {s1, s8, s16}) {<br class="">
>> -    setAction({G_ZEXT, 1, Ty}, Legal);<br class="">
>> -    setAction({G_SEXT, 1, Ty}, Legal);<br class="">
>> -    setAction({G_ANYEXT, 1, Ty}, Legal);<br class="">
>> -  }<br class="">
>> -<br class="">
>>  // Comparison<br class="">
>>  setAction({G_ICMP, s1}, Legal);<br class="">
>><br class="">
>> @@ -123,7 +147,6 @@ void X86LegalizerInfo::setLegalizer<wbr class="">Info6<br class="">
>>  if (!Subtarget.is64Bit())<br class="">
>>    return;<br class="">
>><br class="">
>> -  const LLT s32 = LLT::scalar(32);<br class="">
>>  const LLT s64 = LLT::scalar(64);<br class="">
>><br class="">
>>  setAction({G_IMPLICIT_DEF, s64}, Legal);<br class="">
>> @@ -145,7 +168,6 @@ void X86LegalizerInfo::setLegalizer<wbr class="">Info6<br class="">
>>  // Extensions<br class="">
>>  for (unsigned extOp : {G_ZEXT, G_SEXT, G_ANYEXT}) {<br class="">
>>    setAction({extOp, s64}, Legal);<br class="">
>> -    setAction({extOp, 1, s32}, Legal);<br class="">
>>  }<br class="">
>><br class="">
>>  // Comparison<br class="">
>><br class="">
>> Modified: llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/arm64-fallback.ll<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/test/CodeGen/<wbr class="">AArch64/GlobalISel/arm64-<wbr class="">fallback.ll?rev=317560&r1=<wbr class="">317559&r2=317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/arm64-fallback.ll (original)<br class="">
>> +++ llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/arm64-fallback.ll Tue Nov  7 02:34:34 2017<br class="">
>> @@ -167,3 +167,70 @@ end:<br class="">
>>  %vec = load <2 x i16*>, <2 x i16*>* undef<br class="">
>>  br label %block<br class="">
>> }<br class="">
>> +<br class="">
>> +; FALLBACK-WITH-REPORT-ERR-G_IMP<wbr class="">LICIT_DEF-LEGALIZABLE: (FIXME: this is what is expected once we can legalize non-pow-of-2 G_IMPLICIT_DEF) remark: <unknown>:0:0: unable to legalize instruction: %vreg1<def>(s96) = G_INSERT %vreg2, %vreg0, 0;
 (in function: nonpow2_insertvalue_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg2<def>(s96) = G_IMPLICIT_DEF; (in function: nonpow2_insertvalue_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_insertvalue_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-OUT-LABEL<wbr class="">: nonpow2_insertvalue_narrowing:<br class="">
>> +%struct96 = type { float, float, float }<br class="">
>> +define void @nonpow2_insertvalue_narrowing<wbr class="">(float %a) {<br class="">
>> +  %dummy = insertvalue %struct96 undef, float %a, 0<br class="">
>> +  ret void<br class="">
>> +}<br class="">
>> +<br class="">
>> +; FALLBACK-WITH-REPORT-ERR remark: <unknown>:0:0: unable to legalize instruction: %vreg3<def>(s96) = G_ADD %vreg2, %vreg2; (in function: nonpow2_add_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_add_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-OUT-LABEL<wbr class="">: nonpow2_add_narrowing:<br class="">
>> +define void @nonpow2_add_narrowing() {<br class="">
>> +  %a = add i128 undef, undef<br class="">
>> +  %b = trunc i128 %a to i96<br class="">
>> +  %dummy = add i96 %b, %b<br class="">
>> +  ret void<br class="">
>> +}<br class="">
>> +<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg3<def>(s96) = G_OR %vreg2, %vreg2; (in function: nonpow2_or_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_or_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-OUT-LABEL<wbr class="">: nonpow2_or_narrowing:<br class="">
>> +define void @nonpow2_or_narrowing() {<br class="">
>> +  %a = add i128 undef, undef<br class="">
>> +  %b = trunc i128 %a to i96<br class="">
>> +  %dummy = or i96 %b, %b<br class="">
>> +  ret void<br class="">
>> +}<br class="">
>> +<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg0<def>(s96) = G_LOAD %vreg1; mem:LD12[undef](align=16) (in function: nonpow2_load_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_load_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-OUT-LABEL<wbr class="">: nonpow2_load_narrowing:<br class="">
>> +define void @nonpow2_load_narrowing() {<br class="">
>> +  %dummy = load i96, i96* undef<br class="">
>> +  ret void<br class="">
>> +}<br class="">
>> +<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: G_STORE %vreg3, %vreg0; mem:ST12[%c](align=16) (in function: nonpow2_store_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_store_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-OUT-LABEL<wbr class="">: nonpow2_store_narrowing:<br class="">
>> +define void @nonpow2_store_narrowing(i96* %c) {<br class="">
>> +  %a = add i128 undef, undef<br class="">
>> +  %b = trunc i128 %a to i96<br class="">
>> +  store i96 %b, i96* %c<br class="">
>> +  ret void<br class="">
>> +}<br class="">
>> +<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg0<def>(s96) = G_CONSTANT 0; (in function: nonpow2_constant_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_constant_narrowing<br class="">
>> +; FALLBACK-WITH-REPORT-OUT-LABEL<wbr class="">: nonpow2_constant_narrowing:<br class="">
>> +define void @nonpow2_constant_narrowing() {<br class="">
>> +  store i96 0, i96* undef<br class="">
>> +  ret void<br class="">
>> +}<br class="">
>> +<br class="">
>> +; Currently can't handle vector lengths that aren't an exact multiple of<br class="">
>> +; natively supported vector lengths. Test that the fall-back works for those.<br class="">
>> +; FALLBACK-WITH-REPORT-ERR-G_IMP<wbr class="">LICIT_DEF-LEGALIZABLE: (FIXME: this is what is expected once we can legalize non-pow-of-2 G_IMPLICIT_DEF) remark: <unknown>:0:0: unable to legalize instruction: %vreg1<def>(<7 x s64>) = G_ADD %vreg0, %vreg0;
 (in function: nonpow2_vector_add_fewerelemen<wbr class="">ts<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg0<def>(<7 x s64>) = G_IMPLICIT_DEF; (in function: nonpow2_vector_add_fewerelemen<wbr class="">ts<br class="">
>> +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_vector_add_fewerelemen<wbr class="">ts<br class="">
>> +; FALLBACK-WITH-REPORT-OUT-LABEL<wbr class="">: nonpow2_vector_add_fewerelemen<wbr class="">ts:<br class="">
>> +define void @nonpow2_vector_add_fewereleme<wbr class="">nts() {<br class="">
>> +  %dummy = add <7 x i64> undef, undef<br class="">
>> +  ret void<br class="">
>> +}<br class="">
>><br class="">
>> Modified: llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/legalize-add.mir<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/test/CodeGen/<wbr class="">AArch64/GlobalISel/legalize-<wbr class="">add.mir?rev=317560&r1=317559&<wbr class="">r2=317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/legalize-add.mir (original)<br class="">
>> +++ llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/legalize-add.mir Tue Nov  7 02:34:34 2017<br class="">
>> @@ -8,6 +8,10 @@<br class="">
>>  entry:<br class="">
>>    ret void<br class="">
>>  }<br class="">
>> +  define void @test_scalar_add_big_nonpow2() {<br class="">
>> +  entry:<br class="">
>> +    ret void<br class="">
>> +  }<br class="">
>>  define void @test_scalar_add_small() {<br class="">
>>  entry:<br class="">
>>    ret void<br class="">
>> @@ -16,6 +20,10 @@<br class="">
>>  entry:<br class="">
>>    ret void<br class="">
>>  }<br class="">
>> +  define void @test_vector_add_nonpow2() {<br class="">
>> +  entry:<br class="">
>> +    ret void<br class="">
>> +  }<br class="">
>> ...<br class="">
>><br class="">
>> ---<br class="">
>> @@ -58,6 +66,49 @@ body: |<br class="">
>> ...<br class="">
>><br class="">
>> ---<br class="">
>> +name:            test_scalar_add_big_nonpow2<br class="">
>> +registers:<br class="">
>> +  - { id: 0, class: _ }<br class="">
>> +  - { id: 1, class: _ }<br class="">
>> +  - { id: 2, class: _ }<br class="">
>> +  - { id: 3, class: _ }<br class="">
>> +  - { id: 4, class: _ }<br class="">
>> +  - { id: 5, class: _ }<br class="">
>> +  - { id: 6, class: _ }<br class="">
>> +  - { id: 7, class: _ }<br class="">
>> +  - { id: 8, class: _ }<br class="">
>> +  - { id: 9, class: _ }<br class="">
>> +body: |<br class="">
>> +  bb.0.entry:<br class="">
>> +    liveins: %x0, %x1, %x2, %x3<br class="">
>> +    ; CHECK-LABEL: name: test_scalar_add_big_nonpow2<br class="">
>> +    ; CHECK-NOT: G_MERGE_VALUES<br class="">
>> +    ; CHECK-NOT: G_UNMERGE_VALUES<br class="">
>> +    ; CHECK-DAG: [[CARRY0_32:%[0-9]+]]:_(s32) = G_CONSTANT i32 0<br class="">
>> +    ; CHECK-DAG: [[CARRY0:%[0-9]+]]:_(s1) = G_TRUNC [[CARRY0_32]]<br class="">
>> +    ; CHECK: [[RES_LO:%[0-9]+]]:_(s64), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE %0, %1, [[CARRY0]]<br class="">
>> +    ; CHECK: [[RES_MI:%[0-9]+]]:_(s64), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE %1, %2, [[CARRY1]]<br class="">
>> +    ; CHECK: [[RES_HI:%[0-9]+]]:_(s64), {{%.*}}(s1) = G_UADDE %2, %3, [[CARRY2]]<br class="">
>> +    ; CHECK-NOT: G_MERGE_VALUES<br class="">
>> +    ; CHECK-NOT: G_UNMERGE_VALUES<br class="">
>> +    ; CHECK: %x0 = COPY [[RES_LO]]<br class="">
>> +    ; CHECK: %x1 = COPY [[RES_MI]]<br class="">
>> +    ; CHECK: %x2 = COPY [[RES_HI]]<br class="">
>> +<br class="">
>> +    %0(s64) = COPY %x0<br class="">
>> +    %1(s64) = COPY %x1<br class="">
>> +    %2(s64) = COPY %x2<br class="">
>> +    %3(s64) = COPY %x3<br class="">
>> +    %4(s192) = G_MERGE_VALUES %0, %1, %2<br class="">
>> +    %5(s192) = G_MERGE_VALUES %1, %2, %3<br class="">
>> +    %6(s192) = G_ADD %4, %5<br class="">
>> +    %7(s64), %8(s64), %9(s64) = G_UNMERGE_VALUES %6<br class="">
>> +    %x0 = COPY %7<br class="">
>> +    %x1 = COPY %8<br class="">
>> +    %x2 = COPY %9<br class="">
>> +...<br class="">
>> +<br class="">
>> +---<br class="">
>> name:            test_scalar_add_small<br class="">
>> registers:<br class="">
>>  - { id: 0, class: _ }<br class="">
>> @@ -124,3 +175,43 @@ body: |<br class="">
>>    %q0 = COPY %7<br class="">
>>    %q1 = COPY %8<br class="">
>> ...<br class="">
>> +---<br class="">
>> +name:            test_vector_add_nonpow2<br class="">
>> +registers:<br class="">
>> +  - { id: 0, class: _ }<br class="">
>> +  - { id: 1, class: _ }<br class="">
>> +  - { id: 2, class: _ }<br class="">
>> +  - { id: 3, class: _ }<br class="">
>> +  - { id: 4, class: _ }<br class="">
>> +  - { id: 5, class: _ }<br class="">
>> +  - { id: 6, class: _ }<br class="">
>> +  - { id: 7, class: _ }<br class="">
>> +  - { id: 8, class: _ }<br class="">
>> +  - { id: 9, class: _ }<br class="">
>> +body: |<br class="">
>> +  bb.0.entry:<br class="">
>> +    liveins: %q0, %q1, %q2, %q3<br class="">
>> +    ; CHECK-LABEL: name: test_vector_add_nonpow2<br class="">
>> +    ; CHECK-NOT: G_EXTRACT<br class="">
>> +    ; CHECK-NOT: G_SEQUENCE<br class="">
>> +    ; CHECK: [[RES_LO:%[0-9]+]]:_(<2 x s64>) = G_ADD %0, %1<br class="">
>> +    ; CHECK: [[RES_MI:%[0-9]+]]:_(<2 x s64>) = G_ADD %1, %2<br class="">
>> +    ; CHECK: [[RES_HI:%[0-9]+]]:_(<2 x s64>) = G_ADD %2, %3<br class="">
>> +    ; CHECK-NOT: G_EXTRACT<br class="">
>> +    ; CHECK-NOT: G_SEQUENCE<br class="">
>> +    ; CHECK: %q0 = COPY [[RES_LO]]<br class="">
>> +    ; CHECK: %q1 = COPY [[RES_MI]]<br class="">
>> +    ; CHECK: %q2 = COPY [[RES_HI]]<br class="">
>> +<br class="">
>> +    %0(<2 x s64>) = COPY %q0<br class="">
>> +    %1(<2 x s64>) = COPY %q1<br class="">
>> +    %2(<2 x s64>) = COPY %q2<br class="">
>> +    %3(<2 x s64>) = COPY %q3<br class="">
>> +    %4(<6 x s64>) = G_MERGE_VALUES %0, %1, %2<br class="">
>> +    %5(<6 x s64>) = G_MERGE_VALUES %1, %2, %3<br class="">
>> +    %6(<6 x s64>) = G_ADD %4, %5<br class="">
>> +    %7(<2 x s64>), %8(<2 x s64>), %9(<2 x s64>) = G_UNMERGE_VALUES %6<br class="">
>> +    %q0 = COPY %7<br class="">
>> +    %q1 = COPY %8<br class="">
>> +    %q2 = COPY %9<br class="">
>> +...<br class="">
>><br class="">
>> Modified: llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/legalize-inserts.<wbr class="">mir<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-inserts.mir?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/test/CodeGen/<wbr class="">AArch64/GlobalISel/legalize-<wbr class="">inserts.mir?rev=317560&r1=<wbr class="">317559&r2=317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/legalize-inserts.<wbr class="">mir (original)<br class="">
>> +++ llvm/trunk/test/CodeGen/AArch6<wbr class="">4/GlobalISel/legalize-inserts.<wbr class="">mir Tue Nov  7 02:34:34 2017<br class="">
>> @@ -9,6 +9,7 @@<br class="">
>>  define void @test_inserts_4() { ret void }<br class="">
>>  define void @test_inserts_5() { ret void }<br class="">
>>  define void @test_inserts_6() { ret void }<br class="">
>> +  define void @test_inserts_nonpow2() { ret void }<br class="">
>> ...<br class="">
>><br class="">
>> ---<br class="">
>> @@ -141,3 +142,21 @@ body: |<br class="">
>>    %4:_(s128) = G_INSERT %3, %2, 32<br class="">
>>    RET_ReallyLR<br class="">
>> ...<br class="">
>> +<br class="">
>> +---<br class="">
>> +name:            test_inserts_nonpow2<br class="">
>> +body: |<br class="">
>> +  bb.0:<br class="">
>> +    liveins: %x0, %x1, %x2<br class="">
>> +<br class="">
>> +<br class="">
>> +    ; CHECK-LABEL: name: test_inserts_nonpow2<br class="">
>> +    ; CHECK: %5:_(s192) = G_MERGE_VALUES %3(s64), %1(s64), %2(s64)<br class="">
>> +    %0:_(s64) = COPY %x0<br class="">
>> +    %1:_(s64) = COPY %x1<br class="">
>> +    %2:_(s64) = COPY %x2<br class="">
>> +    %3:_(s64) = COPY %x3<br class="">
>> +    %4:_(s192) = G_MERGE_VALUES %0, %1, %2<br class="">
>> +    %5:_(s192) = G_INSERT %4, %3, 0<br class="">
>> +    RET_ReallyLR<br class="">
>> +...<br class="">
>><br class="">
>> Modified: llvm/trunk/test/CodeGen/ARM/Gl<wbr class="">obalISel/arm-instruction-selec<wbr class="">t.mir<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/test/CodeGen/<wbr class="">ARM/GlobalISel/arm-instruction<wbr class="">-select.mir?rev=317560&r1=<wbr class="">317559&r2=317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/test/CodeGen/ARM/Gl<wbr class="">obalISel/arm-instruction-selec<wbr class="">t.mir (original)<br class="">
>> +++ llvm/trunk/test/CodeGen/ARM/Gl<wbr class="">obalISel/arm-instruction-selec<wbr class="">t.mir Tue Nov  7 02:34:34 2017<br class="">
>> @@ -970,9 +970,10 @@ registers:<br class="">
>>  - { id: 1, class: gprb }<br class="">
>>  - { id: 2, class: gprb }<br class="">
>>  - { id: 3, class: gprb }<br class="">
>> +  - { id: 4, class: gprb }<br class="">
>> body:             |<br class="">
>>  bb.0:<br class="">
>> -    liveins: %r0, %r1<br class="">
>> +    liveins: %r0, %r1, %r2<br class="">
>><br class="">
>>    %0(p0) = COPY %r0<br class="">
>>    ; CHECK: [[VREGX:%[0-9]+]]:gpr = COPY %r0<br class="">
>> @@ -980,14 +981,17 @@ body:             |<br class="">
>>    %1(p0) = COPY %r1<br class="">
>>    ; CHECK: [[VREGY:%[0-9]+]]:gpr = COPY %r1<br class="">
>><br class="">
>> -    %2(s1) = G_TRUNC %1(p0)<br class="">
>> -    ; CHECK: [[VREGC:%[0-9]+]]:gpr = COPY [[VREGY]]<br class="">
>> +    %2(s32) = COPY %r2<br class="">
>> +    ; CHECK: [[VREGC:%[0-9]+]]:gpr = COPY %r2<br class="">
>><br class="">
>> -    %3(p0) = G_SELECT %2(s1),  %0, %1<br class="">
>> -    ; CHECK: CMPri [[VREGC]], 0, 14, _, implicit-def %cpsr<br class="">
>> +    %3(s1) = G_TRUNC %2(s32)<br class="">
>> +    ; CHECK: [[VREGD:%[0-9]+]]:gpr = COPY [[VREGC]]<br class="">
>> +<br class="">
>> +    %4(p0) = G_SELECT %3(s1),  %0, %1<br class="">
>> +    ; CHECK: CMPri [[VREGD]], 0, 14, _, implicit-def %cpsr<br class="">
>>    ; CHECK: [[RES:%[0-9]+]]:gpr = MOVCCr [[VREGX]], [[VREGY]], 0, %cpsr<br class="">
>><br class="">
>> -    %r0 = COPY %3(p0)<br class="">
>> +    %r0 = COPY %4(p0)<br class="">
>>    ; CHECK: %r0 = COPY [[RES]]<br class="">
>><br class="">
>>    BX_RET 14, _, implicit %r0<br class="">
>><br class="">
>> Modified: llvm/trunk/unittests/CodeGen/G<wbr class="">lobalISel/LegalizerInfoTest.cp<wbr class="">p<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/unittests/Cod<wbr class="">eGen/GlobalISel/LegalizerInfoT<wbr class="">est.cpp?rev=317560&r1=317559&<wbr class="">r2=317560&view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/unittests/CodeGen/G<wbr class="">lobalISel/LegalizerInfoTest.cp<wbr class="">p (original)<br class="">
>> +++ llvm/trunk/unittests/CodeGen/G<wbr class="">lobalISel/LegalizerInfoTest.cp<wbr class="">p Tue Nov  7 02:34:34 2017<br class="">
>> @@ -49,66 +49,91 @@ TEST(LegalizerInfoTest, ScalarRISC) {<br class="">
>>  using namespace TargetOpcode;<br class="">
>>  LegalizerInfo L;<br class="">
>>  // Typical RISCy set of operations based on AArch64.<br class="">
>> -  L.setAction({G_ADD, LLT::scalar(8)}, LegalizerInfo::WidenScalar);<br class="">
>> -  L.setAction({G_ADD, LLT::scalar(16)}, LegalizerInfo::WidenScalar);<br class="">
>> -  L.setAction({G_ADD, LLT::scalar(32)}, LegalizerInfo::Legal);<br class="">
>> -  L.setAction({G_ADD, LLT::scalar(64)}, LegalizerInfo::Legal);<br class="">
>> +  for (auto Op : {G_ADD, G_SUB}) {<br class="">
>> +    for (unsigned Size : {32, 64})<br class="">
>> +      L.setAction({Op, 0, LLT::scalar(Size)}, LegalizerInfo::Legal);<br class="">
>> +    L.setLegalizeScalarToDifferent<wbr class="">SizeStrategy(<br class="">
>> +        Op, 0, LegalizerInfo::widenToLargerTy<wbr class="">pesAndNarrowToLargest);<br class="">
>> +  }<br class="">
>> +<br class="">
>>  L.computeTables();<br class="">
>><br class="">
>> -  // Check we infer the correct types and actually do what we're told.<br class="">
>> -  ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(8)}),<br class="">
>> -            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(32)));<br class="">
>> -  ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(16)}),<br class="">
>> -            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(32)));<br class="">
>> -  ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(32)}),<br class="">
>> -            std::make_pair(LegalizerInfo::<wbr class="">Legal, LLT::scalar(32)));<br class="">
>> -  ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(64)}),<br class="">
>> -            std::make_pair(LegalizerInfo::<wbr class="">Legal, LLT::scalar(64)));<br class="">
>> -<br class="">
>> -  // Make sure the default for over-sized types applies.<br class="">
>> -  ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(128)}),<br class="">
>> -            std::make_pair(LegalizerInfo::<wbr class="">NarrowScalar, LLT::scalar(64)));<br class="">
>> +  for (auto &opcode : {G_ADD, G_SUB}) {<br class="">
>> +    // Check we infer the correct types and actually do what we're told.<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(8)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(32)));<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(16)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(32)));<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(32)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">Legal, LLT::scalar(32)));<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(64)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">Legal, LLT::scalar(64)));<br class="">
>> +<br class="">
>> +    // Make sure the default for over-sized types applies.<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(128)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">NarrowScalar, LLT::scalar(64)));<br class="">
>> +    // Make sure we also handle unusual sizes<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(1)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(32)));<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(31)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(32)));<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(33)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(64)));<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(63)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(64)));<br class="">
>> +    ASSERT_EQ(L.getAction({opcode, LLT::scalar(65)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">NarrowScalar, LLT::scalar(64)));<br class="">
>> +  }<br class="">
>> }<br class="">
>><br class="">
>> TEST(LegalizerInfoTest, VectorRISC) {<br class="">
>>  using namespace TargetOpcode;<br class="">
>>  LegalizerInfo L;<br class="">
>>  // Typical RISCy set of operations based on ARM.<br class="">
>> -  L.setScalarInVectorAction(G_AD<wbr class="">D, LLT::scalar(8), LegalizerInfo::Legal);<br class="">
>> -  L.setScalarInVectorAction(G_AD<wbr class="">D, LLT::scalar(16), LegalizerInfo::Legal);<br class="">
>> -  L.setScalarInVectorAction(G_AD<wbr class="">D, LLT::scalar(32), LegalizerInfo::Legal);<br class="">
>> -<br class="">
>>  L.setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal);<br class="">
>>  L.setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal);<br class="">
>>  L.setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal);<br class="">
>>  L.setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal);<br class="">
>>  L.setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal);<br class="">
>>  L.setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal);<br class="">
>> +<br class="">
>> +  L.setLegalizeVectorElementToDi<wbr class="">fferentSizeStrategy(<br class="">
>> +      G_ADD, 0, LegalizerInfo::widenToLargerTy<wbr class="">pesUnsupportedOtherwise);<br class="">
>> +<br class="">
>> +  L.setAction({G_ADD, 0, LLT::scalar(32)}, LegalizerInfo::Legal);<br class="">
>> +<br class="">
>>  L.computeTables();<br class="">
>><br class="">
>>  // Check we infer the correct types and actually do what we're told for some<br class="">
>>  // simple cases.<br class="">
>> -  ASSERT_EQ(L.getAction({G_ADD, LLT::vector(2, 8)}),<br class="">
>> -            std::make_pair(LegalizerInfo::<wbr class="">MoreElements, LLT::vector(8, 8)));<br class="">
>>  ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 8)}),<br class="">
>>            std::make_pair(LegalizerInfo::<wbr class="">Legal, LLT::vector(8, 8)));<br class="">
>> -  ASSERT_EQ(<br class="">
>> -      L.getAction({G_ADD, LLT::vector(8, 32)}),<br class="">
>> -      std::make_pair(LegalizerInfo::<wbr class="">FewerElements, LLT::vector(4, 32)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 7)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::vector(8, 8)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_ADD, LLT::vector(2, 8)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">MoreElements, LLT::vector(8, 8)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 32)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">FewerElements, LLT::vector(4, 32)));<br class="">
>> +  // Check a few non-power-of-2 sizes:<br class="">
>> +  ASSERT_EQ(L.getAction({G_ADD, LLT::vector(3, 3)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::vector(3, 8)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_ADD, LLT::vector(3, 8)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">MoreElements, LLT::vector(8, 8)));<br class="">
>> }<br class="">
>><br class="">
>> TEST(LegalizerInfoTest, MultipleTypes) {<br class="">
>>  using namespace TargetOpcode;<br class="">
>>  LegalizerInfo L;<br class="">
>>  LLT p0 = LLT::pointer(0, 64);<br class="">
>> -  LLT s32 = LLT::scalar(32);<br class="">
>>  LLT s64 = LLT::scalar(64);<br class="">
>><br class="">
>>  // Typical RISCy set of operations based on AArch64.<br class="">
>>  L.setAction({G_PTRTOINT, 0, s64}, LegalizerInfo::Legal);<br class="">
>>  L.setAction({G_PTRTOINT, 1, p0}, LegalizerInfo::Legal);<br class="">
>><br class="">
>> -  L.setAction({G_PTRTOINT, 0, s32}, LegalizerInfo::WidenScalar);<br class="">
>> +  L.setLegalizeScalarToDifferent<wbr class="">SizeStrategy(<br class="">
>> +      G_PTRTOINT, 0, LegalizerInfo::widenToLargerTy<wbr class="">pesAndNarrowToLargest);<br class="">
>> +<br class="">
>>  L.computeTables();<br class="">
>><br class="">
>>  // Check we infer the correct types and actually do what we're told.<br class="">
>> @@ -116,16 +141,21 @@ TEST(LegalizerInfoTest, MultipleTypes) {<br class="">
>>            std::make_pair(LegalizerInfo::<wbr class="">Legal, s64));<br class="">
>>  ASSERT_EQ(L.getAction({G_PTRTO<wbr class="">INT, 1, p0}),<br class="">
>>            std::make_pair(LegalizerInfo::<wbr class="">Legal, p0));<br class="">
>> +  // Make sure we also handle unusual sizes<br class="">
>> +  ASSERT_EQ(L.getAction({G_PTRTO<wbr class="">INT, 0, LLT::scalar(65)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">NarrowScalar, s64));<br class="">
>> +  ASSERT_EQ(L.getAction({G_PTRTO<wbr class="">INT, 1, LLT::pointer(0, 32)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">Unsupported, LLT::pointer(0, 32)));<br class="">
>> }<br class="">
>><br class="">
>> TEST(LegalizerInfoTest, MultipleSteps) {<br class="">
>>  using namespace TargetOpcode;<br class="">
>>  LegalizerInfo L;<br class="">
>> -  LLT s16 = LLT::scalar(16);<br class="">
>>  LLT s32 = LLT::scalar(32);<br class="">
>>  LLT s64 = LLT::scalar(64);<br class="">
>><br class="">
>> -  L.setAction({G_UREM, 0, s16}, LegalizerInfo::WidenScalar);<br class="">
>> +  L.setLegalizeScalarToDifferent<wbr class="">SizeStrategy(<br class="">
>> +      G_UREM, 0, LegalizerInfo::widenToLargerTy<wbr class="">pesUnsupportedOtherwise);<br class="">
>>  L.setAction({G_UREM, 0, s32}, LegalizerInfo::Lower);<br class="">
>>  L.setAction({G_UREM, 0, s64}, LegalizerInfo::Lower);<br class="">
>><br class="">
>> @@ -136,4 +166,33 @@ TEST(LegalizerInfoTest, MultipleSteps) {<br class="">
>>  ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(32)}),<br class="">
>>            std::make_pair(LegalizerInfo::<wbr class="">Lower, LLT::scalar(32)));<br class="">
>> }<br class="">
>> +<br class="">
>> +TEST(LegalizerInfoTest, SizeChangeStrategy) {<br class="">
>> +  using namespace TargetOpcode;<br class="">
>> +  LegalizerInfo L;<br class="">
>> +  for (unsigned Size : {1, 8, 16, 32})<br class="">
>> +    L.setAction({G_UREM, 0, LLT::scalar(Size)}, LegalizerInfo::Legal);<br class="">
>> +<br class="">
>> +  L.setLegalizeScalarToDifferent<wbr class="">SizeStrategy(<br class="">
>> +      G_UREM, 0, LegalizerInfo::widenToLargerTy<wbr class="">pesUnsupportedOtherwise);<br class="">
>> +  L.computeTables();<br class="">
>> +<br class="">
>> +  // Check we infer the correct types and actually do what we're told.<br class="">
>> +  for (unsigned Size : {1, 8, 16, 32}) {<br class="">
>> +    ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(Size)}),<br class="">
>> +              std::make_pair(LegalizerInfo::<wbr class="">Legal, LLT::scalar(Size)));<br class="">
>> +  }<br class="">
>> +  ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(2)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(8)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(7)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(8)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(9)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(16)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(17)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(32)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(31)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">WidenScalar, LLT::scalar(32)));<br class="">
>> +  ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(33)}),<br class="">
>> +            std::make_pair(LegalizerInfo::<wbr class="">Unsupported, LLT::scalar(33)));<br class="">
>> +}<br class="">
>> }<br class="">
>><br class="">
>> Modified: llvm/trunk/unittests/CodeGen/L<wbr class="">owLevelTypeTest.cpp<br class="">
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/LowLevelTypeTest.cpp?rev=317560&r1=317559&r2=317560&view=diff" rel="noreferrer" target="_blank" class="">
http://llvm.org/viewvc/llvm-pr<wbr class="">oject/llvm/trunk/unittests/Cod<wbr class="">eGen/LowLevelTypeTest.cpp?rev=<wbr class="">317560&r1=317559&r2=317560&<wbr class="">view=diff</a><br class="">
>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>> --- llvm/trunk/unittests/CodeGen/L<wbr class="">owLevelTypeTest.cpp (original)<br class="">
>> +++ llvm/trunk/unittests/CodeGen/L<wbr class="">owLevelTypeTest.cpp Tue Nov  7 02:34:34 2017<br class="">
>> @@ -36,36 +36,22 @@ TEST(LowLevelTypeTest, Scalar) {<br class="">
>><br class="">
>>  for (unsigned S : {1U, 17U, 32U, 64U, 0xfffffU}) {<br class="">
>>    const LLT Ty = LLT::scalar(S);<br class="">
>> -    const LLT HalfTy = (S % 2) == 0 ? Ty.halfScalarSize() : Ty;<br class="">
>> -    const LLT DoubleTy = Ty.doubleScalarSize();<br class="">
>><br class="">
>>    // Test kind.<br class="">
>> -    for (const LLT TestTy : {Ty, HalfTy, DoubleTy}) {<br class="">
>> -      ASSERT_TRUE(TestTy.isValid());<br class="">
>> -      ASSERT_TRUE(TestTy.isScalar())<wbr class="">;<br class="">
>> -<br class="">
>> -      ASSERT_FALSE(TestTy.isPointer(<wbr class="">));<br class="">
>> -      ASSERT_FALSE(TestTy.isVector()<wbr class="">);<br class="">
>> -    }<br class="">
>> +    ASSERT_TRUE(Ty.isValid());<br class="">
>> +    ASSERT_TRUE(Ty.isScalar());<br class="">
>> +<br class="">
>> +    ASSERT_FALSE(Ty.isPointer());<br class="">
>> +    ASSERT_FALSE(Ty.isVector());<br class="">
>><br class="">
>>    // Test sizes.<br class="">
>>    EXPECT_EQ(S, Ty.getSizeInBits());<br class="">
>>    EXPECT_EQ(S, Ty.getScalarSizeInBits());<br class="">
>><br class="">
>> -    EXPECT_EQ(S*2, DoubleTy.getSizeInBits());<br class="">
>> -    EXPECT_EQ(S*2, DoubleTy.getScalarSizeInBits()<wbr class="">);<br class="">
>> -<br class="">
>> -    if ((S % 2) == 0) {<br class="">
>> -      EXPECT_EQ(S/2, HalfTy.getSizeInBits());<br class="">
>> -      EXPECT_EQ(S/2, HalfTy.getScalarSizeInBits());<br class="">
>> -    }<br class="">
>> -<br class="">
>>    // Test equality operators.<br class="">
>>    EXPECT_TRUE(Ty == Ty);<br class="">
>>    EXPECT_FALSE(Ty != Ty);<br class="">
>><br class="">
>> -    EXPECT_NE(Ty, DoubleTy);<br class="">
>> -<br class="">
>>    // Test Type->LLT conversion.<br class="">
>>    Type *IRTy = IntegerType::get(C, S);<br class="">
>>    EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));<br class="">
>> @@ -90,62 +76,18 @@ TEST(LowLevelTypeTest, Vector) {<br class="">
>>      // Test getElementType().<br class="">
>>      EXPECT_EQ(STy, VTy.getElementType());<br class="">
>><br class="">
>> -      const LLT HalfSzTy = ((S % 2) == 0) ? VTy.halfScalarSize() : VTy;<br class="">
>> -      const LLT DoubleSzTy = VTy.doubleScalarSize();<br class="">
>> -<br class="">
>> -      // halfElements requires an even number of elements.<br class="">
>> -      const LLT HalfEltIfEvenTy = ((Elts % 2) == 0) ?  VTy.halfElements() : VTy;<br class="">
>> -      const LLT DoubleEltTy = VTy.doubleElements();<br class="">
>> -<br class="">
>>      // Test kind.<br class="">
>> -      for (const LLT TestTy : {VTy, HalfSzTy, DoubleSzTy, DoubleEltTy}) {<br class="">
>> -        ASSERT_TRUE(TestTy.isValid());<br class="">
>> -        ASSERT_TRUE(TestTy.isVector())<wbr class="">;<br class="">
>> -<br class="">
>> -        ASSERT_FALSE(TestTy.isScalar()<wbr class="">);<br class="">
>> -        ASSERT_FALSE(TestTy.isPointer(<wbr class="">));<br class="">
>> -      }<br class="">
>> -<br class="">
>> -      // Test halving elements to a scalar.<br class="">
>> -      {<br class="">
>> -        ASSERT_TRUE(<a href="http://HalfEltIfEvenTy.is" class="">HalfEltIfEvenTy.is</a><wbr class="">Valid());<br class="">
>> -        ASSERT_FALSE(HalfEltIfEvenTy.i<wbr class="">sPointer());<br class="">
>> -        if (Elts > 2) {<br class="">
>> -          ASSERT_TRUE(<a href="http://HalfEltIfEvenTy.is" class="">HalfEltIfEvenTy.is</a><wbr class="">Vector());<br class="">
>> -        } else {<br class="">
>> -          ASSERT_FALSE(HalfEltIfEvenTy.i<wbr class="">sVector());<br class="">
>> -          EXPECT_EQ(STy, HalfEltIfEvenTy);<br class="">
>> -        }<br class="">
>> -      }<br class="">
>> +      ASSERT_TRUE(VTy.isValid());<br class="">
>> +      ASSERT_TRUE(VTy.isVector());<br class="">
>><br class="">
>> +      ASSERT_FALSE(VTy.isScalar());<br class="">
>> +      ASSERT_FALSE(VTy.isPointer());<br class="">
>><br class="">
>>      // Test sizes.<br class="">
>>      EXPECT_EQ(S * Elts, VTy.getSizeInBits());<br class="">
>>      EXPECT_EQ(S, VTy.getScalarSizeInBits());<br class="">
>>      EXPECT_EQ(Elts, VTy.getNumElements());<br class="">
>><br class="">
>> -      if ((S % 2) == 0) {<br class="">
>> -        EXPECT_EQ((S / 2) * Elts, HalfSzTy.getSizeInBits());<br class="">
>> -        EXPECT_EQ(S / 2, HalfSzTy.getScalarSizeInBits()<wbr class="">);<br class="">
>> -        EXPECT_EQ(Elts, HalfSzTy.getNumElements());<br class="">
>> -      }<br class="">
>> -<br class="">
>> -      EXPECT_EQ((S * 2) * Elts, DoubleSzTy.getSizeInBits());<br class="">
>> -      EXPECT_EQ(S * 2, DoubleSzTy.getScalarSizeInBits<wbr class="">());<br class="">
>> -      EXPECT_EQ(Elts, DoubleSzTy.getNumElements());<br class="">
>> -<br class="">
>> -      if ((Elts % 2) == 0) {<br class="">
>> -        EXPECT_EQ(S * (Elts / 2), HalfEltIfEvenTy.getSizeInBits(<wbr class="">));<br class="">
>> -        EXPECT_EQ(S, HalfEltIfEvenTy.getScalarSizeI<wbr class="">nBits());<br class="">
>> -        if (Elts > 2) {<br class="">
>> -          EXPECT_EQ(Elts / 2, HalfEltIfEvenTy.getNumElements<wbr class="">());<br class="">
>> -        }<br class="">
>> -      }<br class="">
>> -<br class="">
>> -      EXPECT_EQ(S * (Elts * 2), DoubleEltTy.getSizeInBits());<br class="">
>> -      EXPECT_EQ(S, DoubleEltTy.getScalarSizeInBit<wbr class="">s());<br class="">
>> -      EXPECT_EQ(Elts * 2, DoubleEltTy.getNumElements());<br class="">
>> -<br class="">
>>      // Test equality operators.<br class="">
>>      EXPECT_TRUE(VTy == VTy);<br class="">
>>      EXPECT_FALSE(VTy != VTy);<br class="">
>> @@ -153,10 +95,6 @@ TEST(LowLevelTypeTest, Vector) {<br class="">
>>      // Test inequality operators on..<br class="">
>>      // ..different kind.<br class="">
>>      EXPECT_NE(VTy, STy);<br class="">
>> -      // ..different #elts.<br class="">
>> -      EXPECT_NE(VTy, DoubleEltTy);<br class="">
>> -      // ..different scalar size.<br class="">
>> -      EXPECT_NE(VTy, DoubleSzTy);<br class="">
>><br class="">
>>      // Test Type->LLT conversion.<br class="">
>>      Type *IRSTy = IntegerType::get(C, S);<br class="">
>><br class="">
>><br class="">
>> ______________________________<wbr class="">_________________<br class="">
>> llvm-commits mailing list<br class="">
>> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a><br class="">
>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="">
http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/llvm-commits</a><br class="">
><br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/llvm-commits</a><br class="">
</blockquote>
</div>
<br class="">
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
</body>
</html>