aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-01-21 20:19:54 +0000
committerSanjay Patel <spatel@rotateright.com>2016-01-21 20:19:54 +0000
commitfcc7c1a0baf8341b2d0926bd2e5244d684b48d8d (patch)
tree15eb980c3cd59427508dbc7cc8a4c7e9782b1ec5 /llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
parent88d79a06b73952affd09f38da90e57d549fdaa5e (diff)
downloadllvm-fcc7c1a0baf8341b2d0926bd2e5244d684b48d8d.zip
llvm-fcc7c1a0baf8341b2d0926bd2e5244d684b48d8d.tar.gz
llvm-fcc7c1a0baf8341b2d0926bd2e5244d684b48d8d.tar.bz2
[LibCallSimplifier] don't get fooled by a fake fmin()
This is similar to the bug/fix: https://llvm.org/bugs/show_bug.cgi?id=26211 http://reviews.llvm.org/rL258325 The fmin() test case reveals another bug caused by sloppy code duplication. It will crash without this patch because fp128 is a valid floating-point type, but we would think that we had matched a function that used doubles. The new helper function can be used to replace similar checks that are used in several other places in this file. llvm-svn: 258428
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 4f79509..da4a478 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -953,13 +953,34 @@ static Value *valueHasFloatPrecision(Value *Val) {
return nullptr;
}
+/// Any floating-point library function that we're trying to simplify will have
+/// a signature of the form: fptype foo(fptype param1, fptype param2, ...).
+/// CheckDoubleTy indicates that 'fptype' must be 'double'.
+static bool matchesFPLibFunctionSignature(const Function *F, unsigned NumParams,
+ bool CheckDoubleTy) {
+ FunctionType *FT = F->getFunctionType();
+ if (FT->getNumParams() != NumParams)
+ return false;
+
+ // The return type must match what we're looking for.
+ Type *RetTy = FT->getReturnType();
+ if (CheckDoubleTy ? !RetTy->isDoubleTy() : !RetTy->isFloatingPointTy())
+ return false;
+
+ // Each parameter must match the return type, and therefore, match every other
+ // parameter too.
+ for (const Type *ParamTy : FT->params())
+ if (ParamTy != RetTy)
+ return false;
+
+ return true;
+}
+
/// Shrink double -> float for unary functions like 'floor'.
static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B,
bool CheckRetType) {
Function *Callee = CI->getCalledFunction();
- FunctionType *FT = Callee->getFunctionType();
- if (FT->getNumParams() != 1 || !FT->getReturnType()->isDoubleTy() ||
- !FT->getParamType(0)->isDoubleTy())
+ if (!matchesFPLibFunctionSignature(Callee, 1, true))
return nullptr;
if (CheckRetType) {
@@ -997,12 +1018,7 @@ static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B,
/// Shrink double -> float for binary functions like 'fmin/fmax'.
static Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilder<> &B) {
Function *Callee = CI->getCalledFunction();
- FunctionType *FT = Callee->getFunctionType();
- // Just make sure this has 2 arguments of the same FP type, which match the
- // result type.
- if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
- FT->getParamType(0) != FT->getParamType(1) ||
- !FT->getParamType(0)->isFloatingPointTy())
+ if (!matchesFPLibFunctionSignature(Callee, 2, true))
return nullptr;
// If this is something like 'fmin((double)floatval1, (double)floatval2)',