[flang-commits] [flang] e0daa2e - [flang] Fix ISHFTC argument value check

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Mar 2 09:21:44 PST 2023


Author: Peter Klausler
Date: 2023-03-02T09:17:09-08:00
New Revision: e0daa2ebd39c5ce542a6af87e1e3ce68e91604d8

URL: https://github.com/llvm/llvm-project/commit/e0daa2ebd39c5ce542a6af87e1e3ce68e91604d8
DIFF: https://github.com/llvm/llvm-project/commit/e0daa2ebd39c5ce542a6af87e1e3ce68e91604d8.diff

LOG: [flang] Fix ISHFTC argument value check

The code that visits all pairs of constant SHIFT= and SIZE= arguments
in an array-valued call to the ISHFTC intrinsic function had a bad loop
test that affected the case where one of these arguments was scalar and
the other was not.  Fix it, and add tests.

Differential Revision: https://reviews.llvm.org/D145092

Added: 
    

Modified: 
    flang/lib/Evaluate/fold-integer.cpp
    flang/test/Semantics/ishftc.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 4a66d437f06c1..601fa729980e6 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -596,7 +596,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
         name == "dshiftl" ? &Scalar<T>::DSHIFTL : &Scalar<T>::DSHIFTR};
     // Third argument can be of any kind. However, it must be smaller or equal
     // than BIT_SIZE. It can be converted to Int4 to simplify.
