1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[InstCombine] Don't transform compares of calls to functions named fabs{f,l,}

InstCombine wants to optimize compares of calls to fabs with zero.
However, we didn't have the necessary legality checking to verify that
the function call had the same behavior as fabs.

llvm-svn: 266452
This commit is contained in:
David Majnemer 2016-04-15 17:21:03 +00:00
parent 79ebd7fb73
commit 77f3549d90
2 changed files with 37 additions and 30 deletions

View File

@ -26,6 +26,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/VectorUtils.h"
using namespace llvm;
using namespace PatternMatch;
@ -4564,39 +4565,33 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
break;
CallInst *CI = cast<CallInst>(LHSI);
const Function *F = CI->getCalledFunction();
if (!F)
Intrinsic::ID IID = getIntrinsicIDForCall(CI, TLI);
if (IID != Intrinsic::fabs)
break;
// Various optimization for fabs compared with zero.
LibFunc::Func Func;
if (F->getIntrinsicID() == Intrinsic::fabs ||
(TLI->getLibFunc(F->getName(), Func) && TLI->has(Func) &&
(Func == LibFunc::fabs || Func == LibFunc::fabsf ||
Func == LibFunc::fabsl))) {
switch (I.getPredicate()) {
default:
break;
// fabs(x) < 0 --> false
case FCmpInst::FCMP_OLT:
llvm_unreachable("handled by SimplifyFCmpInst");
// fabs(x) > 0 --> x != 0
case FCmpInst::FCMP_OGT:
return new FCmpInst(FCmpInst::FCMP_ONE, CI->getArgOperand(0), RHSC);
// fabs(x) <= 0 --> x == 0
case FCmpInst::FCMP_OLE:
return new FCmpInst(FCmpInst::FCMP_OEQ, CI->getArgOperand(0), RHSC);
// fabs(x) >= 0 --> !isnan(x)
case FCmpInst::FCMP_OGE:
return new FCmpInst(FCmpInst::FCMP_ORD, CI->getArgOperand(0), RHSC);
// fabs(x) == 0 --> x == 0
// fabs(x) != 0 --> x != 0
case FCmpInst::FCMP_OEQ:
case FCmpInst::FCMP_UEQ:
case FCmpInst::FCMP_ONE:
case FCmpInst::FCMP_UNE:
return new FCmpInst(I.getPredicate(), CI->getArgOperand(0), RHSC);
}
switch (I.getPredicate()) {
default:
break;
// fabs(x) < 0 --> false
case FCmpInst::FCMP_OLT:
llvm_unreachable("handled by SimplifyFCmpInst");
// fabs(x) > 0 --> x != 0
case FCmpInst::FCMP_OGT:
return new FCmpInst(FCmpInst::FCMP_ONE, CI->getArgOperand(0), RHSC);
// fabs(x) <= 0 --> x == 0
case FCmpInst::FCMP_OLE:
return new FCmpInst(FCmpInst::FCMP_OEQ, CI->getArgOperand(0), RHSC);
// fabs(x) >= 0 --> !isnan(x)
case FCmpInst::FCMP_OGE:
return new FCmpInst(FCmpInst::FCMP_ORD, CI->getArgOperand(0), RHSC);
// fabs(x) == 0 --> x == 0
// fabs(x) != 0 --> x != 0
case FCmpInst::FCMP_OEQ:
case FCmpInst::FCMP_UEQ:
case FCmpInst::FCMP_ONE:
case FCmpInst::FCMP_UNE:
return new FCmpInst(I.getPredicate(), CI->getArgOperand(0), RHSC);
}
}
}

View File

@ -9,3 +9,15 @@ entry:
}
; CHECK-LABEL: define <4 x i1> @test1(
; CHECK: ret <4 x i1> zeroinitializer
declare float @fabsf()
define i1 @test2() {
%call = call float @fabsf()
%cmp = fcmp olt float %call, 0.000000e+00
ret i1 %cmp
}
; CHECK-LABEL: define i1 @test2(
; CHECK: %[[call:.*]] = call float @fabsf()
; CHECK: %[[cmp:.*]] = fcmp olt float %[[call]], 0.000000e+00
; CHECK: ret i1 %[[cmp]]