aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Evaluate/fold-real.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Evaluate/fold-real.cpp')
-rw-r--r--flang/lib/Evaluate/fold-real.cpp25
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") {