On Wed, Sep 12, 2012 at 2:23 PM, Villmow, Micah <span dir="ltr"><<a href="mailto:Micah.Villmow@amd.com" target="_blank">Micah.Villmow@amd.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">






<div lang="EN-US" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></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""> <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<u></u><u></u></span></p>
</div>
</div><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">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:<u></u><u></u></p>
</div></div><div><div><div class="h5">
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">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.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">OpenCL 1.2 (6.3)/k says the result of sizeof is an ICE. So these are valid:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div></div><div><div><div class="h5">
<p class="MsoNormal">int does_this_compile[sizeof(void*) - 3];</p></div></div></div></div></div></div></div></blockquote><div><br></div><div>Oops, I meant sizeof(void*) - 5.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div lang="EN-US" link="blue" vlink="purple"><div><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt"><div><div><div><div class="h5"><p class="MsoNormal"><u></u><u></u></p>
</div></div><p class="MsoNormal"><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<u></u><u></u></span></i></b></p>

<p class="MsoNormal"><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)<u></u><u></u></span></i></b></p>
<p class="MsoNormal"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">%2 = call %spir.size_t @__spir_size_of_sizet()<u></u><u></u></span></i></b></p>
<p class="MsoNormal"><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)<u></u><u></u></span></i></b></p>

<p class="MsoNormal"><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)<u></u><u></u></span></i></b></p>

<p class="MsoNormal"><b><i><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">%5 = alloca i32, i32 %4</span></i></b></p></div></div></div></div></div></blockquote><div><br>
</div><div>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). Another case which might depend on this:</div>
<div><br></div><div>enum E {</div><div>  a = sizeof(void*) // is this valid?</div><div>};</div><div><br></div><div>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.</div>
<div><br></div><div><br></div><div>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?</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div><div><p class="MsoNormal">How do you perform record layout if the size of a pointer is unknown? For instance:</p></div><div class="im"><div><p class="MsoNormal"><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">struct A {<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  int *p;<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  int n;<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">} a;<u></u><u></u></p>
</div>
</div><div><div class="im">
<p class="MsoNormal">int arr[offsetof(A, n) - 3]; // or, int arr[(char*)&a.n - (char*)&a.p - 3];<u></u><u></u></p>
</div><p class="MsoNormal"><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></p></div></div></div></div></div></blockquote><div><br></div><div>I see, that makes sense.</div></div>