<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Aug 13, 2013 at 5:58 AM, Kuperstein, Michael M <span dir="ltr"><<a href="mailto:michael.m.kuperstein@intel.com" target="_blank">michael.m.kuperstein@intel.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div link="blue" vlink="purple" lang="EN-US">
<div>
<p class="MsoNormal">Hi,<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">It looks like SimplifyLibCalls has a tendency to emit calls to libm functions without checking with TLI whether these calls are available.<u></u><u></u></p>
<p class="MsoNormal">For example, PowOpt has this code:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">struct PowOpt : public UnsafeFPLibCallOptimization {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  PowOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {}<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    Value *Ret = NULL;<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    if (UnsafeFPShrink && Callee->getName() == "pow" &&<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">        TLI->has(LibFunc::powf)) {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    }<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">[...]<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    if (Op2C->isExactlyValue(0.5)) {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))).<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      // This is faster than calling pow, and still handles negative zero<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      // and negative infinity correctly.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      // TODO: In fast-math mode, this could be just sqrt(x).<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      // TODO: In finite-only mode, this could be just fabs(sqrt(x)).<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      Value *Inf = ConstantFP::getInfinity(CI->getType());<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      Value *NegInf = ConstantFP::getInfinity(CI->getType(), true);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      Value *Sqrt = EmitUnaryFloatFnCall(Op1, "sqrt", B,<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">                                         Callee->getAttributes());<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      Value *FAbs = EmitUnaryFloatFnCall(Sqrt, "fabs", B,<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">                                         Callee->getAttributes());<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      Value *Sel = B.CreateSelect(FCmp, Inf, FAbs);<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      return Sel;<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    }<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">[...]<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">}<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal">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.<u></u><u></u></p>

<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">This may be problematic in two cases:<u></u><u></u></p>
<p><u></u><span>1)<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u><span dir="LTR"></span>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.<u></u><u></u></p>
<p><u></u><span>2)<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u><span dir="LTR"></span>The simplification functions are also called for intrinsics (pow and exp2). In this case, it’s possible that libm is not available at all.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Is this a bug, or am I missing something here? Those unchecked EmitnaryFloatFnCalls are all over the pass.<u></u><u></u></p>
<p class="MsoNormal"> </p><p class="MsoNormal"><br></p></div></div></blockquote><div><br></div><div>Bug.<br><br></div><div>-Eli <br></div></div><br></div></div>