diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index c97b67eff24..013548ae4d2 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -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(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); } } } diff --git a/test/Transforms/InstCombine/pr27332.ll b/test/Transforms/InstCombine/pr27332.ll index 543ffbe1fa7..87e440eed1c 100644 --- a/test/Transforms/InstCombine/pr27332.ll +++ b/test/Transforms/InstCombine/pr27332.ll @@ -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]]