diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:01:22 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:01:22 +0000 | 
| commit | 71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch) | |
| tree | 5343938942df402b49ec7300a1c25a2d4ccd5821 /lib/Analysis/ConstantFolding.cpp | |
| parent | 31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff) | |
Notes
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
| -rw-r--r-- | lib/Analysis/ConstantFolding.cpp | 204 | 
1 files changed, 97 insertions, 107 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 73867279abe4..14176dac2104 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -1058,8 +1058,8 @@ ConstantFoldConstantImpl(const Constant *C, const DataLayout &DL,        if (It == FoldedOps.end()) {          if (auto *FoldedC =                  ConstantFoldConstantImpl(NewC, DL, TLI, FoldedOps)) { -          NewC = FoldedC;            FoldedOps.insert({NewC, FoldedC}); +          NewC = FoldedC;          } else {            FoldedOps.insert({NewC, NewC});          } @@ -1401,7 +1401,7 @@ bool llvm::canConstantFoldCallTo(const Function *F) {      return true;    default:      return false; -  case 0: break; +  case Intrinsic::not_intrinsic: break;    }    if (!F->hasName()) @@ -1518,9 +1518,9 @@ Constant *ConstantFoldSSEConvertToInt(const APFloat &Val, bool roundTowardZero,    bool isExact = false;    APFloat::roundingMode mode = roundTowardZero? APFloat::rmTowardZero                                                : APFloat::rmNearestTiesToEven; -  APFloat::opStatus status = Val.convertToInteger(&UIntVal, ResultWidth, -                                                  /*isSigned=*/true, mode, -                                                  &isExact); +  APFloat::opStatus status = +      Val.convertToInteger(makeMutableArrayRef(UIntVal), ResultWidth, +                           /*isSigned=*/true, mode, &isExact);    if (status != APFloat::opOK &&        (!roundTowardZero || status != APFloat::opInexact))      return nullptr; @@ -1630,6 +1630,8 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,            return ConstantFoldFP(sin, V, Ty);          case Intrinsic::cos:            return ConstantFoldFP(cos, V, Ty); +        case Intrinsic::sqrt: +          return ConstantFoldFP(sqrt, V, Ty);        }        if (!TLI) @@ -1637,87 +1639,74 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,        switch (Name[0]) {        case 'a': -        if ((Name == "acos" && TLI->has(LibFunc::acos)) || -            (Name == "acosf" && TLI->has(LibFunc::acosf))) +        if ((Name == "acos" && TLI->has(LibFunc_acos)) || +            (Name == "acosf" && TLI->has(LibFunc_acosf)))            return ConstantFoldFP(acos, V, Ty); -        else if ((Name == "asin" && TLI->has(LibFunc::asin)) || -                 (Name == "asinf" && TLI->has(LibFunc::asinf))) +        else if ((Name == "asin" && TLI->has(LibFunc_asin)) || +                 (Name == "asinf" && TLI->has(LibFunc_asinf)))            return ConstantFoldFP(asin, V, Ty); -        else if ((Name == "atan" && TLI->has(LibFunc::atan)) || -                 (Name == "atanf" && TLI->has(LibFunc::atanf))) +        else if ((Name == "atan" && TLI->has(LibFunc_atan)) || +                 (Name == "atanf" && TLI->has(LibFunc_atanf)))            return ConstantFoldFP(atan, V, Ty);          break;        case 'c': -        if ((Name == "ceil" && TLI->has(LibFunc::ceil)) || -            (Name == "ceilf" && TLI->has(LibFunc::ceilf))) +        if ((Name == "ceil" && TLI->has(LibFunc_ceil)) || +            (Name == "ceilf" && TLI->has(LibFunc_ceilf)))            return ConstantFoldFP(ceil, V, Ty); -        else if ((Name == "cos" && TLI->has(LibFunc::cos)) || -                 (Name == "cosf" && TLI->has(LibFunc::cosf))) +        else if ((Name == "cos" && TLI->has(LibFunc_cos)) || +                 (Name == "cosf" && TLI->has(LibFunc_cosf)))            return ConstantFoldFP(cos, V, Ty); -        else if ((Name == "cosh" && TLI->has(LibFunc::cosh)) || -                 (Name == "coshf" && TLI->has(LibFunc::coshf))) +        else if ((Name == "cosh" && TLI->has(LibFunc_cosh)) || +                 (Name == "coshf" && TLI->has(LibFunc_coshf)))            return ConstantFoldFP(cosh, V, Ty);          break;        case 'e': -        if ((Name == "exp" && TLI->has(LibFunc::exp)) || -            (Name == "expf" && TLI->has(LibFunc::expf))) +        if ((Name == "exp" && TLI->has(LibFunc_exp)) || +            (Name == "expf" && TLI->has(LibFunc_expf)))            return ConstantFoldFP(exp, V, Ty); -        if ((Name == "exp2" && TLI->has(LibFunc::exp2)) || -            (Name == "exp2f" && TLI->has(LibFunc::exp2f))) +        if ((Name == "exp2" && TLI->has(LibFunc_exp2)) || +            (Name == "exp2f" && TLI->has(LibFunc_exp2f)))            // Constant fold exp2(x) as pow(2,x) in case the host doesn't have a            // C99 library.            return ConstantFoldBinaryFP(pow, 2.0, V, Ty);          break;        case 'f': -        if ((Name == "fabs" && TLI->has(LibFunc::fabs)) || -            (Name == "fabsf" && TLI->has(LibFunc::fabsf))) +        if ((Name == "fabs" && TLI->has(LibFunc_fabs)) || +            (Name == "fabsf" && TLI->has(LibFunc_fabsf)))            return ConstantFoldFP(fabs, V, Ty); -        else if ((Name == "floor" && TLI->has(LibFunc::floor)) || -                 (Name == "floorf" && TLI->has(LibFunc::floorf))) +        else if ((Name == "floor" && TLI->has(LibFunc_floor)) || +                 (Name == "floorf" && TLI->has(LibFunc_floorf)))            return ConstantFoldFP(floor, V, Ty);          break;        case 'l': -        if ((Name == "log" && V > 0 && TLI->has(LibFunc::log)) || -            (Name == "logf" && V > 0 && TLI->has(LibFunc::logf))) +        if ((Name == "log" && V > 0 && TLI->has(LibFunc_log)) || +            (Name == "logf" && V > 0 && TLI->has(LibFunc_logf)))            return ConstantFoldFP(log, V, Ty); -        else if ((Name == "log10" && V > 0 && TLI->has(LibFunc::log10)) || -                 (Name == "log10f" && V > 0 && TLI->has(LibFunc::log10f))) +        else if ((Name == "log10" && V > 0 && TLI->has(LibFunc_log10)) || +                 (Name == "log10f" && V > 0 && TLI->has(LibFunc_log10f)))            return ConstantFoldFP(log10, V, Ty); -        else if (IntrinsicID == Intrinsic::sqrt && -                 (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())) { -          if (V >= -0.0) -            return ConstantFoldFP(sqrt, V, Ty); -          else { -            // Unlike the sqrt definitions in C/C++, POSIX, and IEEE-754 - which -            // all guarantee or favor returning NaN - the square root of a -            // negative number is not defined for the LLVM sqrt intrinsic. -            // This is because the intrinsic should only be emitted in place of -            // libm's sqrt function when using "no-nans-fp-math". -            return UndefValue::get(Ty); -          } -        }          break;        case 'r': -        if ((Name == "round" && TLI->has(LibFunc::round)) || -            (Name == "roundf" && TLI->has(LibFunc::roundf))) +        if ((Name == "round" && TLI->has(LibFunc_round)) || +            (Name == "roundf" && TLI->has(LibFunc_roundf)))            return ConstantFoldFP(round, V, Ty);        case 's': -        if ((Name == "sin" && TLI->has(LibFunc::sin)) || -            (Name == "sinf" && TLI->has(LibFunc::sinf))) +        if ((Name == "sin" && TLI->has(LibFunc_sin)) || +            (Name == "sinf" && TLI->has(LibFunc_sinf)))            return ConstantFoldFP(sin, V, Ty); -        else if ((Name == "sinh" && TLI->has(LibFunc::sinh)) || -                 (Name == "sinhf" && TLI->has(LibFunc::sinhf))) +        else if ((Name == "sinh" && TLI->has(LibFunc_sinh)) || +                 (Name == "sinhf" && TLI->has(LibFunc_sinhf)))            return ConstantFoldFP(sinh, V, Ty); -        else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc::sqrt)) || -                 (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc::sqrtf))) +        else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc_sqrt)) || +                 (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc_sqrtf)))            return ConstantFoldFP(sqrt, V, Ty);          break;        case 't': -        if ((Name == "tan" && TLI->has(LibFunc::tan)) || -            (Name == "tanf" && TLI->has(LibFunc::tanf))) +        if ((Name == "tan" && TLI->has(LibFunc_tan)) || +            (Name == "tanf" && TLI->has(LibFunc_tanf)))            return ConstantFoldFP(tan, V, Ty); -        else if ((Name == "tanh" && TLI->has(LibFunc::tanh)) || -                 (Name == "tanhf" && TLI->has(LibFunc::tanhf))) +        else if ((Name == "tanh" && TLI->has(LibFunc_tanh)) || +                 (Name == "tanhf" && TLI->has(LibFunc_tanhf)))            return ConstantFoldFP(tanh, V, Ty);          break;        default: @@ -1779,7 +1768,8 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,      }      if (isa<UndefValue>(Operands[0])) { -      if (IntrinsicID == Intrinsic::bswap) +      if (IntrinsicID == Intrinsic::bswap || +          IntrinsicID == Intrinsic::bitreverse)          return Operands[0];        return nullptr;      } @@ -1822,14 +1812,14 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,          if (!TLI)            return nullptr; -        if ((Name == "pow" && TLI->has(LibFunc::pow)) || -            (Name == "powf" && TLI->has(LibFunc::powf))) +        if ((Name == "pow" && TLI->has(LibFunc_pow)) || +            (Name == "powf" && TLI->has(LibFunc_powf)))            return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty); -        if ((Name == "fmod" && TLI->has(LibFunc::fmod)) || -            (Name == "fmodf" && TLI->has(LibFunc::fmodf))) +        if ((Name == "fmod" && TLI->has(LibFunc_fmod)) || +            (Name == "fmodf" && TLI->has(LibFunc_fmodf)))            return ConstantFoldBinaryFP(fmod, Op1V, Op2V, Ty); -        if ((Name == "atan2" && TLI->has(LibFunc::atan2)) || -            (Name == "atan2f" && TLI->has(LibFunc::atan2f))) +        if ((Name == "atan2" && TLI->has(LibFunc_atan2)) || +            (Name == "atan2f" && TLI->has(LibFunc_atan2f)))            return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);        } else if (auto *Op2C = dyn_cast<ConstantInt>(Operands[1])) {          if (IntrinsicID == Intrinsic::powi && Ty->isHalfTy()) @@ -2022,7 +2012,7 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {    if (!F)      return false; -  LibFunc::Func Func; +  LibFunc Func;    if (!TLI || !TLI->getLibFunc(*F, Func))      return false; @@ -2030,20 +2020,20 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {      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: +      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: +      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 && @@ -2053,9 +2043,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {                   Op.compare(APFloat(88.0f)) != APFloat::cmpGreaterThan;          break; -      case LibFunc::exp2l: -      case LibFunc::exp2: -      case LibFunc::exp2f: +      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 && @@ -2065,17 +2055,17 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {                   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: +      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: { +      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(); @@ -2086,23 +2076,23 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {          break;        } -      case LibFunc::asinl: -      case LibFunc::asin: -      case LibFunc::asinf: -      case LibFunc::acosl: -      case LibFunc::acos: -      case LibFunc::acosf: +      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: +      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 && @@ -2112,9 +2102,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {                   Op.compare(APFloat(89.0f)) != APFloat::cmpGreaterThan;          break; -      case LibFunc::sqrtl: -      case LibFunc::sqrt: -      case LibFunc::sqrtf: +      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, @@ -2133,9 +2123,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {        const APFloat &Op1 = Op1C->getValueAPF();        switch (Func) { -      case LibFunc::powl: -      case LibFunc::pow: -      case LibFunc::powf: { +      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(); @@ -2149,9 +2139,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {          break;        } -      case LibFunc::fmodl: -      case LibFunc::fmod: -      case LibFunc::fmodf: +      case LibFunc_fmodl: +      case LibFunc_fmod: +      case LibFunc_fmodf:          return Op0.isNaN() || Op1.isNaN() ||                 (!Op0.isInfinity() && !Op1.isZero());  | 
