[flang-commits] [flang] d3f5ef2 - Add ieee_is_normal/ieee_is_negative to ieee_arithmetic module.
Yuri Gribov via flang-commits
flang-commits at lists.llvm.org
Wed Jan 26 00:33:29 PST 2022
Author: Yury Gribov
Date: 2022-01-26T11:33:23+03:00
New Revision: d3f5ef241ae3841b6f9b70bd138a9252ed3a002e
URL: https://github.com/llvm/llvm-project/commit/d3f5ef241ae3841b6f9b70bd138a9252ed3a002e
DIFF: https://github.com/llvm/llvm-project/commit/d3f5ef241ae3841b6f9b70bd138a9252ed3a002e.diff
LOG: Add ieee_is_normal/ieee_is_negative to ieee_arithmetic module.
Added:
Modified:
flang/include/flang/Evaluate/real.h
flang/lib/Evaluate/fold-logical.cpp
flang/lib/Evaluate/intrinsics.cpp
flang/module/__fortran_builtins.f90
flang/module/ieee_arithmetic.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Evaluate/real.h b/flang/include/flang/Evaluate/real.h
index 77c25c4feae1..01634022d5fd 100644
--- a/flang/include/flang/Evaluate/real.h
+++ b/flang/include/flang/Evaluate/real.h
@@ -88,6 +88,9 @@ class Real : public common::RealDetails<PREC> {
constexpr bool IsSubnormal() const {
return Exponent() == 0 && !GetSignificand().IsZero();
}
+ constexpr bool IsNormal() const {
+ return !(IsInfinite() || IsNotANumber() || IsSubnormal());
+ }
constexpr Real ABS() const { // non-arithmetic, no flags returned
return {word_.IBCLR(bits - 1)};
diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index 4ba4ce838760..34a7639ba32d 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -118,6 +118,20 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
ScalarFunc<T, DefaultReal>([](const Scalar<DefaultReal> &x) {
return Scalar<T>{x.IsNotANumber()};
}));
+ } else if (name == "__builtin_ieee_is_negative") {
+ auto restorer{context.messages().DiscardMessages()};
+ using DefaultReal = Type<TypeCategory::Real, 4>;
+ return FoldElementalIntrinsic<T, DefaultReal>(context, std::move(funcRef),
+ ScalarFunc<T, DefaultReal>([](const Scalar<DefaultReal> &x) {
+ return Scalar<T>{x.IsNegative()};
+ }));
+ } else if (name == "__builtin_ieee_is_normal") {
+ auto restorer{context.messages().DiscardMessages()};
+ using DefaultReal = Type<TypeCategory::Real, 4>;
+ return FoldElementalIntrinsic<T, DefaultReal>(context, std::move(funcRef),
+ ScalarFunc<T, DefaultReal>([](const Scalar<DefaultReal> &x) {
+ return Scalar<T>{x.IsNormal()};
+ }));
} else if (name == "is_contiguous") {
if (args.at(0)) {
if (auto *expr{args[0]->UnwrapExpr()}) {
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index ae7e5e9bf788..9dca8b4cc60a 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -793,6 +793,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
DefaultingKIND},
KINDInt},
{"__builtin_ieee_is_nan", {{"a", AnyFloating}}, DefaultLogical},
+ {"__builtin_ieee_is_normal", {{"a", AnyFloating}}, DefaultLogical},
+ {"__builtin_ieee_is_negative", {{"a", AnyFloating}}, DefaultLogical},
{"__builtin_ieee_next_after", {{"x", SameReal}, {"y", AnyReal}}, SameReal},
{"__builtin_ieee_next_down", {{"x", SameReal}}, SameReal},
{"__builtin_ieee_next_up", {{"x", SameReal}}, SameReal},
diff --git a/flang/module/__fortran_builtins.f90 b/flang/module/__fortran_builtins.f90
index 5d7a0008ec36..4a4c55e44e05 100644
--- a/flang/module/__fortran_builtins.f90
+++ b/flang/module/__fortran_builtins.f90
@@ -41,7 +41,8 @@
procedure(type(__builtin_c_ptr)) :: __builtin_c_loc
- intrinsic :: __builtin_ieee_is_nan
+ intrinsic :: __builtin_ieee_is_nan, __builtin_ieee_is_normal, &
+ __builtin_ieee_is_negative
intrinsic :: __builtin_ieee_next_after, __builtin_ieee_next_down, &
__builtin_ieee_next_up
intrinsic :: scale ! for ieee_scalb
diff --git a/flang/module/ieee_arithmetic.f90 b/flang/module/ieee_arithmetic.f90
index 1d7c32e7e116..45d3cc3f02a1 100644
--- a/flang/module/ieee_arithmetic.f90
+++ b/flang/module/ieee_arithmetic.f90
@@ -11,6 +11,8 @@ module ieee_arithmetic
use __Fortran_builtins, only: &
ieee_is_nan => __builtin_ieee_is_nan, &
+ ieee_is_normal => __builtin_ieee_is_normal, &
+ ieee_is_negative => __builtin_ieee_is_negative, &
ieee_next_after => __builtin_ieee_next_after, &
ieee_next_down => __builtin_ieee_next_down, &
ieee_next_up => __builtin_ieee_next_up, &
@@ -235,6 +237,40 @@ elemental function ieee_is_finite_a##KIND(x) result(res); \
_IS_FINITE(16)
#undef _IS_FINITE
+#define _IS_NEGATIVE(KIND) \
+ elemental function ieee_is_negative_a##KIND(x) result(res); \
+ real(kind=KIND), intent(in) :: x; \
+ logical :: res; \
+ type(ieee_class_type) :: classification; \
+ classification = ieee_class(x); \
+ res = classification == ieee_negative_zero .or. classification == ieee_negative_denormal \
+ .or. classification == ieee_negative_normal .or. classification == ieee_negative_inf; \
+ end function
+ _IS_NEGATIVE(2)
+ _IS_NEGATIVE(3)
+ _IS_NEGATIVE(4)
+ _IS_NEGATIVE(8)
+ _IS_NEGATIVE(10)
+ _IS_NEGATIVE(16)
+#undef _IS_NEGATIVE
+
+#define _IS_NORMAL(KIND) \
+ elemental function ieee_is_normal_a##KIND(x) result(res); \
+ real(kind=KIND), intent(in) :: x; \
+ logical :: res; \
+ type(ieee_class_type) :: classification; \
+ classification = ieee_class(x); \
+ res = classification == ieee_negative_normal .or. classification == ieee_positive_normal \
+ .or. classification == ieee_negative_zero .or. classification == ieee_positive_zero; \
+ end function
+ _IS_NORMAL(2)
+ _IS_NORMAL(3)
+ _IS_NORMAL(4)
+ _IS_NORMAL(8)
+ _IS_NORMAL(10)
+ _IS_NORMAL(16)
+#undef _IS_NORMAL
+
! TODO: handle edge cases from 17.11.31
#define _REM(XKIND,YKIND) \
elemental function ieee_rem_a##XKIND##_a##YKIND(x, y) result(res); \
More information about the flang-commits
mailing list