[llvm] r285857 - DCE math library calls with a constant operand.
NAKAMURA Takumi via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 3 12:03:05 PDT 2016
nvm, I posted wrong log. This is the right one.
define void @T() {
entry:
%log1 = call double @log(double 0.000000e+00)
%log2 = call double @log(double -1.000000e+00)
%exp2 = call double @exp(double 1.000000e+03)
%cos2 = call double @cos(double 0x7FF0000000000000)
%fmod2 = call double @fmod(double 0x7FF0000000000000, double 1.000000e+00)
ret void
}
I am investigating.
On Fri, Nov 4, 2016 at 3:45 AM NAKAMURA Takumi <geek4civic at gmail.com> wrote:
> FYI, it emits %pow1.
>
> %cos2 = call double @cos(double 0x7FF0000000000000)
> %pow1 = call double @pow(double 0x7FF0000000000000, double 1.000000e+00)
> %pow2 = call double @pow(double 0.000000e+00, double -1.000000e+00)
>
>
> On Thu, Nov 3, 2016 at 2:29 PM Yaron Keren via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
> Hi Eli,
>
> The test is failing here
>
>
> http://bb.pgr.jp/builders/ninja-clang-x64-mingw64-RA/builds/13954/steps/test-llvm/logs/LLVM%20%3A%3A%20Transforms__DCE__calls-errno.ll
>
> Yaron
>
>
> 2016-11-02 22:48 GMT+02:00 Eli Friedman via llvm-commits <
> llvm-commits at lists.llvm.org>:
>
> Author: efriedma
> Date: Wed Nov 2 15:48:11 2016
> New Revision: 285857
>
> URL: http://llvm.org/viewvc/llvm-project?rev=285857&view=rev
> Log:
> DCE math library calls with a constant operand.
>
> On platforms which use -fmath-errno, math libcalls without any uses
> require some extra checks to figure out if they are actually dead.
>
> Fixes https://llvm.org/bugs/show_bug.cgi?id=30464 .
>
> Differential Revision: https://reviews.llvm.org/D25970
>
>
> Added:
> llvm/trunk/test/Transforms/DCE/calls-errno.ll
> Modified:
> llvm/trunk/include/llvm/Analysis/ConstantFolding.h
> llvm/trunk/lib/Analysis/ConstantFolding.cpp
> llvm/trunk/lib/Transforms/Utils/Local.cpp
>
> Modified: llvm/trunk/include/llvm/Analysis/ConstantFolding.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ConstantFolding.h?rev=285857&r1=285856&r2=285857&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/ConstantFolding.h (original)
> +++ llvm/trunk/include/llvm/Analysis/ConstantFolding.h Wed Nov 2 15:48:11
> 2016
> @@ -23,6 +23,7 @@
> namespace llvm {
> class APInt;
> template <typename T> class ArrayRef;
> +class CallSite;
> class Constant;
> class ConstantExpr;
> class ConstantVector;
> @@ -125,6 +126,10 @@ bool canConstantFoldCallTo(const Functio
> /// with the specified arguments, returning null if unsuccessful.
> Constant *ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
> const TargetLibraryInfo *TLI = nullptr);
> +
> +/// \brief Check whether the given call has no side-effects.
> +/// Specifically checks for math routimes which sometimes set errno.
> +bool isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI);
> }
>
> #endif
>
> Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=285857&r1=285856&r2=285857&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
> +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed Nov 2 15:48:11 2016
> @@ -1967,3 +1967,152 @@ llvm::ConstantFoldCall(Function *F, Arra
>
> return ConstantFoldScalarCall(Name, F->getIntrinsicID(), Ty, Operands,
> TLI);
> }
> +
> +bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
> + // FIXME: Refactor this code; this duplicates logic in
> LibCallsShrinkWrap
> + // (and to some extent ConstantFoldScalarCall).
> + Function *F = CS.getCalledFunction();
> + if (!F)
> + return false;
> +
> + LibFunc::Func Func;
> + if (!TLI || !TLI->getLibFunc(*F, Func))
> + return false;
> +
> + if (CS.getNumArgOperands() == 1) {
> + if (ConstantFP *OpC = dyn_cast<ConstantFP>(CS.getArgOperand(0))) {
> + const APFloat &Op = OpC->getValueAPF();
> + switch (Func) {
> + case LibFunc::logl:
> + case LibFunc::log:
> + case LibFunc::logf:
> + case LibFunc::log2l:
> + case LibFunc::log2:
> + case LibFunc::log2f:
> + case LibFunc::log10l:
> + case LibFunc::log10:
> + case LibFunc::log10f:
> + return Op.isNaN() || (!Op.isZero() && !Op.isNegative());
> +
> + case LibFunc::expl:
> + case LibFunc::exp:
> + case LibFunc::expf:
> + // FIXME: These boundaries are slightly conservative.
> + if (OpC->getType()->isDoubleTy())
> + return Op.compare(APFloat(-745.0)) != APFloat::cmpLessThan &&
> + Op.compare(APFloat(709.0)) != APFloat::cmpGreaterThan;
> + if (OpC->getType()->isFloatTy())
> + return Op.compare(APFloat(-103.0f)) != APFloat::cmpLessThan &&
> + Op.compare(APFloat(88.0f)) != APFloat::cmpGreaterThan;
> + break;
> +
> + case LibFunc::exp2l:
> + case LibFunc::exp2:
> + case LibFunc::exp2f:
> + // FIXME: These boundaries are slightly conservative.
> + if (OpC->getType()->isDoubleTy())
> + return Op.compare(APFloat(-1074.0)) != APFloat::cmpLessThan &&
> + Op.compare(APFloat(1023.0)) != APFloat::cmpGreaterThan;
> + if (OpC->getType()->isFloatTy())
> + return Op.compare(APFloat(-149.0f)) != APFloat::cmpLessThan &&
> + Op.compare(APFloat(127.0f)) != APFloat::cmpGreaterThan;
> + break;
> +
> + case LibFunc::sinl:
> + case LibFunc::sin:
> + case LibFunc::sinf:
> + case LibFunc::cosl:
> + case LibFunc::cos:
> + case LibFunc::cosf:
> + return !Op.isInfinity();
> +
> + case LibFunc::tanl:
> + case LibFunc::tan:
> + case LibFunc::tanf: {
> + // FIXME: Stop using the host math library.
> + // FIXME: The computation isn't done in the right precision.
> + Type *Ty = OpC->getType();
> + if (Ty->isDoubleTy() || Ty->isFloatTy() || Ty->isHalfTy()) {
> + double OpV = getValueAsDouble(OpC);
> + return ConstantFoldFP(tan, OpV, Ty) != nullptr;
> + }
> + break;
> + }
> +
> + case LibFunc::asinl:
> + case LibFunc::asin:
> + case LibFunc::asinf:
> + case LibFunc::acosl:
> + case LibFunc::acos:
> + case LibFunc::acosf:
> + return Op.compare(APFloat(Op.getSemantics(), "-1")) !=
> + APFloat::cmpLessThan &&
> + Op.compare(APFloat(Op.getSemantics(), "1")) !=
> + APFloat::cmpGreaterThan;
> +
> + case LibFunc::sinh:
> + case LibFunc::cosh:
> + case LibFunc::sinhf:
> + case LibFunc::coshf:
> + case LibFunc::sinhl:
> + case LibFunc::coshl:
> + // FIXME: These boundaries are slightly conservative.
> + if (OpC->getType()->isDoubleTy())
> + return Op.compare(APFloat(-710.0)) != APFloat::cmpLessThan &&
> + Op.compare(APFloat(710.0)) != APFloat::cmpGreaterThan;
> + if (OpC->getType()->isFloatTy())
> + return Op.compare(APFloat(-89.0f)) != APFloat::cmpLessThan &&
> + Op.compare(APFloat(89.0f)) != APFloat::cmpGreaterThan;
> + break;
> +
> + case LibFunc::sqrtl:
> + case LibFunc::sqrt:
> + case LibFunc::sqrtf:
> + return Op.isNaN() || Op.isZero() || !Op.isNegative();
> +
> + // FIXME: Add more functions: sqrt_finite, atanh, expm1, log1p,
> + // maybe others?
> + default:
> + break;
> + }
> + }
> + }
> +
> + if (CS.getNumArgOperands() == 2) {
> + ConstantFP *Op0C = dyn_cast<ConstantFP>(CS.getArgOperand(0));
> + ConstantFP *Op1C = dyn_cast<ConstantFP>(CS.getArgOperand(1));
> + if (Op0C && Op1C) {
> + const APFloat &Op0 = Op0C->getValueAPF();
> + const APFloat &Op1 = Op1C->getValueAPF();
> +
> + switch (Func) {
> + case LibFunc::powl:
> + case LibFunc::pow:
> + case LibFunc::powf: {
> + // FIXME: Stop using the host math library.
> + // FIXME: The computation isn't done in the right precision.
> + Type *Ty = Op0C->getType();
> + if (Ty->isDoubleTy() || Ty->isFloatTy() || Ty->isHalfTy()) {
> + if (Ty == Op1C->getType()) {
> + double Op0V = getValueAsDouble(Op0C);
> + double Op1V = getValueAsDouble(Op1C);
> + return ConstantFoldBinaryFP(pow, Op0V, Op1V, Ty) != nullptr;
> + }
> + }
> + break;
> + }
> +
> + case LibFunc::fmodl:
> + case LibFunc::fmod:
> + case LibFunc::fmodf:
> + return Op0.isNaN() || Op1.isNaN() ||
> + (!Op0.isInfinity() && !Op1.isZero());
> +
> + default:
> + break;
> + }
> + }
> + }
> +
> + return false;
> +}
>
> Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=285857&r1=285856&r2=285857&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Wed Nov 2 15:48:11 2016
> @@ -340,6 +340,10 @@ bool llvm::isInstructionTriviallyDead(In
> if (Constant *C = dyn_cast<Constant>(CI->getArgOperand(0)))
> return C->isNullValue() || isa<UndefValue>(C);
>
> + if (CallSite CS = CallSite(I))
> + if (isMathLibCallNoop(CS, TLI))
> + return true;
> +
> return false;
> }
>
>
> Added: llvm/trunk/test/Transforms/DCE/calls-errno.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DCE/calls-errno.ll?rev=285857&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/DCE/calls-errno.ll (added)
> +++ llvm/trunk/test/Transforms/DCE/calls-errno.ll Wed Nov 2 15:48:11 2016
> @@ -0,0 +1,91 @@
> +; RUN: opt < %s -dce -S | FileCheck %s
> +
> +declare double @acos(double) nounwind
> +declare double @asin(double) nounwind
> +declare double @atan(double) nounwind
> +declare double @atan2(double, double) nounwind
> +declare double @ceil(double) nounwind
> +declare double @cos(double) nounwind
> +declare double @cosh(double) nounwind
> +declare double @exp(double) nounwind
> +declare double @exp2(double) nounwind
> +declare double @fabs(double) nounwind
> +declare double @floor(double) nounwind
> +declare double @fmod(double, double) nounwind
> +declare double @log(double) nounwind
> +declare double @log10(double) nounwind
> +declare double @pow(double, double) nounwind
> +declare double @sin(double) nounwind
> +declare double @sinh(double) nounwind
> +declare double @sqrt(double) nounwind
> +declare double @tan(double) nounwind
> +declare double @tanh(double) nounwind
> +
> +declare float @acosf(float) nounwind
> +declare float @asinf(float) nounwind
> +declare float @atanf(float) nounwind
> +declare float @atan2f(float, float) nounwind
> +declare float @ceilf(float) nounwind
> +declare float @cosf(float) nounwind
> +declare float @coshf(float) nounwind
> +declare float @expf(float) nounwind
> +declare float @exp2f(float) nounwind
> +declare float @fabsf(float) nounwind
> +declare float @floorf(float) nounwind
> +declare float @fmodf(float, float) nounwind
> +declare float @logf(float) nounwind
> +declare float @log10f(float) nounwind
> +declare float @powf(float, float) nounwind
> +declare float @sinf(float) nounwind
> +declare float @sinhf(float) nounwind
> +declare float @sqrtf(float) nounwind
> +declare float @tanf(float) nounwind
> +declare float @tanhf(float) nounwind
> +
> +define void @T() {
> +entry:
> +; CHECK-LABEL: @T(
> +; CHECK-NEXT: entry:
> +
> +; log(0) produces a pole error
> +; CHECK-NEXT: %log1 = call double @log(double 0.000000e+00)
> + %log1 = call double @log(double 0.000000e+00)
> +
> +; log(-1) produces a domain error
> +; CHECK-NEXT: %log2 = call double @log(double -1.000000e+00)
> + %log2 = call double @log(double -1.000000e+00)
> +
> +; log(1) is 0
> + %log3 = call double @log(double 1.000000e+00)
> +
> +; exp(100) is roughly 2.6e+43
> + %exp1 = call double @exp(double 1.000000e+02)
> +
> +; exp(1000) is a range error
> +; CHECK-NEXT: %exp2 = call double @exp(double 1.000000e+03)
> + %exp2 = call double @exp(double 1.000000e+03)
> +
> +; cos(0) is 1
> + %cos1 = call double @cos(double 0.000000e+00)
> +
> +; cos(inf) is a domain error
> +; CHECK-NEXT: %cos2 = call double @cos(double 0x7FF0000000000000)
> + %cos2 = call double @cos(double 0x7FF0000000000000)
> +
> +; pow(0, 1) is 0
> + %pow1 = call double @pow(double 0x7FF0000000000000, double 1.000000e+00)
> +
> +; pow(0, -1) is a pole error
> +; CHECK-NEXT: %pow2 = call double @pow(double 0.000000e+00, double
> -1.000000e+00)
> + %pow2 = call double @pow(double 0.000000e+00, double -1.000000e+00)
> +
> +; fmod(inf, nan) is nan
> + %fmod1 = call double @fmod(double 0x7FF0000000000000, double
> 0x7FF0000000000001)
> +
> +; fmod(inf, 1) is a domain error
> +; CHECK-NEXT: %fmod2 = call double @fmod(double 0x7FF0000000000000,
> double 1.000000e+00)
> + %fmod2 = call double @fmod(double 0x7FF0000000000000, double
> 1.000000e+00)
> +
> +; CHECK-NEXT: ret void
> + ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161103/996f1093/attachment.html>
More information about the llvm-commits
mailing list