[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