summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAndrew Ng <anng.sw@gmail.com>2017-04-25 12:36:14 +0000
committerAndrew Ng <anng.sw@gmail.com>2017-04-25 12:36:14 +0000
commit1606fc0bf90fa984f335c7d9d7b56761afa0e67a (patch)
tree8afed9a011b2868979f7a280f8dd96087b00c178 /llvm/lib
parentab0446332e7b50328499e138b9856625a6577109 (diff)
downloadbcm5719-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.cpp18
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());
OpenPOWER on IntegriCloud