diff options
| author | Andrew Ng <anng.sw@gmail.com> | 2017-04-25 12:36:14 +0000 |
|---|---|---|
| committer | Andrew Ng <anng.sw@gmail.com> | 2017-04-25 12:36:14 +0000 |
| commit | 1606fc0bf90fa984f335c7d9d7b56761afa0e67a (patch) | |
| tree | 8afed9a011b2868979f7a280f8dd96087b00c178 /llvm/lib | |
| parent | ab0446332e7b50328499e138b9856625a6577109 (diff) | |
| download | bcm5719-llvm-1606fc0bf90fa984f335c7d9d7b56761afa0e67a.tar.gz bcm5719-llvm-1606fc0bf90fa984f335c7d9d7b56761afa0e67a.zip | |
[SimplifyLibCalls] Fix infinite loop with fast-math optimization.
One of the fast-math optimizations is to replace calls to standard double
functions with their float equivalents, e.g. exp -> expf. However, this can
cause infinite loops for the following:
float expf(float val) { return (float) exp((double) val); }
A similar inline declaration exists in the MinGW-w64 math.h header file which
when compiled with -O2/3 and fast-math generates infinite loops.
So this fix checks that the calling function to the standard double function
that is being replaced does not match the float equivalent.
Differential Revision: https://reviews.llvm.org/D31806
llvm-svn: 301304
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 956bd08d852..4818939824e 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -926,6 +926,24 @@ static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B, if (V == nullptr) return nullptr; + // If call isn't an intrinsic, check that it isn't within a function with the + // same name as the float version of this call. + // + // e.g. inline float expf(float val) { return (float) exp((double) val); } + // + // A similar such definition exists in the MinGW-w64 math.h header file which + // when compiled with -O2 -ffast-math causes the generation of infinite loops + // where expf is called. + if (!Callee->isIntrinsic()) { + const Function *F = CI->getFunction(); + StringRef FName = F->getName(); + StringRef CalleeName = Callee->getName(); + if ((FName.size() == (CalleeName.size() + 1)) && + (FName.back() == 'f') && + FName.startswith(CalleeName)) + return nullptr; + } + // Propagate fast-math flags from the existing call to the new call. IRBuilder<>::FastMathFlagGuard Guard(B); B.setFastMathFlags(CI->getFastMathFlags()); |

