[LLVMdev] [RFC] Proposal to make LLVM-IR endian agnostic
Török Edwin
edwintorok at gmail.com
Mon Oct 3 14:00:18 PDT 2011
On 10/03/2011 09:36 PM, Villmow, Micah wrote:
> One of the projects I am working on with others is to make LLVM-IR endian agnostic.
>
>
>
> So, I am sending out this proposal for feedback to the LLVM community. I’ve attached
>
> pretty version of the proposal in PDF format and pasted a 80-column safe text version
>
> below.
>
>
>
> A second smaller set could be:
>
> declare <type> @llvm.portable.load.<type>(<type>* ptr, i32 alignment,
>
> i1 host, i1 littleEndian, i1 atomic, i1 volatile,
>
> i1 nontemporal, i1 singlethread)
>
>
>
> declare void @llvm.portable.store.<type>(<type> data, <type>* ptr,
>
> i32 alignment, i1 host, i1 littleEndian, i1 atomic, i1 volatile,
>
> i1 nontemporal, i1 singlethread)
FWIW here is another way to do it (which is approximately what ClamAV does currently) by introducing just one intrinsic:
declare i1 @llvm.is_bigendian()
The advantage is that you can implement htonl() and ntohl() like functionality without using a temporary memory location.
Actually I think having the 2 intrinsics you suggest and the is_bigendian() intrinsic would be optimal:
you can use your 2 intrinsics for initial codegen, and mem2reg can transform it to is_bigendian().
For load/store:
<type> %val = load <type>* %ptr
<type> %sval = bswap.i<type> %val
%result = <type> select @llvm.is_bigendian(), %val, %sval
For htonl():
<type> %sval = bswap.i<type> %val
%result = <type> select @llvm.is_bigendian(), %val, %sval
(store is similar, byteswap before the store)
At bytecode JIT time / assembly emission time @llvm.is_bigendian() is a known constant, and constant propagation is
used to throw away the unwanted code path, so it becomes either:
<type> %result = load <type>* %ptr
or
<type> %val = load <type>* %ptr
<type> %result = bswap.i<type> %val
Best regards,
--Edwin
More information about the llvm-dev
mailing list