diff options
Diffstat (limited to 'flang/lib/Evaluate/fold-real.cpp')
| -rw-r--r-- | flang/lib/Evaluate/fold-real.cpp | 25 |
1 files changed, 10 insertions, 15 deletions
diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp index 225e3402fd1a..9c591e2ef36e 100644 --- a/flang/lib/Evaluate/fold-real.cpp +++ b/flang/lib/Evaluate/fold-real.cpp @@ -77,13 +77,8 @@ public: auto scaled{item.Divide(scale).value}; auto square{scaled.Multiply(scaled).value}; if constexpr (useKahanSummation) { - auto next{square.Subtract(correction_, rounding_)}; - overflow_ |= next.flags.test(RealFlag::Overflow); - auto sum{element.Add(next.value, rounding_)}; + auto sum{element.KahanSummation(square, correction_, rounding_)}; overflow_ |= sum.flags.test(RealFlag::Overflow); - correction_ = sum.value.Subtract(element, rounding_) - .value.Subtract(next.value, rounding_) - .value; element = sum.value; } else { auto sum{element.Add(square, rounding_)}; @@ -387,13 +382,7 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction( ScalarFunc<T, T, TBY>( [&](const Scalar<T> &x, const Scalar<TBY> &y) -> Scalar<T> { ValueWithRealFlags<Scalar<T>> result{ - x. -// MSVC chokes on the keyword "template" here in a call to a -// member function template. -#ifndef _MSC_VER - template -#endif - SCALE<Scalar<TBY>>(y)}; + x.template SCALE<Scalar<TBY>>(y)}; if (result.flags.test(RealFlag::Overflow)) { context.Warn(common::UsageWarning::FoldingException, "SCALE/IEEE_SCALB intrinsic folding overflow"_warn_en_US); @@ -425,8 +414,14 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction( [](const Scalar<T> &x) -> Scalar<T> { return x.SPACING(); })); } else if (name == "sqrt") { return FoldElementalIntrinsic<T, T>(context, std::move(funcRef), - ScalarFunc<T, T>( - [](const Scalar<T> &x) -> Scalar<T> { return x.SQRT().value; })); + ScalarFunc<T, T>([&context](const Scalar<T> &x) -> Scalar<T> { + ValueWithRealFlags<Scalar<T>> result{x.SQRT()}; + if (result.flags.test(RealFlag::InvalidArgument)) { + context.Warn(common::UsageWarning::FoldingValueChecks, + "Invalid argument to SQRT()"_warn_en_US); + } + return result.value; + })); } else if (name == "sum") { return FoldSum<T>(context, std::move(funcRef)); } else if (name == "tiny") { |
