LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 3043 - lli fails pointer comparison test
Summary: lli fails pointer comparison test
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: MCJIT (show other bugs)
Version: trunk
Hardware: All All
: P normal
Assignee: Evan Cheng
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-11-11 10:39 PST by Evan Cheng
Modified: 2008-11-22 16:14 PST (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Evan Cheng 2008-11-11 10:39:46 PST
From Prakash Prabhu:


#include<stdio.h>
#include<stdlib.h>

void test();
void (*funcPtr)();

int main(int argc, char **argv) {
  funcPtr = test;
  test();
}

void test() {
  if(funcPtr == test) {
    printf("OK!\n");
  } else {
    fprintf(stderr, "Bad!\n");
    exit(1);
  }
}

$ llvm-gcc -emit-llvm -o FPtrEqTest.bc -c FPtrEqTest.c
$ llc -f FPtrEqTest.bc
$ gcc -o FPtrEqTest FPtrEqTest.s
$ ./FPtrEqTest
OK!

$ lli FPtrEqTest.bc
Bad!
Comment 1 Evan Cheng 2008-11-11 12:24:44 PST
Hrm. This has to do with lazy compilation.

The generated assembly looks like this with -relocation-model=pic:

_main:
        ...
        leal    _test-"L1$pb"(%eax), %ecx
        movl    L_funcPtr$non_lazy_ptr-"L1$pb"(%eax), %eax
        movl    %ecx, (%eax)
        call    _test

_test:
        ...
        leal    _test-"L2$pb"(%eax), %ecx
        movl    L_funcPtr$non_lazy_ptr-"L2$pb"(%eax), %edx
        cmpl    %ecx, (%edx)
        jne     LBB2_3  ## bb1

Looking at -debug-only=jit dump with -relocation-model=pic

JIT: Stub emitted at [0x207fff8] for function 'test'
JIT: Map 'funcPtr' to [0x2080044]
JIT: Initializing 0x2080044 void () * null
JIT: Indirect symbol emitted at [0x207fff4] for GV 'funcPtr'
JIT: Finished CodeGen of [0x2080010] Function: main: 56 bytes of text, 3 relocations
...
JIT: Lazily resolving function 'test' In stub ptr = 0x2080038 actual ptr = 0x2080038
JIT: Starting CodeGen of Function test

The disassembled code looks like this:
0x02080050:     sub    $0x1c,%esp
...
0x02080059:     lea    -0x8(%eax),%ecx
0x0208005f:     mov    -0x64(%eax),%edx
0x02080065:     cmp    %ecx,(%edx)
0x02080067:     jne    0x208007f

After the lea, %ecx contains 0x02080050 which is the address of test. After the load, %edx is 0x2080044. However, the value in 0x2080044 is 0x0207fff8 which is the address of test's stub.
Comment 2 Evan Cheng 2008-11-11 12:26:12 PST
The problem is at the time the address of "test" is taken, it has not been compiled. So it stored the address of its stub instead.
Comment 3 Evan Cheng 2008-11-11 12:42:50 PST
I think the current solution would be something like this:

1. When code emitter sees a function address, emit it as a relocation and remember the function.
2. After the function has been emitted, compile and emit all functions whose addresses are taken.
3. Relocate all references to function addresses.
Comment 4 Thomas B. Jablin 2008-11-11 15:25:27 PST
Alternatively, you could emit all function pointers as pointers to the function's stub. The disadvantage of compiling a function whenever its address is taken is that in a C++ program all the entries all vtable would have to be compiled before execution began. Some C programs also contain statically initialized lists of functions that may or may not be called at runtime. The disadvantage of emitting function pointers as pointers to stubs is that it increases the overhead per function call.
Comment 5 Evan Cheng 2008-11-13 15:58:54 PST
Right. That's an acceptable solution for now. Thanks.
Fixed here:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20081110/069830.html
Comment 6 Thomas B. Jablin 2008-11-22 16:14:37 PST
(In reply to comment #5)
> Right. That's an acceptable solution for now. Thanks.
> Fixed here:
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20081110/069830.html
> 

Thanks!