<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt">Ahead of the Wednesday’s roundtable at the developers’ conference, here is version three of<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">the proposal for first-class complex types in LLVM.  I was not able to add  Krzysztof Parzyszek’s<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">suggestion of a “cunzip” intrinsic returning two vectors as I could not find examples of intrinsics<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">that return two values at the IR level.  The Hexagon intrinsics declared to return two values do<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">not actually have both of their values used at the IR level as far as I can determine.  We can<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">discuss this more at the roundtable.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Following is a general outline for Wednesday’s roundtable.  Please have a look and make<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">any suggestions you’d like about topics we should cover.  Feel free to add to the list of<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">questions to discuss as well.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">LLVM Complex Types Roundtable<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">-----------------------------<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Introductions (name/affiliation if any/interest)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Reasons for a first-class type<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - Reasoning about algebraic optimization<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - Preserve semantics through vectorization and into target-specific lowering<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    Different targets have support for different algorithms<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - Take advantage of faster & less precise algorithms with options/pragmas<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - Better diagnostics for users<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - Other motivations?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Open questions<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - A cunzip intrinsic would need to work at the IR level, returning two<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    separate SSA values.  How can this be done?  The example given was a<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    Hexagon-specific intrinsic that doesn't appear to make use of the two<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    destinations at the IR level.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - Are separate extratreal/extractimag intrinsics sufficient for targets that<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    support such operations (e.g. NEON's VUZP)?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - The proposal allows bitcasts of vector of complex, even though bitcasts of<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    aggregates in general are disallowed.  Is this special case reasonable?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - If we allow such bitcasts, is czip necessary, or is shufflevector + bitcast<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    to vector of complex sufficient?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - Some frontends will likely want to communicate specific algorithms for<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    computing complex values (e.g. C Annex G).  What is the best way to do this?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    User compiler options?  Pragmas?  Function attributes?  Something else?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - What TTI interfaces would be useful to inform the optimizer how best to<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">    lower complex operations?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - When should lowering be done?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">  - Other questions?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">I am looking forward to our discussion!<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                     -David<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Proposal to Support Complex Operations in LLVM<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">==============================================<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Revision History<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">----------------<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">v1 - Initial proposal [1]<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">v2 - 2nd draft [2]<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Added complex of all existing floating point types<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Made complex a special aggregate<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Specified literal syntax<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Added special index values "real" and "imag" for insertvalue/extractvalue<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">         of complex3<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Added czip intrinsic to create vector of complex from vectors of<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">         real/imaginary<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Added extractreal and extractimag intrinsics for vectors of complex<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Added masked vector intrinsics<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">v3 - This proposal<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Added vector-of-complex types<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Added scalable vector support<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">   - Added bitcasts of vector of complex<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Abstract<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">--------<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Several vendors and individuals have proposed first-class complex support in<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">LLVM.  Goals of this proposal include better optimization, diagnostics and<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">general user experience.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Introduction and Motivation<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">---------------------------<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Recently the topic of complex numbers arose on llvm-dev with several developers<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">expressing a desire for first-class IR support for complex [3] [4].  Interest in<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">complex numbers in LLVM goes back much further [5].<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Currently clang chooses to represent standard types like "double complex" and<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">"std::complex<float>" as structure types containing two scalar fields, for<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">example {double, double}.  Consequently, arrays of complex type are represented<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">as, for example, [8 x {double, double}].  This has consequences for how clang<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">converts complex operations to LLVM IR.  In general, clang emits loads of the<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">individual real and imaginary parts and feeds them into arithmetic operations.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Vectorization results in many shufflevector operations to massage the data into<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">sequences suitable for vector arithmetic.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">All of the real/imaginary data manipulation obscures the underlying arithmetic.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">It makes it difficult to reason about the algebraic properties of expressions.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">For expressiveness and optimization ability, it will be nice to have a<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">higher-level representation for complex in LLVM IR.  In general, it is desirable<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">to defer lowering of complex until the optimizer has had a reasonable chance to<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">exploit its properties.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">First-class support for complex can also improve the user experience.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Diagnostics could express concepts in the complex domain instead of referring to<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">expressions containing shuffles and other low-level data manipulation.  Users<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">that wish to examine IR directly will see much less gobbbledygook and can more<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">easily reason about the IR.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Types<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">-----<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">This proposal introduces new aggregate types to represent complex numbers.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c16      - Complex of 16-bit float<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c32      - like float complex or std::complex<float><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c64      - like double complex or std::complex<double><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">x86_c80  - Complex of x86_fp80<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c128     - like long double complex or std::complex<long double><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">ppc_c128 - Complex of ppc_fp128<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Note that the references to C and C++ types above are simply explanatory.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Nothing in this proposal assumes any particular high-level language type will<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">map to the above LLVM types.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The "underlying type" of a complex type is the type of its real and imaginary<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">components.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The sizes of the complex types are twice that of their underlying types.  The<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">real part of the complex shall appear first in the layout of the types.  The<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">format of the real and imaginary parts is the same as for the complex type's<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">underlying type.  This should map to most common data representations of complex<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">in various languages.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">These types are *not* considered floating point types for the purposes of<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Type::isFloatTy and friends, llvm_anyfloat_ty, etc. in order to limit surprises<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">when introducing these types.  New APIs will allow querying and creation of<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">complex types:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">bool Type::isComplexTy()          const;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">bool Type::isComplex16Ty()        const;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">bool Type::isComplex32Ty()        const;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">bool Type::isComplex64Ty()        const;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">bool Type::isComplexX86_FP80Ty()  const;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">bool Type::isComplex128Ty()       const;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">bool Type::isComplexPPC_FP128Ty() const;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The types are a special kind of aggregate, giving them access to the insertvalue<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">and extractvalue operations with special notation (see below).<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">We can define vectors of complex:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><8 x c16> - Vector of eight complex of 16-bit float (128 bits total)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><4 x c32> - Vector of four complex of 32-bit float (128 bits total)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><4 x c64> - Vector of four complex of 64-bit float (512 bits total)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">...<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Such vectors may be scalable:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><vscale x 8 x c16><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><vscale x 4 x c32><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><vscale x 1 x c64><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><vscale x 2 x c64><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">...<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Analogous ValueTypes will be used by intrinsics.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">vdef c16       : ValueType<32,  uuu><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def c32       : ValueType<64,  vvv><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def c64       : ValueType<128, www><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def x86c80    : ValueType<160, xxx><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def c128      : ValueType<256, yyy><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def ppcc128   : ValueType<256, zzz><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def v8c16     : ValueType<128, aaa><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def v4c32     : ValueType<128, bbb><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def v4c64     : ValueType<512, ccc><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">...<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def nxv8c16   : ValueType<128, ddd><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def nxv4c32   : ValueType<128, eee><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def nxv1c64   : ValueType<128, fff><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def nxv2c64   : ValueType<256, ggg><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">...<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_anycomplex_ty : LLVMType<Any>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_c16_ty        : LLVMType<c16>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_c32_ty        : LLVMType<c32>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_c64_ty        : LLVMType<c64>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_x86c80_ty     : LLVMType<x86c80>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_c128_ty       : LLVMType<c128>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_ppcc128_ty    : LLVMType<ppcc128>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_v8c16_ty      : LLVMType<v8c16>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_v4c32_ty      : LLVMType<v4c32>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">def llvm_v4c64_ty      : LLVMType<v4c64>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">...<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The numbering of the ValueTypes will be determined after discussion.  It may be<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">desirable to insert the scalar types before the existing vector types, grouping<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">them with the other scalar types or we may want to put them somewhere else.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Similarly, the vector types may be grouped with the other vector types or<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">somewhere else.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Literals<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">--------<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Literal complex values have special spellings '(' <fp constant> '+'|'-'<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><fpconstant>'i' ')':<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">%v1 = c64 ( 5.67 + 1.56i )<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">%v2 = c64 ( 55.87 - 4.23i )<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">%v3 = c64 ( 55.87 + -4.23i )<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">%v4 = c32 ( 8.24e+2 + 0.0i )<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">%v5 = c16 ( 0.0 + 0.0i )<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Note that the literal representation requires an explicit specification of the<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">imaginary part, even if zero.  A "redundant" <+ negative imaginary> is allowed<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">to facilitate reuse of floating point constants.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Operations<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">----------<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">This proposal overloads existing floating point instructions for complex types<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">in order to leverage existing expression optimizations:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c64 %res   = fadd c64 %a, c64 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">v8c64 %res = fsub v8c64 %a, v8c64 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c128 %res  = fmul c128 %a, c128 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">v4c32 %res = fdiv v4c64 %a, v4c64 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The only valid comparisons of complex values shall be equality:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">i1 %res = eq c32 %a, c32 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">i8 %res = eq v8c32 %a, v8c32 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">i1 %res = ne c64 %a, c64 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">i8 %res = ne v8c64 %a, v8c64 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">select is defined for complex:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c32 %res = select i1 %cmp, c32 %a, c32 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">v4c64 %res = select i4 %cmp, v4c64 %a, v4c64 %b<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Complex values may be casted to other complex types:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c32 %res = fptrunc c64 %a to c32<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">c64 %res = fpext c32 %a to c64<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">As a special case, vectors of complex may be bitcasted to vectors of their<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">underlying type:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">v8f32 %res = bitcast <4 x c32> to <8 x float><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Complex types were defined as aggregates above, but special ones.  One aspect of<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">their specialness is allowing bitcasts of vector of complex to equal-width<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">vectors of their underlying type.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">insertvalue and extractvalue may be used with the special index values "real"<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">and "imag":<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">%real = f32 extractvalue c32 %a, real<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">%real = c64 insertvalue c64 undef, f64 %r, real<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">%cplx = c64 insertvalue c64 %real, f64 %i, imag<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">The pseudo-value "real" shall evaluate to the integer constant zero and the<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">pseudo-valid "imag" shall evaluate to the integer constant one, as if<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">extractvalue/insertvalue were written with 0/1.  The use of any other index with<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">a complex value is undefined.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">We also overload existing intrinsics:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c16      @llvm.sqrt.c16(c16 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c32      @llvm.sqrt.c32(c32 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c64      @llvm.sqrt.c64(c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare x86_c80  @llvm.sqrt.x86_c80(x86_c80 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c128     @llvm.sqrt.c128(c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare ppc_c128 @llvm.sqrt.ppc_c128(ppc_c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c16      @llvm.pow.c16(c16 %val, c16 %power)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c32      @llvm.pow.c32(c32 %val, c32 %power)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c64      @llvm.pow.c64(c64 %val, c64 %power<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare x86_c86  @llvm.pow.x86_c80(x86_c80 %val, x86_c80 %power<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c128     @llvm.pow.c128(c128 %val, c128 %power)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare ppc_c128 @llvm.pow.ppc_c128(ppc_c128 %val, ppc_c128 %power)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c16      @llvm.sin.c16(c16 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c32      @llvm.sin.c32(c32 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c64      @llvm.sin.c64(c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare x86_c80  @llvm.sin.x86_c80(x86_c80 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c128     @llvm.sin.c128(c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare ppc_c128 @llvm.sin.ppc_c128(ppc_c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c16      @llvm.cos.c16(c16 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c32      @llvm.cos.c32(c32 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c64      @llvm.cos.c64(c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare x86_c80  @llvm.cos.x86_c80(x86_c80 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c128     @llvm.cos.c128(c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare ppc_c128 @llvm.cos.ppc_c128(ppc_c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c16      @llvm.log.c16(c16 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c32      @llvm.log.c32(c32 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c64      @llvm.log.c64(c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare x86_c80  @llvm.log.x86_c80(x86_c80 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c128     @llvm.log.c128(c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare ppc_c128 @llvm.log.ppc_c128(ppc_c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare half      @llvm.fabs.c16(c16 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare double    @llvm.fabs.c64(c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare x86_fp80  @llvm.fabs.x86_c80(x86_c80 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare fp128     @llvm.fabs.c128(c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare ppc_fp128 @llvm.fabs.ppc_c128(ppc_c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Conversion to/from half-precision overloads the existing intrinsics.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.convert.to.c16.* - Overloaded intrinsic to convert to c16.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c16 @llvm.convert.to.c16.c32(c32 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c16 @llvm.convert.to.c16.c64(c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.convert.from.c16.* - Overloaded intrinsic to convert from c16.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c32 @llvm.convert.from.c16.c32(c16 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c64 @llvm.convert.from.c16.c64(c16 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">In addition, new intrinsics will be used for complex-specific operations:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.cconj.* - Overloaded intrinsic to compute the conjugate of a<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">               complex value<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c16      @llvm.cconj.c16(c16 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c32      @llvm.cconj.c32(c32 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c64      @llvm.cconj.c64(c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare x86_c80  @llvm.cconj.x86_c80(x86_c80 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare c128     @llvm.cconj.c128(c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare ppc_c128 @llvm.cconj.ppc_c128(ppc_c128 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.czip.* - Overloaded intrinsic to create a vector of complex from two<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">              vectors of floating-point type (not all variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4c32 @llvm.czip.v4c32(v4f32 %real, v4f32 %imag)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4c64 @llvm.czip.v4c32(v4f64 %real, v4f64 %imag)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.extractreal.* - Overloaded intrinsic to create a vector of floating-point<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                     type from the real portions of a vector of complex (not all<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                     variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4f32 @llvm.extractreal.v4c32(v4c32 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4f64 @llvm.extractreal.v4c64(v4c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.extractimag.* - Overloaded intrinsic to create a vector of floating-point<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                     type from the imaginary portions of a vector of complex<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                     (not all variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4f32 @llvm.extractimag.v4c32(v4c32 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4f64 @llvm.extractimag.v4c64(v4c64 %val)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Masked intrinsics are also overloaded.  The complex types are considered a<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">single logical entity and thus the mask bits correspond to the complex value as<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">a whole, not the individual real and imaginary parts:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.masked.load.* - Overloaded intrinsic to load complex under mask<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">(not all variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4c32 @llvm.masked.load.v4c32.p0v4c32(<4 x c32>* %ptr,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              i32 %alignment,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              <4 x i1> %mask,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              <4 x c32> %passthrough)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v8c32 @llvm.masked.load.v8c64.p0v8c64(<8 x c64>* %ptr,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              i32 %alignment,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              <8 x i1> %mask,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              <8 x c64> %passthrough)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.masked.store.* - Overloaded intrinsic to store complex under mask (not all<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                      variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare void @llvm.masked.store.v4c32.p0v4c32(<4 x c32> %val,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              <4 x c32>* %ptr,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              i32 %alignment,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              <4 x i1> %mask)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare void @llvm.masked.store.v8c64.p0v8c64(<8 x c64> %val,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              <8 x c64>* %ptr,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              i32 %alignment,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                              <8 x i1> %mask)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.masked.gather.* - Overloaded intrinsic to gather complex under mask (not<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                       all variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4c32 @llvm.masked.gather.v4c32.p0v4c32(<4 x c32 *> %ptrs,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                i32 %alignment,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                <4 x i1> %mask,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                <4 x c32> %passthrough)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v8c32 @llvm.masked.gather.v8c64.p0v8c64(<8 x c64*> %ptrs,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                i32 %alignment,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                <8 x i1> %mask,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                <8 x c64> %passthrough)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.masked.scatter.* - Overloaded intrinsic to scatter complex under mask (not<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                        all variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare void @llvm.masked.scatter.v4c32.p0v4c32(<4 x c32> %val,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                <4 x c32*> %ptrs,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                               i32 %alignment,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                <4 x i1> %mask)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare void @llvm.masked.scatter.v8c64.p0v8c64(<8 x c64> %val,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                <8 x c64*> %ptrs,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                i32 %alignment,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                <8 x i1> %mask)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.masked.expandload.* - Overloaded intrinsic to expandload complex under mask<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                           (not all variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v4c32 @llvm.masked.expandload.v4c32.p0v4c32(c32* %ptr,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                    <4 x i1> %mask,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                    <4 x c32> %passthrough)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare v8c32 @llvm.masked.expandload.v8c64.p0v8c64(c64* %ptr,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                    <8 x i1> %mask,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                    <8 x c64> %passthrough)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">llvm.masked.compressstore.* - Overloaded intrinsic to compressstore complex<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                              under mask (not all variants shown)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare void @llvm.masked.compressstore.v4c32.p0v4c32(<4 x c32> %val,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                       c32* %ptr,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                       <4 x i1> %mask)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">declare void @llvm.masked.compressstore.v8c64.p0v8c64(<8 x c64> %val,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                      c64* %ptr,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">                                                      <8 x i1> %mask)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Conclusion<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">----------<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">This proposal introduces new complex types and overloads existing floating point<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">instructions and intrinsics for common complex operations and introduces new<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">intrinsics for complex-specific operations.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Goals of this work include better reasoning about complex operations within<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">LLVM, leading to better optimization, reporting and overall user experience.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">This is a draft and subject to change.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">[1] http://lists.llvm.org/pipermail/llvm-dev/2019-July/133558.html<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">[2] http://lists.llvm.org/pipermail/llvm-dev/2019-August/134815.html<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">[3] http://lists.llvm.org/pipermail/llvm-dev/2019-April/131516.html<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">[4] http://lists.llvm.org/pipermail/llvm-dev/2019-April/131523.html<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">[5] http://lists.llvm.org/pipermail/llvm-dev/2010-December/037072.html<o:p></o:p></span></p>
</div>
</body>
</html>