Index: llvm/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/lib/Analysis/ConstantFolding.cpp +++ llvm/lib/Analysis/ConstantFolding.cpp @@ -1718,39 +1718,36 @@ if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy()) return nullptr; - if (IntrinsicID == Intrinsic::round) { - APFloat V = Op->getValueAPF(); - V.roundToIntegral(APFloat::rmNearestTiesToAway); + // Use internal versions of these intrinsics. + APFloat V = Op->getValueAPF(); + + if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) { + V.roundToIntegral(APFloat::rmNearestTiesToEven); return ConstantFP::get(Ty->getContext(), V); } - if (IntrinsicID == Intrinsic::floor) { - APFloat V = Op->getValueAPF(); - V.roundToIntegral(APFloat::rmTowardNegative); + if (IntrinsicID == Intrinsic::round) { + V.roundToIntegral(APFloat::rmNearestTiesToAway); return ConstantFP::get(Ty->getContext(), V); } if (IntrinsicID == Intrinsic::ceil) { - APFloat V = Op->getValueAPF(); V.roundToIntegral(APFloat::rmTowardPositive); return ConstantFP::get(Ty->getContext(), V); } - if (IntrinsicID == Intrinsic::trunc) { - APFloat V = Op->getValueAPF(); - V.roundToIntegral(APFloat::rmTowardZero); + if (IntrinsicID == Intrinsic::floor) { + V.roundToIntegral(APFloat::rmTowardNegative); return ConstantFP::get(Ty->getContext(), V); } - if (IntrinsicID == Intrinsic::rint) { - APFloat V = Op->getValueAPF(); - V.roundToIntegral(APFloat::rmNearestTiesToEven); + if (IntrinsicID == Intrinsic::trunc) { + V.roundToIntegral(APFloat::rmTowardZero); return ConstantFP::get(Ty->getContext(), V); } - if (IntrinsicID == Intrinsic::nearbyint) { - APFloat V = Op->getValueAPF(); - V.roundToIntegral(APFloat::rmNearestTiesToEven); + if (IntrinsicID == Intrinsic::fabs) { + V.clearSign(); return ConstantFP::get(Ty->getContext(), V); } @@ -1764,31 +1761,29 @@ /// the host native double versions. Float versions are not called /// directly but for all these it is true (float)(f((double)arg)) == /// f(arg). Long double not supported yet. - double V = getValueAsDouble(Op); + double W = getValueAsDouble(Op); switch (IntrinsicID) { default: break; - case Intrinsic::fabs: - return ConstantFoldFP(fabs, V, Ty); case Intrinsic::log: - return ConstantFoldFP(log, V, Ty); + return ConstantFoldFP(log, W, Ty); case Intrinsic::log2: // TODO: What about hosts that lack a C99 library? - return ConstantFoldFP(Log2, V, Ty); + return ConstantFoldFP(Log2, W, Ty); case Intrinsic::log10: // TODO: What about hosts that lack a C99 library? - return ConstantFoldFP(log10, V, Ty); + return ConstantFoldFP(log10, W, Ty); case Intrinsic::exp: - return ConstantFoldFP(exp, V, Ty); + return ConstantFoldFP(exp, W, Ty); case Intrinsic::exp2: // Fold exp2(x) as pow(2, x), in case the host lacks a C99 library. - return ConstantFoldBinaryFP(pow, 2.0, V, Ty); + return ConstantFoldBinaryFP(pow, 2.0, W, Ty); case Intrinsic::sin: - return ConstantFoldFP(sin, V, Ty); + return ConstantFoldFP(sin, W, Ty); case Intrinsic::cos: - return ConstantFoldFP(cos, V, Ty); + return ConstantFoldFP(cos, W, Ty); case Intrinsic::sqrt: - return ConstantFoldFP(sqrt, V, Ty); + return ConstantFoldFP(sqrt, W, Ty); } if (!TLI) @@ -1796,7 +1791,6 @@ LibFunc Func = NotLibFunc; TLI->getLibFunc(Name, Func); - switch (Func) { default: break; @@ -1805,43 +1799,45 @@ case LibFunc_acos_finite: case LibFunc_acosf_finite: if (TLI->has(Func)) - return ConstantFoldFP(acos, V, Ty); + return ConstantFoldFP(acos, W, Ty); break; case LibFunc_asin: case LibFunc_asinf: case LibFunc_asin_finite: case LibFunc_asinf_finite: if (TLI->has(Func)) - return ConstantFoldFP(asin, V, Ty); + return ConstantFoldFP(asin, W, Ty); break; case LibFunc_atan: case LibFunc_atanf: if (TLI->has(Func)) - return ConstantFoldFP(atan, V, Ty); + return ConstantFoldFP(atan, W, Ty); break; case LibFunc_ceil: case LibFunc_ceilf: - if (TLI->has(Func)) - return ConstantFoldFP(ceil, V, Ty); + if (TLI->has(Func)) { + V.roundToIntegral(APFloat::rmTowardPositive); + return ConstantFP::get(Ty->getContext(), V); + } break; case LibFunc_cos: case LibFunc_cosf: if (TLI->has(Func)) - return ConstantFoldFP(cos, V, Ty); + return ConstantFoldFP(cos, W, Ty); break; case LibFunc_cosh: case LibFunc_coshf: case LibFunc_cosh_finite: case LibFunc_coshf_finite: if (TLI->has(Func)) - return ConstantFoldFP(cosh, V, Ty); + return ConstantFoldFP(cosh, W, Ty); break; case LibFunc_exp: case LibFunc_expf: case LibFunc_exp_finite: case LibFunc_expf_finite: if (TLI->has(Func)) - return ConstantFoldFP(exp, V, Ty); + return ConstantFoldFP(exp, W, Ty); break; case LibFunc_exp2: case LibFunc_exp2f: @@ -1849,64 +1845,71 @@ case LibFunc_exp2f_finite: if (TLI->has(Func)) // Fold exp2(x) as pow(2, x), in case the host lacks a C99 library. - return ConstantFoldBinaryFP(pow, 2.0, V, Ty); + return ConstantFoldBinaryFP(pow, 2.0, W, Ty); break; case LibFunc_fabs: case LibFunc_fabsf: - if (TLI->has(Func)) - return ConstantFoldFP(fabs, V, Ty); + if (TLI->has(Func)) { + V.clearSign(); + return ConstantFP::get(Ty->getContext(), V); + } break; case LibFunc_floor: case LibFunc_floorf: - if (TLI->has(Func)) - return ConstantFoldFP(floor, V, Ty); + if (TLI->has(Func)) { + V.roundToIntegral(APFloat::rmTowardNegative); + return ConstantFP::get(Ty->getContext(), V); + } break; case LibFunc_log: case LibFunc_logf: + case LibFunc_log_finite: case LibFunc_logf_finite: - if (V > 0.0 && TLI->has(Func)) - return ConstantFoldFP(log, V, Ty); + if (W > 0.0 && TLI->has(Func)) + return ConstantFoldFP(log, W, Ty); break; case LibFunc_log10: case LibFunc_log10f: case LibFunc_log10_finite: case LibFunc_log10f_finite: - if (V > 0.0 && TLI->has(Func)) + if (W > 0.0 && TLI->has(Func)) // TODO: What about hosts that lack a C99 library? - return ConstantFoldFP(log10, V, Ty); + return ConstantFoldFP(log10, W, Ty); break; case LibFunc_round: case LibFunc_roundf: - if (TLI->has(Func)) - return ConstantFoldFP(round, V, Ty); + if (TLI->has(Func)) { + V.roundToIntegral(APFloat::rmNearestTiesToAway); + return ConstantFP::get(Ty->getContext(), V); + } break; case LibFunc_sin: case LibFunc_sinf: if (TLI->has(Func)) - return ConstantFoldFP(sin, V, Ty); + return ConstantFoldFP(sin, W, Ty); break; case LibFunc_sinh: case LibFunc_sinhf: case LibFunc_sinh_finite: case LibFunc_sinhf_finite: if (TLI->has(Func)) - return ConstantFoldFP(sinh, V, Ty); + return ConstantFoldFP(sinh, W, Ty); break; case LibFunc_sqrt: case LibFunc_sqrtf: - if (V >= 0.0 && TLI->has(Func)) - return ConstantFoldFP(sqrt, V, Ty); + if (W >= 0.0 && TLI->has(Func)) + return ConstantFoldFP(sqrt, W, Ty); break; case LibFunc_tan: case LibFunc_tanf: if (TLI->has(Func)) - return ConstantFoldFP(tan, V, Ty); + return ConstantFoldFP(tan, W, Ty); break; case LibFunc_tanh: case LibFunc_tanhf: if (TLI->has(Func)) - return ConstantFoldFP(tanh, V, Ty); + return ConstantFoldFP(tanh, W, Ty); break; } return nullptr; @@ -2040,9 +2043,11 @@ break; case LibFunc_fmod: case LibFunc_fmodf: - if (TLI->has(Func)) - // TODO: What about hosts that lack a C99 library? - return ConstantFoldBinaryFP(fmod, Op1V, Op2V, Ty); + if (TLI->has(Func)) { + APFloat V = Op1->getValueAPF(); + if (APFloat::opStatus::opOK == V.mod(Op2->getValueAPF())) + return ConstantFP::get(Ty->getContext(), V); + } break; case LibFunc_atan2: case LibFunc_atan2f: