Hi,
It looks like SimplifyLibCalls has a tendency to emit calls to libm functions without checking with TLI whether these calls are available.
For example, PowOpt has this code:
struct PowOpt : public UnsafeFPLibCallOptimization {
PowOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {}
virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Value *Ret = NULL;
if (UnsafeFPShrink && Callee>getName() == “pow” &&
TLI>has(LibFunc::powf)) {
UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);
}
[…]
if (Op2C>isExactlyValue(0.5)) {
// Expand pow(x, 0.5) to (x == infinity ? +infinity : fabs(sqrt(x))).
// This is faster than calling pow, and still handles negative zero
// and negative infinity correctly.
// TODO: In fastmath mode, this could be just sqrt(x).
// TODO: In finiteonly mode, this could be just fabs(sqrt(x)).
Value *Inf = ConstantFP::getInfinity(CI>getType());
Value *NegInf = ConstantFP::getInfinity(CI>getType(), true);
Value *Sqrt = EmitUnaryFloatFnCall(Op1, “sqrt”, B,
Callee>getAttributes());
Value *FAbs = EmitUnaryFloatFnCall(Sqrt, “fabs”, B,
Callee>getAttributes());
Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf);
Value *Sel = B.CreateSelect(FCmp, Inf, FAbs);
return Sel;
}
[…]
}
So, before the callOptimizer call, it actually does check TLI to see that powf is available. However, the code below (that expands pow(x, 0.5) ) emits sqrt and fabs without making any checks.
This may be problematic in two cases:

If LibFunc::pow is available, but LibFunc::sqrt and LibFunc::fabs are not. This is not very likely, but I guess it is technically possible.

The simplification functions are also called for intrinsics (pow and exp2). In this case, it’s possible that libm is not available at all.
Is this a bug, or am I missing something here? Those unchecked EmitnaryFloatFnCalls are all over the pass.
Thanks,
Michael