diff --git a/flang/lib/Evaluate/fold-matmul.h b/flang/lib/Evaluate/fold-matmul.h index be9c547d45286..c3d65a9040909 100644 --- a/flang/lib/Evaluate/fold-matmul.h +++ b/flang/lib/Evaluate/fold-matmul.h @@ -61,7 +61,7 @@ static Expr FoldMatmul(FoldingContext &context, FunctionRef &&funcRef) { auto product{aElt.Multiply(bElt)}; overflow |= product.flags.test(RealFlag::Overflow); if constexpr (useKahanSummation) { - auto next{correction.Add(product.value, rounding)}; + auto next{product.value.Subtract(correction, rounding)}; overflow |= next.flags.test(RealFlag::Overflow); auto added{sum.Add(next.value, rounding)}; overflow |= added.flags.test(RealFlag::Overflow); diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp index 0b79a417942a4..6fb5249c8a5e2 100644 --- a/flang/lib/Evaluate/fold-real.cpp +++ b/flang/lib/Evaluate/fold-real.cpp @@ -78,7 +78,7 @@ template class Norm2Accumulator { auto scaled{item.Divide(scale).value}; auto square{scaled.Multiply(scaled).value}; if constexpr (useKahanSummation) { - auto next{square.Add(correction_, rounding_)}; + auto next{square.Subtract(correction_, rounding_)}; overflow_ |= next.flags.test(RealFlag::Overflow); auto sum{element.Add(next.value, rounding_)}; overflow_ |= sum.flags.test(RealFlag::Overflow); diff --git a/flang/lib/Evaluate/fold-reduction.h b/flang/lib/Evaluate/fold-reduction.h index 8ca0794ab0fc7..b1b81d8740d3f 100644 --- a/flang/lib/Evaluate/fold-reduction.h +++ b/flang/lib/Evaluate/fold-reduction.h @@ -47,7 +47,7 @@ static Expr FoldDotProduct( const auto &rounding{context.targetCharacteristics().roundingMode()}; for (const Element &x : cProducts.values()) { if constexpr (useKahanSummation) { - auto next{correction.Add(x, rounding)}; + auto next{x.Subtract(correction, rounding)}; overflow |= next.flags.test(RealFlag::Overflow); auto added{sum.Add(next.value, rounding)}; overflow |= added.flags.test(RealFlag::Overflow); @@ -90,7 +90,7 @@ static Expr FoldDotProduct( const auto &rounding{context.targetCharacteristics().roundingMode()}; for (const Element &x : cProducts.values()) { if constexpr (useKahanSummation) { - auto next{correction.Add(x, rounding)}; + auto next{x.Subtract(correction, rounding)}; overflow |= next.flags.test(RealFlag::Overflow); auto added{sum.Add(next.value, rounding)}; overflow |= added.flags.test(RealFlag::Overflow); @@ -348,7 +348,7 @@ template class SumAccumulator { overflow_ |= sum.overflow; element = sum.value; } else { // Real & Complex: use Kahan summation - auto next{array_.At(at).Add(correction_, rounding_)}; + auto next{array_.At(at).Subtract(correction_, rounding_)}; overflow_ |= next.flags.test(RealFlag::Overflow); auto sum{element.Add(next.value, rounding_)}; overflow_ |= sum.flags.test(RealFlag::Overflow); diff --git a/flang/runtime/sum.cpp b/flang/runtime/sum.cpp index 04241443275eb..10b8124254652 100644 --- a/flang/runtime/sum.cpp +++ b/flang/runtime/sum.cpp @@ -53,7 +53,7 @@ template class RealSumAccumulator { } template RT_API_ATTRS bool Accumulate(A x) { // Kahan summation - auto next{x + correction_}; + auto next{x - correction_}; auto oldSum{sum_}; sum_ += next; correction_ = (sum_ - oldSum) - next; // algebraically zero