[flang-commits] [flang] [flang] Fold IS_IOSTAT_END() & IS_IOSTAT_EOR() (PR #70971)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Wed Nov 1 11:38:12 PDT 2023
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/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.
>From ffa3114840a3f404d76a1654f50b62dcec025f67 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 1 Nov 2023 11:30:09 -0700
Subject: [PATCH] [flang] Fold IS_IOSTAT_END() & IS_IOSTAT_EOR()
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.
---
flang/lib/Evaluate/fold-logical.cpp | 21 ++++++++++++++++++++-
flang/test/Evaluate/fold-iostat.f90 | 12 ++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Evaluate/fold-iostat.f90
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