Hi Duncan,
thanks for your response. Meanwhile I got a quick and dirty version
working.
It is. For example you can declare a new global constant P2 with the
appropriate initial value (0 or 1), then do:
P->replaceAllUsesWith(P2).
At that you can erase (i.e. delete) P.
I'm currently using a global variable, set it's initializer to a freshly
created constant value, declare the variable as itself being constant
and set it's linkage to internal.
Running the instcombine pass on
the module should then propagate the information into all functions;
following that by a run of the simplifycfg pass will get rid of dead
basic blocks.
I used a complete set of standard optimizations copy-pasted from some
tutorials. I was surprised that's all I had to do. Pretty cool and fast

So everything ends up in something like:
bc = MemoryBuffer::getFile ("test.bc");
mod = ParseBitcodeFile (bc, Context);
GlobalVariable *val;
ConstantInt *const_val;
val = mod->getNamedGlobal ("P");
const_val = ConstantInt::get (Context, APInt (32, 1234));
val->setInitializer (const_val);
val->setConstant (true);
val->setLinkage (GlobalValue::InternalLinkage);
FunctionPassManager fpm (mod);
fpm.add (createInstructionCombiningPass());
fpm.add (createCFGSimplificationPass ());
fpm.doInitialization ();
Function *f = mod->getFunction ("t");
fpm.run (*f);
This allows me to write in C:
int P;
float t (float a, float b) {
if (P == 0)
return a - b;
else
return b - a;
}
compiling this with: clang -O3 -x c test.c -emit-llvm -c -o test.bc
results in:
@P = common global i32 0, align 4 ; <i32*> [#uses=1]
define float @t(float %a, float %b) nounwind readonly {
%1 = load i32* @P ; <i32> [#uses=1]
%2 = icmp eq i32 %1, 0 ; <i1> [#uses=1]
br i1 %2, label %3, label %5
; <label>:3 ; preds = %0
%4 = fsub float %a, %b ; <float> [#uses=1]
ret float %4
; <label>:5 ; preds = %0
%6 = fsub float %b, %a ; <float> [#uses=1]
ret float %6
}
and after replacing the global with a constant and run the optimizations
I get a simple:
define float @t(float %a, float %b) nounwind readnone {
%1 = fsub float %a, %b ; <float> [#uses=1]
ret float %1
}
That is what I wanted. LLVM is really pretty cool stuff...