[llvm] r285857 - DCE math library calls with a constant operand.

Friedman, Eli via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 3 09:59:58 PDT 2016


On 11/2/2016 10:28 PM, Yaron Keren 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
>

It's breaking just on Windows? Probably something is going wrong using 
the host math library.  I won't have time to look at this until next 
week; please XFAIL or revert.

-Eli

> Yaron
>
>
> 2016-11-02 22:48 GMT+02:00 Eli Friedman via llvm-commits 
> <llvm-commits at lists.llvm.org <mailto: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
>     <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
>     <https://llvm.org/bugs/show_bug.cgi?id=30464> .
>
>     Differential Revision: https://reviews.llvm.org/D25970
>     <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
>     <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
>     <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
>     <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
>     <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 <mailto:llvm-commits at lists.llvm.org>
>     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>     <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits>
>
>


-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161103/576fe249/attachment.html>


More information about the llvm-commits mailing list