[flang-commits] [flang] 67f15e7 - [flang] Fold IS_IOSTAT_END() & IS_IOSTAT_EOR() (#70971)

via flang-commits flang-commits at lists.llvm.org
Mon Nov 13 14:07:42 PST 2023


Author: Peter Klausler
Date: 2023-11-13T14:07:38-08:00
New Revision: 67f15e76ebd23f659168f845f9660d3e5e9c606c

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

LOG: [flang] Fold IS_IOSTAT_END() & IS_IOSTAT_EOR() (#70971)

These intrinsic functions are not particularly valuable -- one can just
compare a value to IOSTAT_END or IOSTAT_EOR directly -- but they are in
the standard and are allowed to appear in constant expressions, so
here's code to fold them.

Added: 
    flang/test/Evaluate/fold-iostat.f90

Modified: 
    flang/lib/Evaluate/fold-logical.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index 9fc42adf805f468..bfedc32a33a8bad 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -9,6 +9,7 @@
 #include "fold-implementation.h"
 #include "fold-reduction.h"
 #include "flang/Evaluate/check-expression.h"
+#include "flang/Runtime/magic-numbers.h"
 
 namespace Fortran::evaluate {
 
@@ -194,6 +195,24 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
         }
       }
     }
+  } else if (name == "is_iostat_end") {
+    if (args[0] && args[0]->UnwrapExpr() &&
+        IsActuallyConstant(*args[0]->UnwrapExpr())) {
+      using Int64 = Type<TypeCategory::Integer, 8>;
+      return FoldElementalIntrinsic<T, Int64>(context, std::move(funcRef),
+          ScalarFunc<T, Int64>([](const Scalar<Int64> &x) {
+            return Scalar<T>{x.ToInt64() == FORTRAN_RUNTIME_IOSTAT_END};
+          }));
+    }
+  } else if (name == "is_iostat_eor") {
+    if (args[0] && args[0]->UnwrapExpr() &&
+        IsActuallyConstant(*args[0]->UnwrapExpr())) {
+      using Int64 = Type<TypeCategory::Integer, 8>;
+      return FoldElementalIntrinsic<T, Int64>(context, std::move(funcRef),
+          ScalarFunc<T, Int64>([](const Scalar<Int64> &x) {
+            return Scalar<T>{x.ToInt64() == FORTRAN_RUNTIME_IOSTAT_EOR};
+          }));
+    }
   } else if (name == "lge" || name == "lgt" || name == "lle" || name == "llt") {
     // Rewrite LGE/LGT/LLE/LLT into ASCII character relations
     auto *cx0{UnwrapExpr<Expr<SomeCharacter>>(args[0])};
@@ -348,7 +367,7 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
       name == "__builtin_ieee_support_underflow_control") {
     return Expr<T>{true};
   }
-  // TODO: is_iostat_end, is_iostat_eor, logical, matmul, parity
+  // TODO: logical, matmul, parity
   return Expr<T>{std::move(funcRef)};
 }
 

diff  --git a/flang/test/Evaluate/fold-iostat.f90 b/flang/test/Evaluate/fold-iostat.f90
new file mode 100644
index 000000000000000..7b795d82fa0529a
--- /dev/null
+++ b/flang/test/Evaluate/fold-iostat.f90
@@ -0,0 +1,12 @@
+! RUN: %python %S/test_folding.py %s %flang_fc1
+module m
+  use iso_fortran_env
+  logical, parameter :: test_end1 = is_iostat_end(iostat_end)
+  logical, parameter :: test_end2 = .not. is_iostat_end(iostat_eor)
+  logical, parameter :: test_eor1 = is_iostat_eor(iostat_eor)
+  logical, parameter :: test_eor2 = .not. is_iostat_eor(iostat_end)
+  logical, parameter :: test_arr1 = &
+    all(is_iostat_end([iostat_end, iostat_eor]) .eqv. [.true., .false.])
+  logical, parameter :: test_arr2 = &
+    all(is_iostat_eor([iostat_end, iostat_eor]) .eqv. [.false., .true.])
+end


        


More information about the flang-commits mailing list