[LLVMdev] CBE errors

Jeffrey Sandoval jasandov at rice.edu
Fri Nov 7 10:31:52 PST 2008


I'm running into some strange errors with the CBE.  I've narrowed the  
problem down to a very simple CPP program:

#include <string>

static std::string hello("Hello world!");

int main() {
   return 0;

When I generate C code (using LLVM's C backend) with the following  
commands, I get a compile error on the resulting C code:

$ llvm-g++ -emit-llvm -O2 -c -o main.bc main.cpp
$ llc -f -march=c main.bc
$ gcc -c main.cbe.c
main.cbe.c:223: warning: conflicting types for built-in function  
main.cbe.c: In function ‘main’:
main.cbe.c:254: warning: return type of ‘main’ is not ‘int’
main.cbe.c: In function ‘__tcf_0’:
main.cbe.c:286: error: ‘_ZL22__gthrw_pthread_cancelm’ undeclared  
(first use in this function)
main.cbe.c:286: error: (Each undeclared identifier is reported only once
main.cbe.c:286: error: for each function it appears in.)

Here are the relevant lines from main.cbe.c.  Notice that  
"pthread_cancel" is declared as a weak external symbol, but  
"_ZL22__gthrw_pthread_cancelm" is never declared (even though it is  

$ grep -Hn pthread_cancel main.cbe.c
main.cbe.c:213:extern unsigned int pthread_cancel(unsigned long long )  
main.cbe.c:286:  if ((((unsigned char )(bool )(((unsigned int )(bool ) 
(_ZL22__gthrw_pthread_cancelm != ((unsigned int  (*) (unsigned long  
long ))/*NULL*/0))) != 0u)) != ((unsigned char )0))) {

Here are the relevant lines from the LLVM bitcode.  The bitcode  
appears correct since "pthread_cancel" is declared as extern_weak and  
the alias "_ZL22__gthrw_pthread_cancelm" is declared as a weak alias  
of "pthread_cancel".  I'm just a bit confused about "pthread_cancel"  
-- shouldn't it be declared as a regular external symbol?

$ llvm-dis main.bc
$ grep -Hn pthread_cancel main.ll
main.ll:24:@_ZL22__gthrw_pthread_cancelm = alias weak i32 (i64)*  
@pthread_cancel		; <i32 (i64)*> [#uses=1]
main.ll:57:	br i1 icmp ne (i8 zext (i1 icmp ne (i32 zext (i1 icmp ne  
(i32 (i64)* @_ZL22__gthrw_pthread_cancelm, i32 (i64)* null) to i32),  
i32 0) to i8), i8 0), label %bb69, label %bb76
main.ll:120:declare extern_weak i32 @pthread_cancel(i64)

Finally, looking at the preprocessed main.cpp file (before running it  
through LLVM), I can see the appropriate declarations for  
"pthread_cancel" and its alias.  This (mostly) matches the LLVM  
representation above.

$ llvm-g++ -emit-llvm -E -o main.E.cpp main.cpp
$ grep -Hn pthread_cancel main.E.cpp
main.E.cpp:4414:extern int pthread_cancel (pthread_t __th);
main.E.cpp:6058:static __typeof(pthread_cancel) __gthrw_pthread_cancel  
__attribute__ ((__weakref__("pthread_cancel")));
main.E.cpp:6075:    = __extension__ (void *) &__gthrw_pthread_cancel;

So, it looks like the CBE code generator is not producing correct  
output for the alias, since the LLVM bitcode appears correct.  Has  
anybody seen anything like this before?  Or, am I just doing something  
wrong?  I'm not quite sure why pthreads are involved with just  
creating a std::string; but, if I understand it correctly, the alias  
is meant to be a "weak" symbol that resolves to NULL if the symbol is  
not found during linking.  (This makes sense, since the code is  
checking to see whether the symbol value is NULL.)  The CBE correctly  
generates an external weak declaration for pthread_cancel, but it  
produces no declaration for the associated alias.  This problem only  
appears when I turn on optimization (any level above 0) -- the code  
compiles fine at "-O0".

I'm using LLVM release 2.3, but I also verified that the problem  
occurs with the latest trunk revision from SVN.  I'm on x86_64 linux  
(Fedora 8).

Any help would be appreciated!  (If you want copies of my files, just  
let me know and I'll post them somewhere -- however, the problem  
should be easy to duplicate with the input file I gave above.)


Jeff Sandoval

More information about the llvm-dev mailing list