SimplifyLibCalls doesn't check TLI for LibFunc availability

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 fast-math mode, this could be just sqrt(x).

// TODO: In finite-only 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:

  1. 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.

  2. 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

Bug.

-Eli

Ok, I’ll prepare a patch.

Michael