[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