<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 12 (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;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> metafoo@gmail.com [mailto:metafoo@gmail.com]
<b>On Behalf Of </b>Richard Smith<br>
<b>Sent:</b> Wednesday, September 12, 2012 2:51 PM<br>
<b>To:</b> Villmow, Micah<br>
<b>Cc:</b> Ouriel, Boaz; cfe-dev@cs.uiuc.edu; llvmdev@cs.uiuc.edu<br>
<b>Subject:</b> Re: [LLVMdev] SPIR Portability Discussion<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">On Wed, Sep 12, 2012 at 2:23 PM, Villmow, Micah <<a href="mailto:Micah.Villmow@amd.com" target="_blank">Micah.Villmow@amd.com</a>> wrote:<o:p></o:p></p>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><o:p></o:p></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">
<a href="mailto:llvmdev-bounces@cs.uiuc.edu" target="_blank">llvmdev-bounces@cs.uiuc.edu</a> [mailto:<a href="mailto:llvmdev-bounces@cs.uiuc.edu" target="_blank">llvmdev-bounces@cs.uiuc.edu</a>]
<b>On Behalf Of </b>Richard Smith<br>
<b>Sent:</b> Wednesday, September 12, 2012 1:55 PM<br>
<b>To:</b> Ouriel, Boaz<br>
<b>Cc:</b> <a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a>;
<a href="mailto:llvmdev@cs.uiuc.edu" target="_blank">llvmdev@cs.uiuc.edu</a><br>
<b>Subject:</b> Re: [LLVMdev] SPIR Portability Discussion</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">On Wed, Sep 12, 2012 at 12:27 PM, Ouriel, Boaz <<a href="mailto:boaz.ouriel@intel.com" target="_blank">boaz.ouriel@intel.com</a>> wrote:<o:p></o:p></p>
</div>
</div>
<div>
<div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Hey All,<br>
<br>
This is a very big topic in SPIR and probably a very controversial one as well. It includes dealing with 32 vs. 64 bit architectures and OpenCL "C" endianness.<br>
We have written down some of the aspects, but of course did not cover everything - let's start a discussion on the portability and see where it takes us.<br>
I suggest we start with the 32 vs. 64 bits discussion and then move to the Endianness part.<br>
<br>
****Introduction****<br>
As a reminder, portability is one of SPIR's goals.<br>
However, SPIR does not attempt to solve inherent portability issues, which exist in OpenCL "C" or in C99.<br>
It is clear that OpenCL programs could be written in a way which make them non portable and very device specific.<br>
Such programs will never be portable. In addition, some corner case scenario's which have been identified by Khronos members have been disallowed in SPIR.<br>
So, SPIR aims at being portable but not for every scenario.<br>
<br>
1) ****Portability between Devices with different address width (32 vs. 64 bits)****<br>
During the design stages, Khronos members needed to decide on its philosophy when it comes to dealing with the address width of devices (32 vs. 64bits).<br>
During internal discussions, two alternatives came up. The first alternative was to split SPIR into two sub-cases: SPIR 32bits and SPIR 64bits.<br>
The second alternative was to try and abstract this information at SPIR level.<br>
<br>
Splitting SPIR into 32bit and 64bit is simpler to implement. However, it is less portable.<br>
This will require OpenCL developers to pre-compile two versions of their code one for 32bit and another for 64bit devices and make their application aware at runtime to the underlying device architecture.<br>
OpenCL applications would need to load the proper SPIR binary based on the device architecture.<br>
An option that was raised during the discussions was to have a fat binary that contains both 32bit and 64bit versions of SPIR binaries.<br>
However, this option was controversial inside Khronos and eventually was not accepted.<br>
The decision was to pursue the second alternative. Khronos members understand that this is a more complex alternative and does not guarantee 100% percent coverage to all cases.<br>
However, as stated before, SPIR attempts to solve the important cases. Those particular cases which SPIR will not be able to address are explicitly documented in the specification.<br>
<br>
         ****Pointers****<br>
During SPIR generation, the size, and the alignment of pointers is unknown (32 vs. 64 bits).<br>
The SPIR representation shouldn't assume anything about the size and the alignment of pointers,<br>
but it might use pointers in the usual way (except from using GEP when the pointed type has unknown size - this one is illegal in SPIR and will fail the SPIR verification pass which was written by Khronos members)<br>
<br>
         *****Sizeof******<br>
Most valid built-in and user specific types in OpenCL have known non device-specific size.<br>
However, for some types (pointers, size_t, ptrdiff_t) the size is unknown during compilation.<br>
To overcome this issue, SPIR provides functions to substitute the constant values of the sizeof operator.<br>
These functions should be resolved by the device backend compiler when producing the final machine code of the OpenCL program.<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">OpenCL 1.2 (6.3)/k says the result of sizeof is an ICE. So these are valid:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
</div>
</div>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">int does_this_compile[sizeof(void*) - 3];<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Oops, I meant sizeof(void*) - 5.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Villmow, Micah] ‘ICE’? Integer compile time expression? While not pretty, this can be represented
 in SPIR with the following sequence on instructions</span></i></b><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">%1 = call %spir.size_t @__spir_sizet_convert_size_t(i32 3)</span></i></b><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">%2 = call %spir.size_t @__spir_size_of_sizet()</span></i></b><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">%3 = call %spir.size_t @__spir_sizet_sub(%spir.size_t %1, %spir.size_t %2)</span></i></b><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">%4 = call %spir.size_t @__spir_sizet_convert_i32(%spir.size_t %3)</span></i></b><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">%5 = alloca i32, i32 %4</span></i></b><o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">My point here was that if sizeof(void*) is an integer constant expression, then this code has a constraint violation if sizeof(void*) is 4 but not if sizeof(void*) is 8 (and my example was intended to be of a global array, not a function-local
 one, so you can't fall back to treating it as a VLA). <span style="color:#1F497D">
<o:p></o:p></span></p>
<p class="MsoNormal"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Villmow, Micah] OpenCL restricts this behavior, so it is illegal.<o:p></o:p></span></i></b></p>
<p class="MsoNormal">Another case which might depend on this:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">enum E {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  a = sizeof(void*) // is this valid?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">};<o:p></o:p></p>
<p class="MsoNormal"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Villmow, Micah] I will have to think on this one, good example.</span></i></b><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Based on the behavior you describe above, it looks like sizeof applied to a pointer (and to size_t etc.) isn't a constant expression in SPIR's model.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Another factor to consider, with size_t etc as defined in SPIR, is the usual arithmetic conversions. For instance (assuming a 64-bit long long), sizeof(int) + 1LL would be signed if size_t is 32 bits wide, and would be unsigned if size_t
 is 64 bits wide. How is this handled?<o:p></o:p></p>
<p class="MsoNormal"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Villmow, Micah] OpenCL C defines ‘int’ to be 32bits irrespective of the host/device bitness. So this would follow the normal integer promotion rules.</span></i></b><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">How do you perform record layout if the size of a pointer is unknown? For instance:<o:p></o:p></p>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">struct A {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">  int *p;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">  int n;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">} a;<o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">int arr[offsetof(A, n) - 3]; // or, int arr[(char*)&a.n - (char*)&a.p - 3];<o:p></o:p></p>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Villmow, Micah] Since in the current implementation of SPIR, a pointer is defined as 64bits
 when in a structure(SPIR spec 2.1.5), the offsets themselves are well defined.</span></i></b><o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I see, that makes sense.<o:p></o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>