[LLVMdev] JIT on ARM

Jeffrey Yasskin jyasskin at google.com
Tue Jan 19 08:43:03 PST 2010


This sounds like http://llvm.org/bugs/show_bug.cgi?id=5201. The
summary of that bug talks about x86, but it applies to arm too, and
with a much smaller offset limit. I didn't remember it happening with
external functions, but there could be cases where it does. To check,
can you run your program in a debugger and look at the address of
my_add1 and the address it actually calls (and crashes on)? If it's
this bug, the low bits will be right, and the high bits will be the
same as the caller.

On Monday, January 18, 2010, Martins Mozeiko <49640f8a at gmail.com> wrote:
> Hi.
> I am trying to run LLVM with JIT on ARM processor (Android phone).
> Currently I have problems using external functions. Any call to external function crashes and gives me signal 11 (SIGSEGV) at some random address.
>
> I'm trying to run following C code:
> ***
> extern void add1(int* x);
> int main()
> {
>     int a = 10;
>     int b = 20;
>     add1(&b);
>     int c = a + b;
>     return c;
> }
> ***
> It gives me following LL code:
> ***
> define i32 @main() nounwind {
> entry:
>   %b = alloca i32, align 4                        ; <i32*> [#uses=3]
>   store i32 20, i32* %b, align 4
>   call void @add1(i32* %b) nounwind
>   %0 = load i32* %b, align 4                      ; <i32> [#uses=1]
>   %1 = add nsw i32 %0, 10                         ; <i32> [#uses=1]
>   ret i32 %1
> }
>
> declare void @add1(i32*)
> ***
> When using llvm::DebugFlag=true JIT gives me following debug messages:
>
> ********** Function: main
>
> Ifcvt: function (0) 'main'
> block 0 offset 0 size 40
> block 0 offset 0 size 40
> JITTing function 'main'
> JIT: Starting CodeGen of Function main
> JIT: Emitting BB0 at [0x4512e010]
> JIT: 0x4512e010:        STM %SP, 12, 14, %reg0, %R11<kill>, %LR<kill>
>   0xe92d4800
> JIT: 0x4512e014:        %SP<def> = SUBri %SP<kill>, 8, 14, %reg0, %reg0
>   0xe24dd008
> JIT: 0x4512e018:        %R0<def> = MOVi 20, 14, %reg0, %reg0
>   0xe3a00014
> JIT: 0x4512e01c:        STR %R0<kill>, %SP, %reg0, 4, 14, %reg0, Mem:ST(4,4) [b + 0]
>   0xe58d0004
> JIT: 0x4512e020:        %R0<def> = ADDri %SP, 4, 14, %reg0, %reg0
>   0xe28d0004
> JIT: 0x4512e024:        BL <ga:add1>, %R0<kill>, %R0<imp-def,dead>, %R1<imp-def,dead>, %R2<imp-def,dead>, %R3<imp-def,dead>, %R12<imp-def,dead>, %LR<imp-def,dead>, %D0<imp-def,dead>, %D1<imp-def,dead>, %D2<imp-def,dead>, %D3<imp-def,dead>, %D4<imp-def,dead>, %D5<imp-def,dead>, %D6<imp-def,dead>, %D7<imp-def,dead>, %D16<imp-def,dead>, %D17<imp-def,dead>, %D18<imp-def,dead>, %D19<imp-def,dead>, %D20<imp-def,dead>, %D21<imp-def,dead>, %D22<imp-def,dead>, %D23<imp-def,dead>, %D24<imp-def,dead>, %D25<imp-def,dead>, %D26<imp-def,dead>, %D27<imp-def,dead>, %D28<imp-def,dead>, %D29<imp-def,dead>, %D30<imp-def,dead>, %D31<imp-def,dead>, %CPSR<imp-def,dead>
>   0xeb000000
> JIT: 0x4512e028:        %R0<def> = LDR %SP, %reg0, 4, 14, %reg0, Mem:LD(4,4) [b + 0]
>   0xe59d0004
> JIT: 0x4512e02c:        %R0<def> = ADDri %R0<kill>, 10, 14, %reg0, %reg0
>   0xe280000a
> JIT: 0x4512e030:        %SP<def> = ADDri %SP<kill>, 8, 14, %reg0, %reg0
>   0xe28dd008
> JIT: 0x4512e034:        LDM_RET %SP, 9, 14, %reg0, %R11<def>, %PC<def>
>   0xe8bd8800
> JIT: Map 'add1' to [0x808e80b4]
> JIT: Stub emitted at [0x42540008] for function 'add1'
> JIT: Finished CodeGen of [0x4512e010] Function: main: 40 bytes of text, 1 relocations
> JIT: Binary code:
> JIT: 00000000: e92d4800 e24dd008 e3a00014 e58d0004
> JIT: 00000010: e28d0004 eb5047f7 e59d0004 e280000a
> JIT: 00000020: e28dd008 e8bd8800
> ****
>
> Just to be sure I inform LLVM about add1 function with following code:
> extern "C" void my_add1(int* x)
> {
>     LOG("in add1, x=%i\n", *x);
>     *x = *x + 1;
> }
> sys::DynamicLibrary::AddSymbol("add1", (void*)&my_add1);
>
> Is there something wrong with generated code? Same code, using same test program, runs fine using JIT on x86 under Windows.
>
> I have successfuly run program that doesn't use external functions. For example following C code
> ****
> int main()
> {
>     int a = 10;
>     int b = 20;
>     int c = a + b;
>     return c;
> }
> ****
> compiles to following LL code:
> ****
> define i32 @main() nounwind readnone {
> entry:
>   ret i32 30
> }
> ****
> which runs fine on ARM. When using llvm::DebugFlag=true JIT prints following debug messages:
> ********** Function: main
>
> Ifcvt: function (0) 'main'
> block 0 offset 0 size 8
> block 0 offset 0 size 8
> JITTing function 'main'
> JIT: Starting CodeGen of Function main
> JIT: Emitting BB0 at [0x4512e010]
> JIT: 0x4512e010:        %R0<def> = MOVi 30, 14, %reg0, %reg0
>   0xe3a0001e
> JIT: 0x4512e014:        BX_RET 14, %reg0, %R0<imp-use,kill>
>   0xe12fff1e
> JIT: Finished CodeGen of [0x4512e010] Function: main: 8 bytes of text, 0 relocations
> JIT: Binary code:
> JIT: 00000000: e3a0001e e12fff1e
> ***
>
> I appreciate any suggestions what can I do in my situation.
>
> --
> Martins Mozeiko
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>




More information about the llvm-dev mailing list