-    if (const auto *shiftCon{Folder<Int4>(context).Folding(args[2])}) {
+    if (const auto *argCon{Folder<T>(context).Folding(args[0])};
+        argCon && argCon->empty()) {
+    } else if (const auto *shiftCon{Folder<Int4>(context).Folding(args[2])}) {
       for (const auto &scalar : shiftCon->values()) {
         std::int64_t shiftVal{scalar.ToInt64()};
         if (shiftVal < 0) {
@@ -696,7 +698,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
     } else {
       common::die("missing case to fold intrinsic function %s", name.c_str());
     }
-    if (const auto *posCon{Folder<Int4>(context).Folding(args[1])}) {
+    if (const auto *argCon{Folder<T>(context).Folding(args[0])};
+        argCon && argCon->empty()) {
+    } else if (const auto *posCon{Folder<Int4>(context).Folding(args[1])}) {
       for (const auto &scalar : posCon->values()) {
         std::int64_t posVal{scalar.ToInt64()};
         if (posVal < 0) {
@@ -720,7 +724,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
   } else if (name == "ibits") {
     const auto *posCon{Folder<Int4>(context).Folding(args[1])};
     const auto *lenCon{Folder<Int4>(context).Folding(args[2])};
-    if (posCon && lenCon &&
+    if (const auto *argCon{Folder<T>(context).Folding(args[0])};
+        argCon && argCon->empty()) {
+    } else if (posCon && lenCon &&
         (posCon->size() == 1 || lenCon->size() == 1 ||
             posCon->size() == lenCon->size())) {
       auto posIter{posCon->values().begin()};
@@ -823,9 +829,17 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
     return FoldBitReduction(
         context, std::move(funcRef), &Scalar<T>::IEOR, Scalar<T>{});
   } else if (name == "ishft" || name == "ishftc") {
+    const auto *argCon{Folder<T>(context).Folding(args[0])};
     const auto *shiftCon{Folder<Int4>(context).Folding(args[1])};
-    if (shiftCon) {
-      for (const auto &scalar : shiftCon->values()) {
+    const auto *shiftVals{shiftCon ? &shiftCon->values() : nullptr};
+    const auto *sizeCon{
+        args.size() == 3 ? Folder<Int4>(context).Folding(args[2]) : nullptr};
+    const auto *sizeVals{sizeCon ? &sizeCon->values() : nullptr};
+    if ((argCon && argCon->empty()) || !shiftVals || shiftVals->empty() ||
+        (sizeVals && sizeVals->empty())) {
+      // size= and shift= values don't need to be checked
+    } else {
+      for (const auto &scalar : *shiftVals) {
         std::int64_t shiftVal{scalar.ToInt64()};
         if (shiftVal < -T::Scalar::bits) {
           context.messages().Say(
@@ -839,10 +853,8 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
           break;
         }
       }
-    }
-    if (args.size() == 3) { // ISHFTC
-      if (const auto *sizeCon{Folder<Int4>(context).Folding(args[2])}) {
-        for (const auto &scalar : sizeCon->values()) {
+      if (sizeVals) {
+        for (const auto &scalar : *sizeVals) {
           std::int64_t sizeVal{scalar.ToInt64()};
           if (sizeVal <= 0) {
             context.messages().Say(
@@ -856,22 +868,14 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
             break;
           }
         }
-        if (shiftCon &&
-            (shiftCon->size() == 1 || sizeCon->size() == 1 ||
-                shiftCon->size() == sizeCon->size())) {
-          auto shiftIter{shiftCon->values().begin()};
-          auto sizeIter{sizeCon->values().begin()};
-          for (; shiftIter != shiftCon->values().end() &&
-               sizeIter != sizeCon->values().end();
-               ++shiftIter, ++sizeIter) {
-            shiftIter = shiftIter == shiftCon->values().end()
-                ? shiftCon->values().begin()
-                : shiftIter;
-            sizeIter = sizeIter == sizeCon->values().end()
-                ? sizeCon->values().begin()
-                : sizeIter;
-            auto shiftVal{static_cast<int>(shiftIter->ToInt64())};
-            auto sizeVal{static_cast<int>(sizeIter->ToInt64())};
+        if (shiftVals->size() == 1 || sizeVals->size() == 1 ||
+            shiftVals->size() == sizeVals->size()) {
+          auto iters{std::max(shiftVals->size(), sizeVals->size())};
+          for (std::size_t j{0}; j < iters; ++j) {
+            auto shiftVal{static_cast<int>(
+                (*shiftVals)[j % shiftVals->size()].ToInt64())};
+            auto sizeVal{
+                static_cast<int>((*sizeVals)[j % sizeVals->size()].ToInt64())};
             if (sizeVal > 0 && std::abs(shiftVal) > sizeVal) {
               context.messages().Say(
                   "SHIFT=%jd count for ishftc is greater in magnitude than SIZE=%jd"_err_en_US,
@@ -900,7 +904,6 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
           ScalarFunc<T, T, Int4, Int4>(
               [&](const Scalar<T> &i, const Scalar<Int4> &shift,
                   const Scalar<Int4> &size) -> Scalar<T> {
-                // Errors are caught in intrinsics.cpp
                 auto shiftVal{static_cast<int>(shift.ToInt64())};
                 auto sizeVal{static_cast<int>(size.ToInt64())};
                 return i.ISHFTC(shiftVal, sizeVal);
@@ -1154,7 +1157,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
     } else {
       common::die("missing case to fold intrinsic function %s", name.c_str());
     }
-    if (const auto *shiftCon{Folder<Int4>(context).Folding(args[1])}) {
+    if (const auto *argCon{Folder<T>(context).Folding(args[0])};
+        argCon && argCon->empty()) {
+    } else if (const auto *shiftCon{Folder<Int4>(context).Folding(args[1])}) {
       for (const auto &scalar : shiftCon->values()) {
         std::int64_t shiftVal{scalar.ToInt64()};
         if (shiftVal < 0) {

diff  --git a/flang/test/Semantics/ishftc.f90 b/flang/test/Semantics/ishftc.f90
index 15d1213999cc9..c6908026e89ff 100644
--- a/flang/test/Semantics/ishftc.f90
+++ b/flang/test/Semantics/ishftc.f90
@@ -26,6 +26,10 @@ program test_ishftc
   n = ishftc(3, 2, 1)
   !ERROR: SHIFT=-2 count for ishftc is greater in magnitude than SIZE=1
   n = ishftc(3, -2, 1)
+  !ERROR: SHIFT=4 count for ishftc is greater in magnitude than SIZE=3
+  array_result = ishftc(666, [(j,integer::j=1,5)], 3)
+  !ERROR: SHIFT=4 count for ishftc is greater in magnitude than SIZE=3
+  array_result = ishftc(666, 4, [(j,integer::j=10,3,-1)])
   !ERROR: SIZE=-3 count for ishftc is not positive
   array_result = ishftc([3,3], [2,2], [-3,3])
   !ERROR: SIZE=-3 count for ishftc is not positive
@@ -44,5 +48,5 @@ program test_ishftc
   array_result = ishftc([3,3], [-2,-2], const_arr6)
   !ERROR: SIZE=0 count for ishftc is not positive
   array_result = ishftc([3,3], [-2,-2], const_arr7)
-
+  array_result = ishftc([(j,integer::j=1,0)], 10, 9) ! ok because empty
 end program test_ishftc


        


More information about the flang-commits mailing list