Folding cast of a global address to boolean

I noticed that folding a cast of a global address to boolean doesn't work like I expected - there is a comment in the code that casts of external symbols should not happen, but I don't understand the rationale for this.

// FIXME: When we support 'external weak' references, we have to prevent
// this transformation from happening. In the meantime we avoid folding
// any cast of an external symbol.
     if (!GV->isExternal())
       return ConstantBool::True;

This particular transformation is quite important for me because I have some symbols which are either ConstantPointerNull or a GlovalVariable depending on which context the program is compiled in. This is used to implement a kind of conditional compilation, and I'm relying on the constant folding to remove branches in my code. I tried to change the linkage type of the GlobalValue, but that's not what the isExternal() function checks so it did not have any effect.

If I understood better why this is disabled, maybe I can fix it. Otherwise I will have to implement the conditional compilation as part of the code generation and that will be quite a bit more complicated.

m.

I noticed that folding a cast of a global address to boolean doesn't work like I expected - there is a comment in the code that casts of external symbols should not happen, but I don't understand the rationale for this.

// FIXME: When we support 'external weak' references, we have to prevent
// this transformation from happening. In the meantime we avoid folding
// any cast of an external symbol.
   if (!GV->isExternal())
     return ConstantBool::True;

The basic idea is that we currently do not support globals with "external weak" linkage, but we will someday. The semantics of an external weak symbol are somewhat interesting: if a definition of the symbol is ever linked into the program, the symbol gets that address (obviously). If a definition is never linked into the program, all uses of the global get a null pointer instead.

This is often used in situations where you want to have code conditional on whether the library is linked into a pthreads-enabled program. It allows you to do stuff like this:

"external weak" pthread_create(...);

...
   if (pthread_create) {
     // Linked to -lpthread.
   }

If a body for pthread_create is linked into the program, the conditional will evaluate to true.

This particular transformation is quite important for me because I have some symbols which are either ConstantPointerNull or a GlovalVariable depending on which context the program is compiled in. This is used to implement a kind of conditional compilation, and I'm relying on the constant folding to remove branches in my code. I tried to change the linkage type of the GlobalValue, but that's not what the isExternal() function checks so it did not have any effect.

Yeah, external functions (those without a body) must have external linkage right now.

If I understood better why this is disabled, maybe I can fix it. Otherwise I will have to implement the conditional compilation as part of the code generation and that will be quite a bit more complicated.

There is no good reason for it to be disabled, so I enabled it. When we add support for "external weak", we should add a check in that code path to make sure the global is not external weak. Until then, we shouldn't pessimize code.

http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20050103/022961.html

-Chris