On Wed, Nov 11, 2009 at 11:11 AM, Chris Lattner <span dir="ltr"><<a href="mailto:clattner@apple.com">clattner@apple.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 class="im">On Nov 10, 2009, at 4:10 PM, Talin wrote:<br>
> I realize that most users of LLVM aren't affected by this, because most frontends aren't target-neutral, and thus know in advance how big a pointer is. At least, that's my impression.<br>
<br>
</div>I believe that.<br>
<div class="im"><br>
> There's only a tiny handful of fairly esoteric cases which require selecting a target before you generate IR. Unfortunately, the "pointer the same size as an int" is one of these rare cases -  it is something that is very painful to try and work around. (A similar esoteric use case is: "which of the following two types is larger, 3 x int32 or 2 x {}*? -- i.e. the union problem.)<br>


<br>
</div>With this explanation, the idea of adding a union type seems a lot more compelling to me.  For the record, I'm not opposed to an intptr_t type or a union type, but the semantics have to be clean and well specified.<br>


<font color="#888888"><br>
-Chris</font></blockquote></div><br>Well, as far as intp goes (or iptr if you prefer - the naming convention in LLVM is i<size>), here's what I would expect:<div><ul><li>General rule #1: If an instruction accepts both i32 and i64, then it should accept iptr as well. If it only accepts i32, then it can continue to only accept i32.</li>

<li>General rule #2: It should support operations that are commonly used with size_t and ptrdiff_t.</li><li>Operations that should work with iptr:</li><ul><li>Basic math: add, subtract, multiply, divide, mod.</li><li>Bitwise binary operators: shl, ashr, lshr, and, or, xor, etc.</li>

<li>Comparison operations.</li><li>alloca - currently doesn't work with i64, should it?</li><li>GEP - rules are the same as for using i64 indices.</li><li>memcpy intrinsics</li><li>bit manipulation intrinsics</li><li>

overflow arithmetic intrinsics - would be nice</li><li>atomic intrinsics - would be very nice (I assume that atomic iptr works on all platforms that support atomics: That is, on 32-bit platforms where iptr == i32 I expect atomic i32 to work; on 64-bit platforms where iptr == i64 I expect atomic i64 to work).</li>

</ul><li>Operations that don't need to work with iptr - i.e. I don't mind having to convert to some other int type first:</li><ul><li>switch</li><li>extractelement / insertelement / shufflevector</li><li>extractvalue / insertvalue - not sure about these.</li>

<li>code generator intrinsics (frameaddress, etc.)</li></ul><li>Converting to pointer types: inttoptr and ptrtoint should be no-ops, effectively.</li><li>Converting to other integer types: The issue here is that with other integer conversions in LLVM, you are required to know whether or not you are converting to a larger or smaller size - whether to use an ext or a trunc instruction. When converting to pointers, however, the choice of trunc or ext is automatic. Ideally, conversion to iptr would work the same way as conversion to a pointer type. There's also the issue of signed vs. unsigned extension.</li>

<ul><li>Note that some constant-folding operations would need to be deferred until the target size is established.</li></ul><li>Converting to FP types: Either don't support (i.e. require casting to known-width integer first), or map to i32->FP or i64->FP after the size is known.</li>

</ul></div><div>-- <br>-- Talin<br>
</div>