[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