[LLVMdev] endian issue of llvm-gcc and llvm backend

dodo dodohack at gmail.com
Thu Jun 4 17:41:49 PDT 2009


Hello, Sam

I used non-arm backend, and I used a target which likes mips has both big
and little endianness. And I have ported llvm-gcc to this platform along
with llvm backend.
The issue is about IR endianness and how backend deal with the data and
instructions in different endian, since I discovered 2 different IR
generates the same asm code by llc for different endian target.


> Message: 27
> Date: Thu, 4 Jun 2009 05:22:07 -0700 (PDT)
> From: Samuel Crow <samuraileumas at yahoo.com>
> Subject: Re: [LLVMdev] endian issue of llvm-gcc and llvm backend
> To: LLVM Developers Mailing List <llvmdev at cs.uiuc.edu>
> Message-ID: <157221.53893.qm at web62002.mail.re1.yahoo.com>
> Content-Type: text/plain; charset=us-ascii
>
>
> Hello,
>
> According to the frequently asked questions on the LLVM webpage, C++ and C
> cannot currently be used for platform indedpendent usage.  Your discovery
> doesn't fall on one of the often discovered problems though so it may be a
> bug in the ARM backend.  The ARM backend is considered to be experimental at
> this point so it is likely to have incorrect code in it.
>
> I hope I answered your question well enough,
>
> --Sam
> ________________________________
> From: dodo <dodohack at gmail.com>
> To: llvmdev at cs.uiuc.edu
> Sent: Thursday, June 4, 2009 3:14:28 AM
> Subject: [LLVMdev] endian issue of llvm-gcc and llvm backend
>
> Hi, all
>
> As I'm a Chinese, be patient of my poor description below.
>
> I compiled libgcc into llvm bitcode in both big endian and little endian.
> and got 2 different version of function: _ashldi3, the following is the
> fragment of this function:
>
> little endian:
> =============================================
> ......
> target datalayout =
> "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
> target triple = "nds32le-linux"
>
> define i64 @__ashldi3(i64 %u, i32 %b) nounwind readnone {
> entry:
>        %0 = icmp eq i32 %b, 0          ; <i1> [#uses=1]
>        br i1 %0, label %bb5, label %bb1
>
> bb1:            ; preds = %entry
>        %1 = trunc i64 %u to i32                ; <i32> [#uses=3]
>        %2 = sub i32 32, %b             ; <i32> [#uses=3]
>        %3 = icmp sgt i32 %2, 0         ; <i1> [#uses=1]
>        br i1 %3, label %bb3, label %bb2
> ......
> ==============================================
>
> big endian:
> ==============================================
> ......
> target datalayout =
> "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
> target triple = "nds32-linux"
>
> define i64 @__ashldi3(i64 %u, i32 %b) nounwind readnone {
> entry:
>        %0 = icmp eq i32 %b, 0          ; <i1> [#uses=1]
>        br i1 %0, label %bb5, label %bb1
>
> bb1:            ; preds = %entry
>        %sroa.store.elt = lshr i64 %u, 32               ; <i64> [#uses=1]
>        %1 = trunc i64 %sroa.store.elt to i32           ; <i32> [#uses=3]
>        %2 = sub i32 32, %b             ; <i32> [#uses=3]
>        %3 = icmp sgt i32 %2, 0         ; <i1> [#uses=1]
>        br i1 %3, label %bb3, label %bb2
> ......
> ==============================================
>
> >From the generated IR, we could see that llvm IR is endian dependent and
> it know how to get the low 32 bits of a 64 bits parameter.
>
> While generate asm code from these 2 different IR,  I got the same asm
> code.
> The following is the asm code which are mips like:
> (NOTE: $rx indicates a 32 bits register x, #x indicates constant, subri
> $r3, $r2, #32 means r3 = 32 - r2,
> r0, r1 contain the first 64 bits parameter which contains %u, r2 contains
> the second parameter %b)
>
> beqz $r2,83f6 <__ashldi3+0x2a>
> subri $r3,$r2,#32
> blez $r3,83fa <__ashldi3+0x2e>
> sll $r1,$r1,$r2
> srl $r3,$r0,$r3
> or $r3,$r3,$r1
> sll $r1,$r0,$r2
> movi $r2,#0
> mov $r0,$r1
> or $r1,$r3,$r2
> ret $lp
> ret $lp
> subri $r3,$r3,#0
> movi $r1,#0
> sll $r3,$r0,$r3
>
> The above asm code is tested ok in little endian, and not ok in big endian,
> because it does not get paramter %u correctly, for big endian, r0, r1 in
>  that asm code should be exchanged  for endian  issue.
>
> One possible reason is that I generate code for big endian and llvm-gcc
> really generates big endian IR for me(from the presented IR, it did). Then I
> use llc to generate asm code, llc eat the target triple and/or datalayout
> from the bitcode and generates big endian asm code for me again.
> The result is that:  llvm-gcc gen'ed big endian code + llc gen'ed big
> endian code = little endian code, am I right?
>
> If I want to generate correct asm code for big endian? what should I do?
> I have tried to generate big endian asm code from little endian IR by
> giving -march option to llc to force the target to big endian, but this
> seems to be unworkable!
>
>
-- 
dodohack at ybu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090605/38911e2e/attachment.html>


More information about the llvm-dev mailing list