Skip to content

Commit fcc7c1a

Browse files
committedJan 21, 2016
[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
1 parent 88d79a0 commit fcc7c1a

File tree

2 files changed

+45
-9
lines changed

2 files changed

+45
-9
lines changed
 

‎llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

+25-9
Original file line numberDiff line numberDiff line change
@@ -953,13 +953,34 @@ static Value *valueHasFloatPrecision(Value *Val) {
953953
return nullptr;
954954
}
955955

956+
/// Any floating-point library function that we're trying to simplify will have
957+
/// a signature of the form: fptype foo(fptype param1, fptype param2, ...).
958+
/// CheckDoubleTy indicates that 'fptype' must be 'double'.
959+
static bool matchesFPLibFunctionSignature(const Function *F, unsigned NumParams,
960+
bool CheckDoubleTy) {
961+
FunctionType *FT = F->getFunctionType();
962+
if (FT->getNumParams() != NumParams)
963+
return false;
964+
965+
// The return type must match what we're looking for.
966+
Type *RetTy = FT->getReturnType();
967+
if (CheckDoubleTy ? !RetTy->isDoubleTy() : !RetTy->isFloatingPointTy())
968+
return false;
969+
970+
// Each parameter must match the return type, and therefore, match every other
971+
// parameter too.
972+
for (const Type *ParamTy : FT->params())
973+
if (ParamTy != RetTy)
974+
return false;
975+
976+
return true;
977+
}
978+
956979
/// Shrink double -> float for unary functions like 'floor'.
957980
static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B,
958981
bool CheckRetType) {
959982
Function *Callee = CI->getCalledFunction();
960-
FunctionType *FT = Callee->getFunctionType();
961-
if (FT->getNumParams() != 1 || !FT->getReturnType()->isDoubleTy() ||
962-
!FT->getParamType(0)->isDoubleTy())
983+
if (!matchesFPLibFunctionSignature(Callee, 1, true))
963984
return nullptr;
964985

965986
if (CheckRetType) {
@@ -997,12 +1018,7 @@ static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B,
9971018
/// Shrink double -> float for binary functions like 'fmin/fmax'.
9981019
static Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilder<> &B) {
9991020
Function *Callee = CI->getCalledFunction();
1000-
FunctionType *FT = Callee->getFunctionType();
1001-
// Just make sure this has 2 arguments of the same FP type, which match the
1002-
// result type.
1003-
if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
1004-
FT->getParamType(0) != FT->getParamType(1) ||
1005-
!FT->getParamType(0)->isFloatingPointTy())
1021+
if (!matchesFPLibFunctionSignature(Callee, 2, true))
10061022
return nullptr;
10071023

10081024
// If this is something like 'fmin((double)floatval1, (double)floatval2)',

‎llvm/test/Transforms/InstCombine/double-float-shrink-1.ll

+20
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,26 @@ define float @max1(float %a, float %b) {
364364
; CHECK-NEXT: ret
365365
}
366366

367+
; A function can have a name that matches a common libcall,
368+
; but with the wrong type(s). Let it be.
369+
370+
define float @fake_fmin(float %a, float %b) {
371+
%c = fpext float %a to fp128
372+
%d = fpext float %b to fp128
373+
%e = call fp128 @fmin(fp128 %c, fp128 %d)
374+
%f = fptrunc fp128 %e to float
375+
ret float %f
376+
377+
; CHECK-LABEL: fake_fmin(
378+
; CHECK-NEXT: %c = fpext float %a to fp128
379+
; CHECK-NEXT: %d = fpext float %b to fp128
380+
; CHECK-NEXT: %e = call fp128 @fmin(fp128 %c, fp128 %d)
381+
; CHECK-NEXT: %f = fptrunc fp128 %e to float
382+
; CHECK-NEXT: ret float %f
383+
}
384+
385+
declare fp128 @fmin(fp128, fp128) ; This is not the 'fmin' you're looking for.
386+
367387
declare double @fmax(double, double)
368388

369389
declare double @tanh(double)

0 commit comments

Comments
 (0)
Please sign in to comment.