Kuperstein, Michael M
2013-Aug-13 12:58 UTC
[LLVMdev] 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 --------------------------------------------------------------------- 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/fbe347eb/attachment.html>
Eli Friedman
2013-Aug-13 18:13 UTC
[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> 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130813/18b8bb08/attachment.html>
Kuperstein, Michael M
2013-Aug-13 18:16 UTC
[LLVMdev] SimplifyLibCalls doesn't check TLI for LibFunc availability
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>