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

Samuel Crow samuraileumas at yahoo.com
Thu Jun 4 05:22:07 PDT 2009


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



      



More information about the llvm-dev mailing list