[flang-commits] [flang] 9f8ee61 - [flang] Warn on overflow folding DIM()
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Sun Feb 12 17:23:29 PST 2023
Author: Peter Klausler
Date: 2023-02-12T16:46:09-08:00
New Revision: 9f8ee610beb18930e2ad8461cf5105bcdb5a4fec
URL: https://github.com/llvm/llvm-project/commit/9f8ee610beb18930e2ad8461cf5105bcdb5a4fec
DIFF: https://github.com/llvm/llvm-project/commit/9f8ee610beb18930e2ad8461cf5105bcdb5a4fec.diff
LOG: [flang] Warn on overflow folding DIM()
The intrinsic function DIM can overflow when its second argument
is negative. Detect this case for real and integer arguments and
emit a warning when necessary.
Differential Revision: https://reviews.llvm.org/D143798
Added:
Modified:
flang/include/flang/Evaluate/integer.h
flang/lib/Evaluate/fold-integer.cpp
flang/lib/Evaluate/fold-real.cpp
flang/test/Evaluate/errors01.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Evaluate/integer.h b/flang/include/flang/Evaluate/integer.h
index 6a129bf62c19d..2fce4bedfaee0 100644
--- a/flang/include/flang/Evaluate/integer.h
+++ b/flang/include/flang/Evaluate/integer.h
@@ -784,12 +784,12 @@ class Integer {
return {
diff .value, overflow};
}
- // MAX(X-Y, 0)
- constexpr Integer DIM(const Integer &y) const {
+ // DIM(X,Y)=MAX(X-Y, 0)
+ constexpr ValueWithOverflow DIM(const Integer &y) const {
if (CompareSigned(y) != Ordering::Greater) {
return {};
} else {
- return SubtractSigned(y).value;
+ return SubtractSigned(y);
}
}
diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 61e76b59b1f9b..cd8e8f5839a8b 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -568,8 +568,15 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
cx->u)};
}
} else if (name == "dim") {
- return FoldElementalIntrinsic<T, T, T>(
- context, std::move(funcRef), &Scalar<T>::DIM);
+ return FoldElementalIntrinsic<T, T, T>(context, std::move(funcRef),
+ ScalarFunc<T, T, T>([&context](const Scalar<T> &x,
+ const Scalar<T> &y) -> Scalar<T> {
+ auto result{x.DIM(y)};
+ if (result.overflow) {
+ context.messages().Say("DIM intrinsic folding overflow"_warn_en_US);
+ }
+ return result.value;
+ }));
} else if (name == "dot_product") {
return FoldDotProduct<T>(context, std::move(funcRef));
} else if (name == "dshiftl" || name == "dshiftr") {
diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp
index ef90d12446454..196fdaf14d23a 100644
--- a/flang/lib/Evaluate/fold-real.cpp
+++ b/flang/lib/Evaluate/fold-real.cpp
@@ -138,10 +138,14 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
}));
} else if (name == "dim") {
return FoldElementalIntrinsic<T, T, T>(context, std::move(funcRef),
- ScalarFunc<T, T, T>(
- [](const Scalar<T> &x, const Scalar<T> &y) -> Scalar<T> {
- return x.DIM(y).value;
- }));
+ ScalarFunc<T, T, T>([&context](const Scalar<T> &x,
+ const Scalar<T> &y) -> Scalar<T> {
+ ValueWithRealFlags<Scalar<T>> result{x.DIM(y)};
+ if (result.flags.test(RealFlag::Overflow)) {
+ context.messages().Say("DIM intrinsic folding overflow"_warn_en_US);
+ }
+ return result.value;
+ }));
} else if (name == "dot_product") {
return FoldDotProduct<T>(context, std::move(funcRef));
} else if (name == "dprod") {
diff --git a/flang/test/Evaluate/errors01.f90 b/flang/test/Evaluate/errors01.f90
index 14702ccf827c8..46cc4e6717588 100644
--- a/flang/test/Evaluate/errors01.f90
+++ b/flang/test/Evaluate/errors01.f90
@@ -156,6 +156,10 @@ subroutine warnings
real, parameter :: bad1 = scale(1.0, 99999)
!CHECK: complex ABS intrinsic folding overflow
real, parameter :: bad2 = abs(cmplx(huge(0.),huge(0.)))
+ !CHECK: warning: DIM intrinsic folding overflow
+ real, parameter :: bad3 = dim(huge(1.),-.5*huge(1.))
+ !CHECK: warning: DIM intrinsic folding overflow
+ integer, parameter :: bad4 = dim(huge(1),-1)
!CHECK: warning: overflow on REAL(8) to REAL(4) conversion
x = 1.D40
end subroutine
More information about the flang-commits
mailing list