[llvm] r225465 - Fix fcmp + fabs instcombines when using the intrinsic
Matt Arsenault
Matthew.Arsenault at amd.com
Thu Jan 8 12:09:34 PST 2015
Author: arsenm
Date: Thu Jan 8 14:09:34 2015
New Revision: 225465
URL: http://llvm.org/viewvc/llvm-project?rev=225465&view=rev
Log:
Fix fcmp + fabs instcombines when using the intrinsic
This was only handling the libcall. This is another example
of why only the intrinsic should ever be used when it exists.
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/trunk/test/Transforms/InstCombine/fcmp.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=225465&r1=225464&r2=225465&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Jan 8 14:09:34 2015
@@ -3960,40 +3960,42 @@ Instruction *InstCombiner::visitFCmpInst
}
break;
case Instruction::Call: {
+ if (!RHSC->isNullValue())
+ break;
+
CallInst *CI = cast<CallInst>(LHSI);
- LibFunc::Func Func;
+ const Function *F = CI->getCalledFunction();
+ if (!F)
+ break;
+
// Various optimization for fabs compared with zero.
- if (RHSC->isNullValue() && CI->getCalledFunction() &&
- TLI->getLibFunc(CI->getCalledFunction()->getName(), Func) &&
- TLI->has(Func)) {
- if (Func == LibFunc::fabs || Func == LibFunc::fabsf ||
- Func == LibFunc::fabsl) {
- switch (I.getPredicate()) {
- default: break;
+ 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:
- return ReplaceInstUsesWith(I, Builder->getFalse());
+ case FCmpInst::FCMP_OLT:
+ return ReplaceInstUsesWith(I, Builder->getFalse());
// fabs(x) > 0 --> x != 0
- case FCmpInst::FCMP_OGT:
- return new FCmpInst(FCmpInst::FCMP_ONE, CI->getArgOperand(0),
- RHSC);
+ 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);
+ 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);
+ 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);
- }
+ 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);
}
}
}
Modified: llvm/trunk/test/Transforms/InstCombine/fcmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fcmp.ll?rev=225465&r1=225464&r2=225465&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fcmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fcmp.ll Thu Jan 8 14:09:34 2015
@@ -1,5 +1,7 @@
; RUN: opt -S -instcombine < %s | FileCheck %s
+declare double @llvm.fabs.f64(double) nounwind readnone
+
define i1 @test1(float %x, float %y) nounwind {
%ext1 = fpext float %x to double
%ext2 = fpext float %y to double
@@ -81,6 +83,16 @@ define i32 @test9(double %a) nounwind {
; CHECK: ret i32 0
}
+define i32 @test9_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp olt double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test9_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: ret i32 0
+}
+
define i32 @test10(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp ole double %call, 0.000000e+00
@@ -91,6 +103,16 @@ define i32 @test10(double %a) nounwind {
; CHECK: fcmp oeq double %a, 0.000000e+00
}
+define i32 @test10_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp ole double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test10_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp oeq double %a, 0.000000e+00
+}
+
define i32 @test11(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp ogt double %call, 0.000000e+00
@@ -101,6 +123,16 @@ define i32 @test11(double %a) nounwind {
; CHECK: fcmp one double %a, 0.000000e+00
}
+define i32 @test11_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp ogt double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test11_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp one double %a, 0.000000e+00
+}
+
define i32 @test12(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp oge double %call, 0.000000e+00
@@ -111,6 +143,16 @@ define i32 @test12(double %a) nounwind {
; CHECK: fcmp ord double %a, 0.000000e+00
}
+define i32 @test12_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp oge double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test12_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp ord double %a, 0.000000e+00
+}
+
define i32 @test13(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp une double %call, 0.000000e+00
@@ -121,6 +163,16 @@ define i32 @test13(double %a) nounwind {
; CHECK: fcmp une double %a, 0.000000e+00
}
+define i32 @test13_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp une double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test13_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp une double %a, 0.000000e+00
+}
+
define i32 @test14(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp oeq double %call, 0.000000e+00
@@ -131,6 +183,16 @@ define i32 @test14(double %a) nounwind {
; CHECK: fcmp oeq double %a, 0.000000e+00
}
+define i32 @test14_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp oeq double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test14_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp oeq double %a, 0.000000e+00
+}
+
define i32 @test15(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp one double %call, 0.000000e+00
@@ -141,6 +203,16 @@ define i32 @test15(double %a) nounwind {
; CHECK: fcmp one double %a, 0.000000e+00
}
+define i32 @test15_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp one double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test15_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp one double %a, 0.000000e+00
+}
+
define i32 @test16(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp ueq double %call, 0.000000e+00
@@ -150,6 +222,16 @@ define i32 @test16(double %a) nounwind {
; CHECK-NOT: fabs
; CHECK: fcmp ueq double %a, 0.000000e+00
}
+
+define i32 @test16_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp ueq double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test16_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp ueq double %a, 0.000000e+00
+}
; Don't crash.
define i32 @test17(double %a, double (double)* %p) nounwind {
More information about the llvm-commits
mailing list