[LLVMdev] SimplifyLibCalls doesn't check TLI for LibFunc availability

Kuperstein, Michael M michael.m.kuperstein at intel.com
Tue Aug 13 11:16:26 PDT 2013


Ok, I'll prepare a patch.

Michael

From: Eli Friedman [mailto:eli.friedman at gmail.com]
Sent: Tuesday, August 13, 2013 21:13
To: Kuperstein, Michael M
Cc: LLVMdev at cs.uiuc.edu; Raoux, Thomas F
Subject: Re: [LLVMdev] SimplifyLibCalls doesn't check TLI for LibFunc availability

On Tue, Aug 13, 2013 at 5:58 AM, Kuperstein, Michael M <michael.m.kuperstein at intel.com<mailto:michael.m.kuperstein at intel.com>> wrote:
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.



Bug.
-Eli

---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130813/14d96061/attachment.html>


More information about the llvm-dev mailing list